반응형
이건 좀 간단한 뱀 게임이다.
조작방법은 숫자키거나 AWSD 키다.
빨간색을 사과라고 생각하고 먹으면 꼬리가 길어진다.
알다시피 벽에 머리 박으면 끝나는 거다.
뱀 방향 전환 할 때 각각 꺽어지는 부분 알고리즘에 시간 좀 들어 갔다.
몸땡이를 어레이에 담고 다니면서 방향을 기록해 두는 방식으로 극뽁
그거 외에는 딱히 어려운 부분은 없었다.
시간이 지나면서 아주조금씩 빨라지긴 하는데.. 몸땡이가 길어 지면 느려도 어렵더라...
사실 VBScript 문법을 잘 몰라서 그런는데... 배열을 복사 할 때 오류가 나는데 왜 나는지 모르겠다.
[Snake.hta]
<html>
<meta charset="euc-kr">
<head>
<title>Snake</title>
<HTA:APPLICATION
ID="강멍멍이"
APPLICATIONNAME="Snake"
SCROLL="no"
SINGLEINSTANCE="yes"
WINDOWSTATE="normal"
/>
<style>
BODY {
font-size:9pt;
font-family:돋움체;
}
TABLE, TR, TD {
font-size:1pt;
text-indent:-10000px;
border:1px solid black;
border-collapse:collapse;
}
.hide {
opacity : 0;
transition: opacity 1s linear;
-webkit-transition: opacity 1s linear;
}
</style>
<script language="VBScript">
Dim interval, levelCnt, levelCntMax , intervalMinus, viewLevel
Dim intRow, intCol
Dim rowBound, colBound
Dim aniXDir, aniYDir
Dim snakeArr()
Dim snakeArrBackup()
Dim turnDir
Dim rollPoint
Dim endGameYn
Dim scoreCnt
Dim timerID
Dim animateTimerID
Dim colorArr
Dim snakeColor
Sub Window_OnLoad
window.resizeTo 300, 350
window.moveTo 1200, 350
colorArr = Array("e2edff", "teal", "aqua", "salmon", "darkkhaki", "darkred", "plum", "lime", "black", "gray")
rowBound = CInt(labRow.innerHTML)
colBound = CInt(labCol.innerHTML)
For nRow = 1 To rowBound
Set tblRow = mainTbl.insertRow()
For nCell = 1 To colBound
Set tblCell = tblRow.insertCell()
tblCell.style.width = 10
tblCell.style.height = 10
tblCell.style.backgroundcolor = "#ffffff"
tblCell.innerHtml= "0"
Next
Next
aniXDir = 0
aniYDir = 0
animateTimerID = window.setTimeOut("animate", 500)
End Sub
Sub startGame
document.body.focus() '시작버튼에 있는 포커스 제거
window.clearTimeOut(animateTimerID)
levelCntMax = 100
intervalMinus = 10
interval = 300
levelCnt = 1
viewLevel = 1
scoreCnt = 0
endGameYn = "N"
snakeColor = 111115
intRow = CInt(rowBound / 2) - 2
intCol = CInt(colBound / 2)
labLevelCnt.innerHTML = viewLevel
For nRow = 0 To rowBound - 1
For nCell = 0 To colBound - 1
mainTbl.Rows(nRow).Cells(nCell).innerHtml = 0
mainTbl.Rows(nRow).Cells(nCell).style.backgroundcolor = "white"
Next
Next
ReDim snakeArr(5,4)
For nRow = 0 To UBound(snakeArr)
snakeColor = snakeColor + 1
snakeArr(nRow, 0) = intRow + nRow
snakeArr(nRow, 1) = intCol
snakeArr(nRow, 2) = 1 '방향
snakeArr(nRow, 3) = 0 '이동대상여부
snakeArr(nRow, 4) = CStr(snakeColor) '블럭 색상
Next
snakeArr(0,3) = 1 '이동대상여부
'뱀 몸땡이 기본
For i = 0 To UBound(snakeArr)
mainTbl.Rows(snakeArr(i, 0)).Cells(snakeArr(i, 1)).innerHtml = 1
mainTbl.Rows(snakeArr(i, 0)).Cells(snakeArr(i, 1)).style.backgroundcolor = Cstr(snakeArr(i, 4))
'mainTbl.Rows(snakeArr(i, 0)).Cells(snakeArr(i, 1)).style.backgroundcolor = Cstr(snakeColor)
Next
Call makeApple
Call makeApple
Call makeApple
snakeArr(0, 2) = 1 '최초 위로 이동
timerID = window.setTimeOut("moveSnake", interval)
End Sub
Sub moveSnake
Call chkEnd(snakeArr(0,2))
If endGameYn = "Y" Then
Exit Sub
End If
levelCnt = levelCnt + 1
If levelCnt > levelCntMax Then
interval = interval - intervalMinus
levelCnt = 1
viewLevel = viewLevel + 1
labLevelCnt.innerHTML = viewLevel
End If
posChg = "N"
eatAppleYn = "N"
snakeDir = snakeArr(0, 2)
For i = 0 To UBound(snakeArr)
'현재 위치는 지운다.
mainTbl.Rows(snakeArr(i, 0)).Cells(snakeArr(i, 1)).innerHtml = 0
mainTbl.Rows(snakeArr(i, 0)).Cells(snakeArr(i, 1)).style.backgroundcolor = "white"
'사과를 먹었으면 현재 꼬리를 추가될 꼬리의 포지션으로 한다.
If eatAppleYn = "Y" And i = UBound(snakeArr) Then
paramRow = snakeArr(i, 0)
paramCol = snakeArr(i, 1)
paramDir = snakeArr(i, 2)
End If
snakeDir = snakeArr(i, 2)
If snakeDir = 1 Then '상
snakeArr(i, 0) = snakeArr(i, 0) - 1
snakeArr(i, 1) = snakeArr(i, 1)
ElseIf snakeDir = 2 Then '하
snakeArr(i, 0) = snakeArr(i, 0) + 1
snakeArr(i, 1) = snakeArr(i, 1)
ElseIf snakeDir = 3 Then '좌
snakeArr(i, 0) = snakeArr(i, 0)
snakeArr(i, 1) = snakeArr(i, 1) - 1
ElseIf snakeDir = 4 Then '우
snakeArr(i, 0) = snakeArr(i, 0)
snakeArr(i, 1) = snakeArr(i, 1) + 1
End If
'사과를 먹으면 꼬리를 1칸 늘여야 한다.
If mainTbl.Rows(snakeArr(i, 0)).Cells(snakeArr(i, 1)).innerHtml = 2 Then
eatAppleYn = "Y"
End If
'이동 할 위치를 찍는다.
mainTbl.Rows(snakeArr(i, 0)).Cells(snakeArr(i, 1)).innerHtml = 1
mainTbl.Rows(snakeArr(i, 0)).Cells(snakeArr(i, 1)).style.backgroundcolor = Cstr(snakeArr(i, 4))
'mainTbl.Rows(snakeArr(i, 0)).Cells(snakeArr(i, 1)).style.backgroundcolor = Cstr(snakeColor)
Next
'역순으로 이전 블럭의 이동 방향을 가져 온다.
For i = UBound(snakeArr) To 1 Step - 1
snakeArr(i, 2) = snakeArr(i - 1, 2) '이전 블럭의 이동 방향을 받아서 다음에 움직일때 적용 한다.
Next
'사과를 먹었으면 꼬리를 추가한다.
If eatAppleYn = "Y" Then
Call eatApple(paramRow, paramCol, paramDir)
End If
window.clearTimeOut(animateTimerID)
timerID = window.setTimeOut("moveSnake", interval)
End Sub
Sub makeApple
'사과 위치
makeDone = "N"
Do While makeDone = "N"
Randomize
rndRow = Int(rowBound * Rnd)
rndCol = Int(colBound * Rnd)
'뱀은 피해서 만든다.
If mainTbl.Rows(rndRow).Cells(rndCol).innerHtml = 0 Then
mainTbl.Rows(rndRow).Cells(rndCol).innerHtml = 2
mainTbl.Rows(rndRow).Cells(rndCol).style.backgroundcolor = "red"
makeDone = "Y"
End If
Loop
End Sub
Sub eatApple(paramRow, paramCol, paramDir)
'원본 어레이 백업
ReDim snakeArrBackup(UBound(snakeArr), 4)
'어레이 복사 중에 오류가 나는데 왜 나는지 모르겠다.
On Error Resume Next
For nRow = 0 To UBound(snakeArr)
For nCol = 0 To 4
'If Err.Number <> 0 Then
' msgBox nRow & " " & nCol
'End If
snakeArrBackup(nRow, nCol) = snakeArr(nRow, nCol)
Next
Next
'뱀 재생성
ReDim snakeArr(UBound(snakeArr) + 1, 4)
For nRow = 0 To UBound(snakeArrBackup)
For nCol = 0 To 4
snakeArr(nRow, nCol) = snakeArrBackup(nRow, nCol)
Next
Next
'msgbox snakeArr(snakeSize - 1, 0) & " " & snakeArr(snakeSize - 1, 1)
'꼬리 추가
snakeColor = snakeColor + 1
snakeArr(UBound(snakeArr), 0) = paramRow
snakeArr(UBound(snakeArr), 1) = paramCol
snakeArr(UBound(snakeArr), 2) = paramDir
snakeArr(UBound(snakeArr), 3) = 0
snakeArr(UBound(snakeArr), 4) = snakeColor
scoreCnt = scoreCnt + 1
labScore.innerHTML = scoreCnt
Call makeApple
End Sub
Sub chkEnd(moveDir)
If moveDir = 1 Then '상
chkRowPos = snakeArr(i, 0) - 1
chkColPos = snakeArr(i, 1)
ElseIf moveDir = 2 Then '하
chkRowPos = snakeArr(i, 0) + 1
chkColPos = snakeArr(i, 1)
ElseIf moveDir = 3 Then '좌
chkRowPos = snakeArr(i, 0)
chkColPos = snakeArr(i, 1) - 1
ElseIf moveDir = 4 Then '우
chkRowPos = snakeArr(i, 0)
chkColPos = snakeArr(i, 1) + 1
End If
If chkRowPos < 0 Or chkRowPos >= rowBound Or chkColPos < 0 Or chkColPos >= colBound Then
endGameYn = "Y"
MsgBox "G a m e O v e r ! !"
animateTimerID = window.setTimeOut("animate", 500)
Exit Sub
End If
'바운더리가 넘어 가기때문에 따로 끝내야 한다
'돌다가 자기 몸땡이에 부딪히면 끝이다.
If mainTbl.Rows(chkRowPos).Cells(chkColPos).innerHtml = 1 Then
endGameYn = "Y"
MsgBox "G a m e O v e r ! !"
animateTimerID = window.setTimeOut("animate", 500)
Exit Sub
End If
End Sub
Sub moveUp
'반대반향으로는 선회 못 한다.
If snakeArr(0,2) = 2 Then
Exit Sub
End If
Call chkEnd(1)
snakeArr(0,2) = 1 '방향
snakeArr(0,3) = 1 '이동대상여부
End Sub
Sub moveDown
'반대반향으로는 선회 못 한다.
If snakeArr(0,2) = 1 Then
Exit Sub
End If
Call chkEnd(2)
snakeArr(0,2) = 2 '방향
snakeArr(0,3) = 1 '이동대상여부
End Sub
Sub moveLeft
'반대반향으로는 선회 못 한다.
If snakeArr(0,2) = 4 Then
Exit Sub
End If
Call chkEnd(3)
snakeArr(0,2) = 3 '방향
snakeArr(0,3) = 1 '이동대상여부
End Sub
Sub moveRight
'반대반향으로는 선회 못 한다.
If snakeArr(0,2) = 3 Then
Exit Sub
End If
Call chkEnd(4)
snakeArr(0,2) = 4 '방향
snakeArr(0,3) = 1 '이동대상여부
End Sub
Sub chekKeyPress
'msgbox window.event.Keycode '키 값을 알고 싶다면?
If endGame <> "Y" Then
IF (window.event.Keycode = 119 Or window.event.Keycode = 56) THEN 'w키, 상
Call moveUp
END IF
IF (window.event.Keycode = 115 Or window.event.Keycode = 53) THEN 's키, 하
Call moveDown
END IF
IF (window.event.Keycode = 97 Or window.event.Keycode = 52) THEN ' a키, 좌
Call moveLeft
END IF
IF (window.event.Keycode = 100 Or window.event.Keycode = 54) THEN 'd키, 우
Call moveRight
END IF
'IF (window.event.Keycode = 32) THEN '스페이스키, 파이어!
' Call fireBlock
'END IF
IF (window.event.Keycode = 27) THEN 'ESC 중지/시작
MsgBox "일시중지!!"
END IF
End If
End Sub
Sub animate
Randomize
aniDir = Int(2 * Rnd)
If aniDir = 0 Then
If aniXDir = 0 Then
intRow = intRow + 1
Else
intRow = intRow - 1
End If
If intRow = colBound -1 Then
aniXDir = 1
End If
If intRow = 0 Then
aniXDir = 0
End If
End If
Randomize
aniDir = Int(2 * Rnd)
If aniDir = 0 Then
If aniYDir = 0 Then
intCol = intCol + 1
Else
intCol = intCol - 1
End If
If intCol = rowBound - 1 Then
aniYDir = 1
End If
If intCol = 0 Then
aniYDir = 0
End If
End If
On Error Resume Next
Randomize
aniColor = Int(10 * Rnd)
mainTbl.Rows(intRow).Cells(intCol).style.backgroundcolor = colorArr(aniColor)
window.clearTimeOut(animateTimerID)
animateTimerID = window.setTimeOut("animate", 100)
End Sub
</script>
</head>
<body onKeyPress="chekKeyPress">
<button onClick="startGame" style="width:35px;height:20px">Start</button>
[Row:<label id="labRow">15</label>
Col:<label id="labCol">15</label>]
lv:<label id="labLevelCnt">1</label>
Sc:<label id="labScore">0</label>
<br>
<div style="float:left;width:100%;height:95%;margin:3px;">
<table id="mainTbl" style="width:100%;height:100%"></table>
</div>
</body>
</html>
반응형
댓글