# 使用Pygame制作一个简单的贪吃蛇游戏,实现游戏界面,游戏的得分机制。
import pygame
import sys
import random
from pygame.math import Vector2
# 初始化pygame
pygame.init()
# 游戏设置
CELL_SIZE = 20
CELL_NUMBER = 20
SCREEN_WIDTH = CELL_SIZE * CELL_NUMBER
SCREEN_HEIGHT = CELL_SIZE * CELL_NUMBER
FPS = 60
# 颜色定义
BACKGROUND_COLOR = (175, 215, 70)
SNAKE_COLOR = (75, 105, 47)
FOOD_COLOR = (220, 60, 60)
TEXT_COLOR = (50, 50, 50)
class Snake:
def __init__(self):
# 初始蛇身(3个方块)
self.body = [Vector2(5, 10), Vector2(4, 10), Vector2(3, 10)]
self.direction = Vector2(1, 0) # 初始向右移动
self.new_block = False
def draw_snake(self, screen):
for block in self.body:
block_rect = pygame.Rect(block.x * CELL_SIZE, block.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
pygame.draw.rect(screen, SNAKE_COLOR, block_rect)
# 绘制蛇身内部小矩形增加细节
inner_rect = pygame.Rect(block.x * CELL_SIZE + 4, block.y * CELL_SIZE + 4, CELL_SIZE - 8, CELL_SIZE - 8)
pygame.draw.rect(screen, (90, 130, 60), inner_rect)
def move_snake(self):
if self.new_block:
body_copy = self.body[:]
body_copy.insert(0, body_copy[0] + self.direction)
self.body = body_copy
self.new_block = False
else:
body_copy = self.body[:-1]
body_copy.insert(0, body_copy[0] + self.direction)
self.body = body_copy
def add_block(self):
self.new_block = True
def reset(self):
self.body = [Vector2(5, 10), Vector2(4, 10), Vector2(3, 10)]
self.direction = Vector2(1, 0)
class Food:
def __init__(self, snake_body=None):
self.snake_body = snake_body if snake_body else []
self.randomize()
def draw_food(self, screen):
food_rect = pygame.Rect(self.pos.x * CELL_SIZE, self.pos.y * CELL_SIZE, CELL_SIZE, CELL_SIZE)
pygame.draw.rect(screen, FOOD_COLOR, food_rect)
def randomize(self):
# 确保食物不会生成在蛇身上
while True:
self.x = random.randint(0, CELL_NUMBER - 1)
self.y = random.randint(0, CELL_NUMBER - 1)
self.pos = Vector2(self.x, self.y)
if self.pos not in self.snake_body:
break
class Game:
def __init__(self):
self.snake = Snake()
self.food = Food(self.snake.body) # 传入蛇身用于检查食物位置
self.score = 0
try:
self.game_font = pygame.font.SysFont(None, 25)
except:
# 如果字体加载失败,使用默认字体
self.game_font = pygame.font.Font(None, 25)
def update(self):
self.snake.move_snake()
self.check_collision()
self.check_fail()
def draw_elements(self, screen):
self.draw_grid(screen)
self.food.draw_food(screen)
self.snake.draw_snake(screen)
self.draw_score(screen)
def check_collision(self):
if self.food.pos == self.snake.body[0]:
self.food.randomize()
self.snake.add_block()
self.score += 1
def check_fail(self):
# 检查是否撞墙
snake_head = self.snake.body[0]
if not 0 <= snake_head.x < CELL_NUMBER or not 0 <= snake_head.y < CELL_NUMBER:
self.game_over()
# 检查是否撞到自己
for block in self.snake.body[1:]:
if block == snake_head:
self.game_over()
def game_over(self):
self.snake.reset()
self.score = 0
# 重置食物位置
self.food = Food(self.snake.body)
def draw_grid(self, screen):
for row in range(CELL_NUMBER):
for col in range(CELL_NUMBER):
rect = pygame.Rect(row * CELL_SIZE, col * CELL_SIZE, CELL_SIZE, CELL_SIZE)
pygame.draw.rect(screen, (160, 200, 80) if (row + col) % 2 == 0 else (170, 210, 90), rect)
def draw_score(self, screen):
score_text = f'Score: {self.score}'
try:
score_surface = self.game_font.render(score_text, True, TEXT_COLOR)
score_rect = score_surface.get_rect(topleft=(10, 10))
screen.blit(score_surface, score_rect)
except:
# 如果字体渲染失败,跳过显示
pass
def main():
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('贪吃蛇游戏')
clock = pygame.time.Clock()
game = Game()
# 设置定时移动事件
SCREEN_UPDATE = pygame.USEREVENT
pygame.time.set_timer(SCREEN_UPDATE, 150) # 每150毫秒移动一次
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == SCREEN_UPDATE:
game.update()
if event.type == pygame.KEYDOWN:
# 键盘控制方向
if event.key == pygame.K_UP and game.snake.direction.y != 1:
game.snake.direction = Vector2(0, -1)
if event.key == pygame.K_DOWN and game.snake.direction.y != -1:
game.snake.direction = Vector2(0, 1)
if event.key == pygame.K_LEFT and game.snake.direction.x != 1:
game.snake.direction = Vector2(-1, 0)
if event.key == pygame.K_RIGHT and game.snake.direction.x != -1:
game.snake.direction = Vector2(1, 0)
screen.fill(BACKGROUND_COLOR)
game.draw_elements(screen)
pygame.display.update()
clock.tick(FPS)
if __name__ == "__main__":
main()这个代码这么写可以吗?有什么需要修改的地方吗?请帮我写出修改后的完整代码。