使用pygame库进行游戏界面的绘制和交互。
界面如下:
定义了一些常量,如方块大小(BLOCK_SIZE)、游戏区域宽度(WIDTH)、游戏区域高度(HEIGHT)等。BLOCK_SIZE = 20
WIDTH = 40
HEIGHT = 30
创建了一个二维数组Blocks用于表示游戏区域的状态,其中每个元素的值代表相应位置的方块的状态,0表示空白,正整数表示蛇身的长度,-1表示食物。
Blocks = [[0] * WIDTH for _ in range(HEIGHT)]
定义了一些全局变量,如移动方向(moveDirection)、食物的位置(food_i、food_j)、是否失败(isFailure)等。
moveDirection = 'D'
food_i, food_j = 0, 0
isFailure = False
screen = None
moveSnake函数用于更新蛇的位置,判断是否吃到食物或碰撞失败。
def moveSnake():
global isFailure,food_i, food_j
for i in range(HEIGHT):
for j in range(WIDTH):
if Blocks[i][j] > 0:
Blocks[i][j] += 1
oldTail_i, oldTail_j, oldHead_i, oldHead_j = 0, 0, 0, 0
max_value = 0
for i in range(HEIGHT):
for j in range(WIDTH):
if max_value < Blocks[i][j]:
max_value = Blocks[i][j]
oldTail_i, oldTail_j = i, j
if Blocks[i][j] == 2:
oldHead_i, oldHead_j = i, j
newHead_i, newHead_j = oldHead_i, oldHead_j
if moveDirection == 'W':
newHead_i = oldHead_i - 1
elif moveDirection == 'S':
newHead_i = oldHead_i + 1
elif moveDirection == 'A':
newHead_j = oldHead_j - 1
elif moveDirection == 'D':
newHead_j = oldHead_j + 1
if (
newHead_i >= HEIGHT
or newHead_i < 0
or newHead_j >= WIDTH
or newHead_j < 0
or Blocks[newHead_i][newHead_j] > 0
):
isFailure = True
return
Blocks[newHead_i][newHead_j] = 1
if newHead_i == food_i and newHead_j == food_j:
food_i = random.randint(2, HEIGHT - 5)
food_j = random.randint(2, WIDTH - 5)
else:
Blocks[oldTail_i][oldTail_j] = 0
startup函数用于初始化游戏,设置初始蛇身和食物的位置,并创建游戏窗口。def startup():
global food_i, food_j,screen
Blocks[10][10] = 1
for i in range(1, 5):
Blocks[10][10 - i] = i + 1
food_i = random.randint(2, HEIGHT - 5)
food_j = random.randint(2, WIDTH - 5)
pygame.init()
screen = pygame.display.set_mode((WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE))
pygame.display.set_caption("贪吃小蛇蛇 键盘切换为大写字母 W为上 A为左 S为下 D为右")
show函数用于绘制游戏界面,包括蛇身、食物和游戏结束提示。
def show():
global screen
screen.fill((0, 0, 0))
for i in range(HEIGHT):
for j in range(WIDTH):
if Blocks[i][j] > 0:
color = ((Blocks[i][j] * 10) % 256, 90, 100)
else:
color = (111, 111, 111)
pygame.draw.rect(
screen,
color,
(j * BLOCK_SIZE, i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
)
pygame.draw.rect(
screen,
(0, 255, 0),
(food_j * BLOCK_SIZE, food_i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
)
if isFailure:
font = pygame.font.Font(None, 36)
text = font.render("GAME OVER~!", True, (255, 0, 0))
screen.blit(text, (240, 220))
pygame.display.update()
update_without_input函数用于在没有输入的情况下更新游戏状态,即使蛇自动移动。
def update_without_input():
if isFailure:
return
global waitIndex
waitIndex = waitIndex + 1 if "waitIndex" in globals() else 1
if waitIndex == 20:
moveSnake()
waitIndex = 1
update_with_input函数用于在有输入的情况下更新游戏状态,根据用户输入改变蛇的移动方向。
def update_with_input():
global moveDirection
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and moveDirection != 'D':
moveDirection = 'A'
moveSnake()
elif keys[pygame.K_d] and moveDirection != 'A':
moveDirection = 'D'
moveSnake()
elif keys[pygame.K_w] and moveDirection != 'S':
moveDirection = 'W'
moveSnake()
elif keys[pygame.K_s] and moveDirection != 'W':
moveDirection = 'S'
moveSnake()
main函数是游戏的主循环,不断调用show、update_without_input和update_with_input函数,并控制游戏的帧率。
def main():
startup()
clock = pygame.time.Clock()
while True:
show()
update_without_input()
update_with_input()
clock.tick(24)
python
import random
import pygame
BLOCK_SIZE = 20
WIDTH = 40
HEIGHT = 30
Blocks = [[0] * WIDTH for _ in range(HEIGHT)]
moveDirection = 'D'
food_i, food_j = 0, 0
isFailure = False
screen = None
def moveSnake():
global isFailure,food_i, food_j
for i in range(HEIGHT):
for j in range(WIDTH):
if Blocks[i][j] > 0:
Blocks[i][j] += 1
oldTail_i, oldTail_j, oldHead_i, oldHead_j = 0, 0, 0, 0
max_value = 0
for i in range(HEIGHT):
for j in range(WIDTH):
if max_value < Blocks[i][j]:
max_value = Blocks[i][j]
oldTail_i, oldTail_j = i, j
if Blocks[i][j] == 2:
oldHead_i, oldHead_j = i, j
newHead_i, newHead_j = oldHead_i, oldHead_j
if moveDirection == 'W':
newHead_i = oldHead_i - 1
elif moveDirection == 'S':
newHead_i = oldHead_i + 1
elif moveDirection == 'A':
newHead_j = oldHead_j - 1
elif moveDirection == 'D':
newHead_j = oldHead_j + 1
if (
newHead_i >= HEIGHT
or newHead_i < 0
or newHead_j >= WIDTH
or newHead_j < 0
or Blocks[newHead_i][newHead_j] > 0
):
isFailure = True
return
Blocks[newHead_i][newHead_j] = 1
if newHead_i == food_i and newHead_j == food_j:
food_i = random.randint(2, HEIGHT - 5)
food_j = random.randint(2, WIDTH - 5)
else:
Blocks[oldTail_i][oldTail_j] = 0
def startup():
global food_i, food_j,screen
Blocks[10][10] = 1
for i in range(1, 5):
Blocks[10][10 - i] = i + 1
food_i = random.randint(2, HEIGHT - 5)
food_j = random.randint(2, WIDTH - 5)
pygame.init()
screen = pygame.display.set_mode((WIDTH * BLOCK_SIZE, HEIGHT * BLOCK_SIZE))
pygame.display.set_caption("贪吃小蛇蛇 键盘切换为大写字母 W为上 A为左 S为下 D为右")
def show():
global screen
screen.fill((0, 0, 0))
for i in range(HEIGHT):
for j in range(WIDTH):
if Blocks[i][j] > 0:
color = ((Blocks[i][j] * 10) % 256, 90, 100)
else:
color = (111, 111, 111)
pygame.draw.rect(
screen,
color,
(j * BLOCK_SIZE, i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
)
pygame.draw.rect(
screen,
(0, 255, 0),
(food_j * BLOCK_SIZE, food_i * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
)
if isFailure:
font = pygame.font.Font(None, 36)
text = font.render("GAME OVER~!", True, (255, 0, 0))
screen.blit(text, (240, 220))
pygame.display.update()
def update_without_input():
if isFailure:
return
global waitIndex
waitIndex = waitIndex + 1 if "waitIndex" in globals() else 1
if waitIndex == 20:
moveSnake()
waitIndex = 1
def update_with_input():
global moveDirection
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
keys = pygame.key.get_pressed()
if keys[pygame.K_a] and moveDirection != 'D':
moveDirection = 'A'
moveSnake()
elif keys[pygame.K_d] and moveDirection != 'A':
moveDirection = 'D'
moveSnake()
elif keys[pygame.K_w] and moveDirection != 'S':
moveDirection = 'W'
moveSnake()
elif keys[pygame.K_s] and moveDirection != 'W':
moveDirection = 'S'
moveSnake()
def main():
startup()
clock = pygame.time.Clock()
while True:
show()
update_without_input()
update_with_input()
clock.tick(24)
if __name__ == "__main__":
main()