import pygame
import random
import sys
# 初始化pygame
pygame.init()
# 游戏常量
WINDOW_WIDTH = 600
WINDOW_HEIGHT = 600
GRID_SIZE = 20
GRID_WIDTH = WINDOW_WIDTH // GRID_SIZE
GRID_HEIGHT = WINDOW_HEIGHT // GRID_SIZE
# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
DARK_GREEN = (0, 200, 0)
GRAY = (128, 128, 128)
# 方向常量
UP = (0, -1)
DOWN = (0, 1)
LEFT = (-1, 0)
RIGHT = (1, 0)
class Snake:
def __init__(self):
# 初始蛇身(三个方块)
self.positions = [
(GRID_WIDTH // 2, GRID_HEIGHT // 2),
(GRID_WIDTH // 2 - 1, GRID_HEIGHT // 2),
(GRID_WIDTH // 2 - 2, GRID_HEIGHT // 2)
]
self.direction = RIGHT
self.grow_flag = False
def move(self):
head = self.positions[0]
new_head = (head[0] + self.direction[0], head[1] + self.direction[1])
# 插入新头部
self.positions.insert(0, new_head)
# 如果不生长,删除尾部
if not self.grow_flag:
self.positions.pop()
else:
self.grow_flag = False
return new_head
def grow(self):
self.grow_flag = True
def change_direction(self, new_direction):
# 防止蛇反向移动
if (new_direction[0] * -1, new_direction[1] * -1) != self.direction:
self.direction = new_direction
def check_collision(self):
head = self.positions[0]
# 检查是否撞墙
if (head[0] < 0 or head[0] >= GRID_WIDTH or
head[1] < 0 or head[1] >= GRID_HEIGHT):
return True
# 检查是否撞到自己
if head in self.positions[1:]:
return True
return False
class Food:
def __init__(self):
self.position = (0, 0)
self.randomize_position([])
def randomize_position(self, snake_positions):
while True:
pos = (random.randint(0, GRID_WIDTH - 1),
random.randint(0, GRID_HEIGHT - 1))
if pos not in snake_positions:
self.position = pos
break
class Game:
def __init__(self):
self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("贪吃蛇游戏")
self.clock = pygame.time.Clock()
self.font = pygame.font.Font(None, 36)
self.big_font = pygame.font.Font(None, 48)
self.reset_game()
def reset_game(self):
self.snake = Snake()
self.food = Food()
self.food.randomize_position(self.snake.positions)
self.score = 0
self.game_over = False
self.game_speed = 10
def handle_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
return False
if event.type == pygame.KEYDOWN:
if self.game_over:
if event.key == pygame.K_SPACE:
self.reset_game()
elif event.key == pygame.K_ESCAPE:
return False
else:
if event.key == pygame.K_UP or event.key == pygame.K_w:
self.snake.change_direction(UP)
elif event.key == pygame.K_DOWN or event.key == pygame.K_s:
self.snake.change_direction(DOWN)
elif event.key == pygame.K_LEFT or event.key == pygame.K_a:
self.snake.change_direction(LEFT)
elif event.key == pygame.K_RIGHT or event.key == pygame.K_d:
self.snake.change_direction(RIGHT)
return True
def update(self):
if self.game_over:
return
# 移动蛇
new_head = self.snake.move()
# 检查是否吃到食物
if new_head == self.food.position:
self.snake.grow()
self.score += 10
self.food.randomize_position(self.snake.positions)
# 加快游戏速度
if self.score % 50 == 0:
self.game_speed += 1
# 检查碰撞
if self.snake.check_collision():
self.game_over = True
def draw_grid(self):
for x in range(0, WINDOW_WIDTH, GRID_SIZE):
pygame.draw.line(self.screen, GRAY, (x, 0), (x, WINDOW_HEIGHT), 1)
for y in range(0, WINDOW_HEIGHT, GRID_SIZE):
pygame.draw.line(self.screen, GRAY, (0, y), (WINDOW_WIDTH, y), 1)
def draw(self):
self.screen.fill(BLACK)
self.draw_grid()
# 绘制蛇
for i, pos in enumerate(self.snake.positions):
rect = pygame.Rect(
pos[0] * GRID_SIZE,
pos[1] * GRID_SIZE,
GRID_SIZE - 1,
GRID_SIZE - 1
)
if i == 0:
pygame.draw.rect(self.screen, GREEN, rect)
else:
pygame.draw.rect(self.screen, DARK_GREEN, rect)
# 绘制食物
food_rect = pygame.Rect(
self.food.position[0] * GRID_SIZE,
self.food.position[1] * GRID_SIZE,
GRID_SIZE - 1,
GRID_SIZE - 1
)
pygame.draw.rect(self.screen, RED, food_rect)
# 显示分数
score_text = self.font.render(f"分数: {self.score}", True, WHITE)
self.screen.blit(score_text, (10, 10))
# 游戏结束画面
if self.game_over:
overlay = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT))
overlay.set_alpha(128)
overlay.fill(BLACK)
self.screen.blit(overlay, (0, 0))
game_over_text = self.big_font.render("游戏结束!", True, WHITE)
score_text = self.font.render(f"最终分数: {self.score}", True, WHITE)
restart_text = self.font.render("按空格键重新开始", True, WHITE)
exit_text = self.font.render("按ESC键退出", True, WHITE)
text_rect = game_over_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 - 50))
self.screen.blit(game_over_text, text_rect)
text_rect = score_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2))
self.screen.blit(score_text, text_rect)
text_rect = restart_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 + 40))
self.screen.blit(restart_text, text_rect)
text_rect = exit_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 + 70))
self.screen.blit(exit_text, text_rect)
pygame.display.flip()
def run(self):
running = True
while running:
running = self.handle_events()
self.update()
self.draw()
self.clock.tick(self.game_speed)
pygame.quit()
sys.exit()
# 运行游戏
if __name__ == "__main__":
game = Game()
game.run()