介绍
贪吃蛇游戏是经典的小游戏之一,通过控制蛇的移动方向,吃食物来增长蛇的长度,同时避免蛇头碰到墙壁或自身身体。本项目使用Python语言实现了贪吃蛇游戏。
环境设置
- Python 3.x
- Pygame 库
项目结构
snake_game/
│
├── main.py
├── assets/
│ └── eat_sound.wav
└── README.md
代码编写
# main.py
import pygame
import random
# 初始化游戏
pygame.init()
# 设置游戏窗口
WIDTH, HEIGHT = 800, 600
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("贪吃蛇游戏")
# 加载音效
EAT_SOUND = pygame.mixer.Sound("assets/eat_sound.wav")
# 定义颜色
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
# 定义蛇和食物的大小
BLOCK_SIZE = 20
# 定义蛇的移动方向
UP = 0
DOWN = 1
LEFT = 2
RIGHT = 3
# 绘制蛇和食物
def draw_snake(snake):
for block in snake:
pygame.draw.rect(SCREEN, GREEN, (block[0], block[1], BLOCK_SIZE, BLOCK_SIZE))
def draw_food(food):
pygame.draw.rect(SCREEN, RED, (food[0], food[1], BLOCK_SIZE, BLOCK_SIZE))
# 主游戏循环
def main():
clock = pygame.time.Clock()
running = True
snake = [[WIDTH // 2, HEIGHT // 2]]
food = [random.randint(0, WIDTH-BLOCK_SIZE), random.randint(0, HEIGHT-BLOCK_SIZE)]
direction = RIGHT
while running:
SCREEN.fill(WHITE)
draw_snake(snake)
draw_food(food)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and direction != DOWN:
direction = UP
elif event.key == pygame.K_DOWN and direction != UP:
direction = DOWN
elif event.key == pygame.K_LEFT and direction != RIGHT:
direction = LEFT
elif event.key == pygame.K_RIGHT and direction != LEFT:
direction = RIGHT
# 移动蛇头
head = list(snake[0])
if direction == UP:
head[1] -= BLOCK_SIZE
elif direction == DOWN:
head[1] += BLOCK_SIZE
elif direction == LEFT:
head[0] -= BLOCK_SIZE
elif direction == RIGHT:
head[0] += BLOCK_SIZE
snake.insert(0, head)
# 判断是否吃到食物
if snake[0] == food:
EAT_SOUND.play() # 播放吃食物音效
food = [random.randint(0, WIDTH-BLOCK_SIZE), random.randint(0, HEIGHT-BLOCK_SIZE)]
else:
snake.pop()
# 碰撞检测
if (snake[0][0] < 0 or snake[0][0] >= WIDTH or
snake[0][1] < 0 or snake[0][1] >= HEIGHT or
snake[0] in snake[1:]):
running = False
clock.tick(10)
pygame.quit()
if __name__ == "__main__":
main()
详细解释
- 通过Pygame库创建游戏窗口,并加载游戏所需的音效文件。
- 定义了蛇的移动方向和大小,并实现了蛇和食物的绘制功能。
- 在游戏循环中,根据用户按键输入改变蛇的移动方向,更新蛇的位置,并检测是否吃到食物或碰到边界或自身。
- 使用音效增加游戏的趣味性。
总结
通过这个项目,我们学习了如何使用Python和Pygame库来实现一个简单的贪吃蛇游戏。同时,我们也了解了游戏开发中常见的一些概念,如游戏循环、碰撞检测等。
扩展功能
你可以进一步扩展游戏,添加以下功能:
- 增加游戏关卡和难度等级。
- 实现多人游戏模式,让多个玩家同时控制不同的蛇。
- 设计更多有趣的音效和动画效果。
首先,我们需要允许玩家选择游戏的难度等级。我会在代码中添加这个功能。首先,我们定义几个不同的难度等级,并根据不同的等级设置蛇的移动速度和食物出现的频率。然后,在游戏开始时,我们可以让玩家选择他们想要的难度等级:
# main.py
# 定义难度等级
EASY = 1
MEDIUM = 2
HARD = 3
# 设置难度等级对应的速度和食物出现频率
SPEED_MAP = {
EASY: 10,
MEDIUM: 15,
HARD: 20
}
FOOD_FREQUENCY_MAP = {
EASY: 0.1,
MEDIUM: 0.05,
HARD: 0.02
}
# 主游戏循环
def main():
clock = pygame.time.Clock()
running = True
snake = [[WIDTH // 2, HEIGHT // 2]]
food = [random.randint(0, WIDTH-BLOCK_SIZE), random.randint(0, HEIGHT-BLOCK_SIZE)]
direction = RIGHT
# 选择难度等级
difficulty = choose_difficulty()
while running:
SCREEN.fill(WHITE)
draw_snake(snake)
draw_food(food)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP and direction != DOWN:
direction = UP
elif event.key == pygame.K_DOWN and direction != UP:
direction = DOWN
elif event.key == pygame.K_LEFT and direction != RIGHT:
direction = LEFT
elif event.key == pygame.K_RIGHT and direction != LEFT:
direction = RIGHT
# 移动蛇头
head = list(snake[0])
if direction == UP:
head[1] -= BLOCK_SIZE
elif direction == DOWN:
head[1] += BLOCK_SIZE
elif direction == LEFT:
head[0] -= BLOCK_SIZE
elif direction == RIGHT:
head[0] += BLOCK_SIZE
snake.insert(0, head)
# 判断是否吃到食物
if snake[0] == food:
EAT_SOUND.play() # 播放吃食物音效
food = [random.randint(0, WIDTH-BLOCK_SIZE), random.randint(0, HEIGHT-BLOCK_SIZE)]
else:
snake.pop()
# 碰撞检测
if (snake[0][0] < 0 or snake[0][0] >= WIDTH or
snake[0][1] < 0 or snake[0][1] >= HEIGHT or
snake[0] in snake[1:]):
running = False
clock.tick(SPEED_MAP[difficulty])
pygame.quit()
# 添加选择难度等级的函数
def choose_difficulty():
print("请选择难度等级:")
print("1. 简单")
print("2. 中等")
print("3. 困难")
while True:
try:
choice = int(input("请输入选择的难度等级编号:"))
if choice in [EASY, MEDIUM, HARD]:
return choice
else:
print("请输入有效的编号!")
except ValueError:
print("请输入一个有效的整数!")
现在玩家可以在游戏开始时选择难度等级了。接下来我们继续添加多人游戏模式。为了实现多人游戏模式,我们需要创建多条蛇,并允许每个玩家控制其中一条蛇。让我们修改代码来实现这个功能:
# main.py
# 定义玩家控制的蛇
player1_snake = [[WIDTH // 4, HEIGHT // 2]]
player2_snake = [[WIDTH // 4 * 3, HEIGHT // 2]]
# 定义玩家1和玩家2的控制键
PLAYER1_CONTROLS = {
pygame.K_w: UP,
pygame.K_s: DOWN,
pygame.K_a: LEFT,
pygame.K_d: RIGHT
}
PLAYER2_CONTROLS = {
pygame.K_UP: UP,
pygame.K_DOWN: DOWN,
pygame.K_LEFT: LEFT,
pygame.K_RIGHT: RIGHT
}
# 主游戏循环
def main():
clock = pygame.time.Clock()
running = True
player1_direction = RIGHT
player2_direction = LEFT
# 选择难度等级
difficulty = choose_difficulty()
while running:
SCREEN.fill(WHITE)
draw_snake(player1_snake)
draw_snake(player2_snake)
draw_food(food)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
# 玩家1控制
if event.key in PLAYER1_CONTROLS:
player1_direction = PLAYER1_CONTROLS[event.key]
# 玩家2控制
elif event.key in PLAYER2_CONTROLS:
player2_direction = PLAYER2_CONTROLS[event.key]
# 移动玩家1的蛇头
player1_head = list(player1_snake[0])
if player1_direction == UP:
player1_head[1] -= BLOCK_SIZE
elif player1_direction == DOWN:
player1_head[1] += BLOCK_SIZE
elif player1_direction == LEFT:
player1_head[0] -= BLOCK_SIZE
elif player1_direction == RIGHT:
player1_head[0] += BLOCK_SIZE
player1_snake.insert(0, player1_head)
# 移动玩家2的蛇头
player2_head = list(player2_snake[0])
if player2_direction == UP:
player2_head[1] -= BLOCK_SIZE
elif player2_direction == DOWN:
player2_head[1] += BLOCK_SIZE
elif player2_direction == LEFT:
player2_head[0] -= BLOCK_SIZE
elif player2_direction == RIGHT:
player2_head[0] += BLOCK_SIZE
player2_snake.insert(0, player2_head)
# 判断是否吃到食物
if player1_snake[0] == food:
EAT_SOUND.play() # 播放吃食物音效
food = [random.randint(0, WIDTH-BLOCK_SIZE), random.randint(0, HEIGHT-BLOCK_SIZE)]
else:
player1_snake.pop()
if player2_snake[0] == food:
EAT_SOUND.play() # 播放吃食物音效
food = [random.randint(0, WIDTH-BLOCK_SIZE), random.randint(0, HEIGHT-BLOCK_SIZE)]
else:
player2_snake.pop()
# 碰撞检测
if (player1_snake[0][0] < 0 or player1_snake[0][0] >= WIDTH or
player1_snake[0][1] < 0 or player1_snake[0][1] >= HEIGHT or
player1_snake[0] in player1_snake[1:] or
player1_snake[0] in player2_snake):
running = False
if (player2_snake[0][0] < 0 or player2_snake[0][0] >= WIDTH or
player2_snake[0][1] < 0 or player2_snake[0][1] >= HEIGHT or
player2_snake[0] in player2_snake[1:] or
player2_snake[0] in player1_snake):
running = False
clock.tick(SPEED_MAP[difficulty])
pygame.quit()
现在,我们可以让两位玩家同时控制不同的蛇了。
接下来我们添加更多有趣的音效和动画效果。
首先,我们来实现碰撞音效和游戏结束动画,以及吃食物音效和增加蛇长度的动画效果。
我们需要导入所需的音频文件,并在游戏中适当的位置播放这些音效。同时,我们也需要在游戏结束时显示一个游戏结束的动画效果。
import pygame
import random
# 添加音频文件
COLLISION_SOUND = pygame.mixer.Sound("collision_sound.wav")
EAT_SOUND = pygame.mixer.Sound("eat_sound.wav")
# 在游戏结束时显示游戏结束动画
def game_over_animation():
font = pygame.font.Font(None, 36)
game_over_text = font.render("Game Over", True, RED)
text_rect = game_over_text.get_rect(center=(WIDTH/2, HEIGHT/2))
SCREEN.blit(game_over_text, text_rect)
pygame.display.update()
pygame.time.wait(2000) # 等待2秒钟显示游戏结束画面
# 主游戏循环
def main():
clock = pygame.time.Clock()
running = True
player1_direction = RIGHT
player2_direction = LEFT
# 选择难度等级
difficulty = choose_difficulty()
while running:
SCREEN.fill(WHITE)
draw_snake(player1_snake)
draw_snake(player2_snake)
draw_food(food)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN:
# 玩家1控制
if event.key in PLAYER1_CONTROLS:
player1_direction = PLAYER1_CONTROLS[event.key]
# 玩家2控制
elif event.key in PLAYER2_CONTROLS:
player2_direction = PLAYER2_CONTROLS[event.key]
# 移动玩家1的蛇头
player1_head = list(player1_snake[0])
if player1_direction == UP:
player1_head[1] -= BLOCK_SIZE
elif player1_direction == DOWN:
player1_head[1] += BLOCK_SIZE
elif player1_direction == LEFT:
player1_head[0] -= BLOCK_SIZE
elif player1_direction == RIGHT:
player1_head[0] += BLOCK_SIZE
player1_snake.insert(0, player1_head)
# 移动玩家2的蛇头
player2_head = list(player2_snake[0])
if player2_direction == UP:
player2_head[1] -= BLOCK_SIZE
elif player2_direction == DOWN:
player2_head[1] += BLOCK_SIZE
elif player2_direction == LEFT:
player2_head[0] -= BLOCK_SIZE
elif player2_direction == RIGHT:
player2_head[0] += BLOCK_SIZE
player2_snake.insert(0, player2_head)
# 判断是否吃到食物
if player1_snake[0] == food:
EAT_SOUND.play() # 播放吃食物音效
food = [random.randint(0, WIDTH-BLOCK_SIZE), random.randint(0, HEIGHT-BLOCK_SIZE)]
# 增加蛇长度
player1_snake.append(player1_snake[-1])
else:
player1_snake.pop()
if player2_snake[0] == food:
EAT_SOUND.play() # 播放吃食物音效
food = [random.randint(0, WIDTH-BLOCK_SIZE), random.randint(0, HEIGHT-BLOCK_SIZE)]
# 增加蛇长度
player2_snake.append(player2_snake[-1])
else:
player2_snake.pop()
# 碰撞检测
if (player1_snake[0][0] < 0 or player1_snake[0][0] >= WIDTH or
player1_snake[0][1] < 0 or player1_snake[0][1] >= HEIGHT or
player1_snake[0] in player1_snake[1:] or
player1_snake[0] in player2_snake):
COLLISION_SOUND.play() # 播放碰撞音效
game_over_animation()
running = False
if (player2_snake[0][0] < 0 or player2_snake[0][0] >= WIDTH or
player2_snake[0][1] < 0 or player2_snake[0][1] >= HEIGHT or
player2_snake[0] in player2_snake[1:] or
player2_snake[0] in player1_snake):
COLLISION_SOUND.play() # 播放碰撞音效
game_over_animation()
running = False
clock.tick(SPEED_MAP[difficulty])
pygame.quit()
现在游戏中添加了碰撞音效和游戏结束动画,以及吃食物音效和增加蛇长度的动画效果。