主题:[原创]贪吃蛇(游戏)
程序部分借鉴了[url=http://pfan.cn/club/showbbs.asp?id=60719]俄罗斯方块[/url]的思路:采用用一个数组记录运动物体的位置。用另一个二维数组记录背景(这里是room(,)).
蛇头及食物的闪烁 改用COLOR 31来产生,在全屏状态下可见闪烁
DECLARE FUNCTION jian$ (s%) '获得按键并延时的函数
DECLARE FUNCTION movesnake! (dx!, dy!) ' 移动蛇身体,并判断移动情况
DECLARE SUB drawsnake (cc$) '画或擦蛇的身体,同时在标记或清除标记
DECLARE SUB win ()
DECLARE SUB lose ()
REM snakeml是snakeMaxLength
CONST x0 = 22, y0 = 5, roomwidth = 20, roomheight = 15, snakeml = 10
CONST left = -1, right = 1, up = -1, down = 1, still = 0
REM蛇的活动场所及标记 取值为-1:食物;为1:墙壁或蛇的身体;其他地点标记为0
DIM SHARED room(0 TO roomwidth + 1, 0 TO roomheight + 1) AS INTEGER
REM 记录蛇的身体位置snake(i,1)为列数;snake(i,2)为行数
DIM SHARED snake(0 TO snakeml, 1 TO 2) AS INTEGER
DIM SHARED snaketail AS INTEGER 'snaketail记录蛇的身长(蛇的尾部所在的环节)
FOR i = 0 TO roomwidth + 1 '边界处标记为-1
room(i, 0) = -1: room(i, roomheight + 1) = -1
NEXT i
FOR j = 1 TO roomheight
room(0, j) = -1: room(roomwidth + 1, j) = -1
NEXT j
CLS '画出边界
LOCATE y0, x0: PRINT CHR$(201); STRING$(2 * roomwidth + 2, CHR$(205)); CHR$(187)
FOR j = 1 TO roomheight
LOCATE y0 + j, x0: PRINT CHR$(186); SPC(2 * roomwidth + 2); CHR$(186)
NEXT j
LOCATE y0 + roomheight + 1, x0: PRINT CHR$(200); STRING$(2 * roomwidth + 2, CHR$(205)); CHR$(188)
FOR i = 1 TO 3 '初始化蛇的位置:左上角
snake(i, 1) = 4 - i: snake(i, 2) = 1
NEXT i
snaketail = 3 '初始化蛇的长度:3
CALL drawsnake("[]") '画出蛇的身体
t = 1: movex = still: movey = still
DO
DO WHILE t = 1 '产生一个食物
foodx = INT(RND * roomwidth + 1)
foody = INT(RND * roomheight + 1)
FOR i = 1 TO snaketail '判断食物在不在蛇的身体上,在则重新产生一个食物
IF foodx = snake(i, 1) AND foody = snake(i, 2) THEN
t = 1: EXIT FOR
ELSE
t = 0
END IF
NEXT i
LOOP
room(foodx, foody) = 1 '有食物的地方标记为1
COLOR 31
LOCATE y0 + foody, x0 + 2 * foodx: PRINT "[]" '食物及蛇头的闪烁
LOCATE y0 + snake(1, 2), x0 + 2 * snake(1, 1): PRINT "[]"
COLOR 7
key$ = jian$(200)
SELECT CASE key$
CASE CHR$(0) + CHR$(72) '上
movex = still: movey = up
CASE CHR$(0) + CHR$(80) '下
movex = still: movey = down
CASE CHR$(0) + CHR$(75) '左
movex = left: movey = still
CASE CHR$(0) + CHR$(77) '右
movex = right: movey = still
CASE CHR$(13) 'ENTER:暂停
movex = still: movey = still
CASE CHR$(27) 'ESC:退出
END
END SELECT
t = movesnake(movex, movey)
LOOP
SUB drawsnake (cc$) '画或擦蛇的身体,同时在标记或清除标记
IF cc$ = "[]" THEN flag = -1 ELSE flag = 0
FOR i = 1 TO snaketail
LOCATE y0 + snake(i, 2), x0 + 2 * snake(i, 1): PRINT cc$
room(snake(i, 1), snake(i, 2)) = flag
NEXT i
END SUB
FUNCTION jian$ (s%) ' 延时S%毫秒并返回所按的键的ASCII码
newtime = TIMER + s% / 1000
DO
key$ = INKEY$
LOOP UNTIL TIMER > newtime OR key$ <> ""
jian$ = key$
END FUNCTION
SUB lose '撞到墙壁或蛇身体时显示红色的头部
COLOR 12
LOCATE y0 + snake(1, 2), x0 + 2 * snake(1, 1): PRINT "[]"
LOCATE 5, 38: PRINT "YOU LOSE"
WHILE INKEY$ = ""
WEND
END
END SUB
'dx取left:左移 right:右移 still: 水平方向不动 dy取down:下移 still:竖直方向不动
FUNCTION movesnake (dx, dy) ' 移动蛇身体,并判断移动情况
snake(0, 1) = snake(1, 1) + dx 'snake(0, 1)和snake(0, 2)记录蛇头
snake(0, 2) = snake(1, 2) + dy '下一步的位置
'蛇头撞到蛇头(蛇不动)
IF snake(0, 1) = snake(1, 1) AND snake(0, 2) = snake(1, 2) THEN EXIT FUNCTION
'蛇头撞到蛇颈
IF snake(0, 1) = snake(2, 1) AND snake(0, 2) = snake(2, 2) THEN
snake(0, 1) = snake(1, 1) - dx: snake(0, 2) = snake(1, 2) - dy
END IF
flag = room(snake(0, 1), snake(0, 2)) 'flag记录该位置的标记值
'蛇头撞到蛇尾
IF snake(0, 1) = snake(snaketail, 1) AND snake(0, 2) = snake(snaketail, 2) THEN flag = 0
IF flag = -1 THEN CALL lose
CALL drawsnake(" ") '擦除蛇的身体,同时清除蛇的身体处的标记
snaketail = snaketail + flag
FOR i = snaketail TO 1 STEP -1
snake(i, 1) = snake(i - 1, 1): snake(i, 2) = snake(i - 1, 2)
NEXT i
CALL drawsnake("[]") '画出蛇的身体,同时标记蛇的身体
LOCATE 22, 23: PRINT "SNAKELENGTH:"; snaketail
IF snaketail = snakeml THEN CALL win
movesnake = flag
END FUNCTION
SUB win
COLOR 12
LOCATE 5, 38: PRINT "YOU WIN"
WHILE INKEY$ = ""
WEND
END
END SUB
蛇头及食物的闪烁 改用COLOR 31来产生,在全屏状态下可见闪烁
DECLARE FUNCTION jian$ (s%) '获得按键并延时的函数
DECLARE FUNCTION movesnake! (dx!, dy!) ' 移动蛇身体,并判断移动情况
DECLARE SUB drawsnake (cc$) '画或擦蛇的身体,同时在标记或清除标记
DECLARE SUB win ()
DECLARE SUB lose ()
REM snakeml是snakeMaxLength
CONST x0 = 22, y0 = 5, roomwidth = 20, roomheight = 15, snakeml = 10
CONST left = -1, right = 1, up = -1, down = 1, still = 0
REM蛇的活动场所及标记 取值为-1:食物;为1:墙壁或蛇的身体;其他地点标记为0
DIM SHARED room(0 TO roomwidth + 1, 0 TO roomheight + 1) AS INTEGER
REM 记录蛇的身体位置snake(i,1)为列数;snake(i,2)为行数
DIM SHARED snake(0 TO snakeml, 1 TO 2) AS INTEGER
DIM SHARED snaketail AS INTEGER 'snaketail记录蛇的身长(蛇的尾部所在的环节)
FOR i = 0 TO roomwidth + 1 '边界处标记为-1
room(i, 0) = -1: room(i, roomheight + 1) = -1
NEXT i
FOR j = 1 TO roomheight
room(0, j) = -1: room(roomwidth + 1, j) = -1
NEXT j
CLS '画出边界
LOCATE y0, x0: PRINT CHR$(201); STRING$(2 * roomwidth + 2, CHR$(205)); CHR$(187)
FOR j = 1 TO roomheight
LOCATE y0 + j, x0: PRINT CHR$(186); SPC(2 * roomwidth + 2); CHR$(186)
NEXT j
LOCATE y0 + roomheight + 1, x0: PRINT CHR$(200); STRING$(2 * roomwidth + 2, CHR$(205)); CHR$(188)
FOR i = 1 TO 3 '初始化蛇的位置:左上角
snake(i, 1) = 4 - i: snake(i, 2) = 1
NEXT i
snaketail = 3 '初始化蛇的长度:3
CALL drawsnake("[]") '画出蛇的身体
t = 1: movex = still: movey = still
DO
DO WHILE t = 1 '产生一个食物
foodx = INT(RND * roomwidth + 1)
foody = INT(RND * roomheight + 1)
FOR i = 1 TO snaketail '判断食物在不在蛇的身体上,在则重新产生一个食物
IF foodx = snake(i, 1) AND foody = snake(i, 2) THEN
t = 1: EXIT FOR
ELSE
t = 0
END IF
NEXT i
LOOP
room(foodx, foody) = 1 '有食物的地方标记为1
COLOR 31
LOCATE y0 + foody, x0 + 2 * foodx: PRINT "[]" '食物及蛇头的闪烁
LOCATE y0 + snake(1, 2), x0 + 2 * snake(1, 1): PRINT "[]"
COLOR 7
key$ = jian$(200)
SELECT CASE key$
CASE CHR$(0) + CHR$(72) '上
movex = still: movey = up
CASE CHR$(0) + CHR$(80) '下
movex = still: movey = down
CASE CHR$(0) + CHR$(75) '左
movex = left: movey = still
CASE CHR$(0) + CHR$(77) '右
movex = right: movey = still
CASE CHR$(13) 'ENTER:暂停
movex = still: movey = still
CASE CHR$(27) 'ESC:退出
END
END SELECT
t = movesnake(movex, movey)
LOOP
SUB drawsnake (cc$) '画或擦蛇的身体,同时在标记或清除标记
IF cc$ = "[]" THEN flag = -1 ELSE flag = 0
FOR i = 1 TO snaketail
LOCATE y0 + snake(i, 2), x0 + 2 * snake(i, 1): PRINT cc$
room(snake(i, 1), snake(i, 2)) = flag
NEXT i
END SUB
FUNCTION jian$ (s%) ' 延时S%毫秒并返回所按的键的ASCII码
newtime = TIMER + s% / 1000
DO
key$ = INKEY$
LOOP UNTIL TIMER > newtime OR key$ <> ""
jian$ = key$
END FUNCTION
SUB lose '撞到墙壁或蛇身体时显示红色的头部
COLOR 12
LOCATE y0 + snake(1, 2), x0 + 2 * snake(1, 1): PRINT "[]"
LOCATE 5, 38: PRINT "YOU LOSE"
WHILE INKEY$ = ""
WEND
END
END SUB
'dx取left:左移 right:右移 still: 水平方向不动 dy取down:下移 still:竖直方向不动
FUNCTION movesnake (dx, dy) ' 移动蛇身体,并判断移动情况
snake(0, 1) = snake(1, 1) + dx 'snake(0, 1)和snake(0, 2)记录蛇头
snake(0, 2) = snake(1, 2) + dy '下一步的位置
'蛇头撞到蛇头(蛇不动)
IF snake(0, 1) = snake(1, 1) AND snake(0, 2) = snake(1, 2) THEN EXIT FUNCTION
'蛇头撞到蛇颈
IF snake(0, 1) = snake(2, 1) AND snake(0, 2) = snake(2, 2) THEN
snake(0, 1) = snake(1, 1) - dx: snake(0, 2) = snake(1, 2) - dy
END IF
flag = room(snake(0, 1), snake(0, 2)) 'flag记录该位置的标记值
'蛇头撞到蛇尾
IF snake(0, 1) = snake(snaketail, 1) AND snake(0, 2) = snake(snaketail, 2) THEN flag = 0
IF flag = -1 THEN CALL lose
CALL drawsnake(" ") '擦除蛇的身体,同时清除蛇的身体处的标记
snaketail = snaketail + flag
FOR i = snaketail TO 1 STEP -1
snake(i, 1) = snake(i - 1, 1): snake(i, 2) = snake(i - 1, 2)
NEXT i
CALL drawsnake("[]") '画出蛇的身体,同时标记蛇的身体
LOCATE 22, 23: PRINT "SNAKELENGTH:"; snaketail
IF snaketail = snakeml THEN CALL win
movesnake = flag
END FUNCTION
SUB win
COLOR 12
LOCATE 5, 38: PRINT "YOU WIN"
WHILE INKEY$ = ""
WEND
END
END SUB