贪吃蛇小游戏

点击查看代码
import pygame
import sys
import random

pygame.init()

WIDTH, HEIGHT = 600, 500
GRID_SIZE = 20
GRID_WIDTH = WIDTH // GRID_SIZE
GRID_HEIGHT = HEIGHT // GRID_SIZE
FPS = 10

BACKGROUND = (15, 25, 35)
GRID_COLOR = (30, 45, 60)
SNAKE_HEAD = (0, 180, 0)
SNAKE_BODY = (0, 150, 0)
FOOD_COLOR = (220, 50, 50)
TEXT_COLOR = (200, 220, 240)
GAME_OVER_BG = (0, 0, 0, 180)
UP = (0, -1)
DOWN = (0, 1)
LEFT = (-1, 0)
RIGHT = (1, 0)

class Snake:
    def __init__(self):
        self.reset()
        
    def reset(self):
        self.length = 3
        self.positions = [(GRID_WIDTH // 2, GRID_HEIGHT // 2)]
        self.direction = random.choice([UP, DOWN, LEFT, RIGHT])
        self.score = 0
        self.grow_to = 3
        self.is_alive = True
        
    def get_head_position(self):
        return self.positions[0]
    
    def update(self):
        head = self.get_head_position()
        x, y = self.direction
        new_x = (head[0] + x) % GRID_WIDTH
        new_y = (head[1] + y) % GRID_HEIGHT
        new_position = (new_x, new_y)
        
        if new_position in self.positions[1:]:
            self.is_alive = False
            return
        
        self.positions.insert(0, new_position)
        
        if len(self.positions) > self.grow_to:
            self.positions.pop()
    
    def render(self, surface):
        for i, p in enumerate(self.positions):
            rect = pygame.Rect((p[0] * GRID_SIZE, p[1] * GRID_SIZE), (GRID_SIZE, GRID_SIZE))
            color = SNAKE_HEAD if i == 0 else SNAKE_BODY
            pygame.draw.rect(surface, color, rect)
            
            pygame.draw.rect(surface, (0, 100, 0), rect, 1)
    
    def change_direction(self, direction):
        if (direction[0] * -1, direction[1] * -1) == self.direction:
            return
        self.direction = direction

class Food:
    def __init__(self):
        self.position = (0, 0)
        self.randomize_position()
        
    def randomize_position(self):
        self.position = (random.randint(0, GRID_WIDTH - 1), 
                          random.randint(0, GRID_HEIGHT - 1))
    
    def render(self, surface):
        rect = pygame.Rect((self.position[0] * GRID_SIZE, self.position[1] * GRID_SIZE), 
                           (GRID_SIZE, GRID_SIZE))
        pygame.draw.rect(surface, FOOD_COLOR, rect)
        pygame.draw.rect(surface, (180, 30, 30), rect, 1)

class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((WIDTH, HEIGHT))
        pygame.display.set_caption("简易贪吃蛇游戏")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.SysFont(None, 36)
        self.small_font = pygame.font.SysFont(None, 24)
        
        self.snake = Snake()
        self.food = Food()
        self.speed = FPS
        
    def draw_grid(self):
        for x in range(0, WIDTH, GRID_SIZE):
            pygame.draw.line(self.screen, GRID_COLOR, (x, 0), (x, HEIGHT), 1)
        for y in range(0, HEIGHT, GRID_SIZE):
            pygame.draw.line(self.screen, GRID_COLOR, (0, y), (WIDTH, y), 1)
    
    def draw_score(self):
        score_text = self.font.render(f"得分: {self.snake.score}", True, TEXT_COLOR)
        self.screen.blit(score_text, (10, 10))
        
        length_text = self.small_font.render(f"长度: {len(self.snake.positions)}", True, TEXT_COLOR)
        self.screen.blit(length_text, (10, 50))
        
        speed_text = self.small_font.render(f"速度: {self.speed}", True, TEXT_COLOR)
        self.screen.blit(speed_text, (10, 80))
    
    def draw_game_over(self):
        overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
        overlay.fill(GAME_OVER_BG)
        self.screen.blit(overlay, (0, 0))
        
        game_over_text = self.font.render("游戏结束!", True, (220, 50, 50))
        restart_text = self.font.render("按 R 键重新开始", True, TEXT_COLOR)
        quit_text = self.font.render("按 ESC 键退出", True, TEXT_COLOR)
        score_text = self.font.render(f"最终得分: {self.snake.score}", True, TEXT_COLOR)
        
        self.screen.blit(game_over_text, (WIDTH // 2 - game_over_text.get_width() // 2, HEIGHT // 2 - 80))
        self.screen.blit(score_text, (WIDTH // 2 - score_text.get_width() // 2, HEIGHT // 2 - 30))
        self.screen.blit(restart_text, (WIDTH // 2 - restart_text.get_width() // 2, HEIGHT // 2 + 20))
        self.screen.blit(quit_text, (WIDTH // 2 - quit_text.get_width() // 2, HEIGHT // 2 + 70))
    
    def draw_instructions(self):
        text1 = self.small_font.render("方向键控制移动", True, (180, 200, 220))
        text2 = self.small_font.render("P键暂停/继续", True, (180, 200, 220))
        text3 = self.small_font.render("空格键加速", True, (180, 200, 220))
        
        self.screen.blit(text1, (WIDTH - text1.get_width() - 10, 10))
        self.screen.blit(text2, (WIDTH - text2.get_width() - 10, 40))
        self.screen.blit(text3, (WIDTH - text3.get_width() - 10, 70))
    
    def check_collision(self):
        if self.snake.get_head_position() == self.food.position:
            self.snake.grow_to += 1
            self.snake.score += 10
            self.food.randomize_position()
            
            while self.food.position in self.snake.positions:
                self.food.randomize_position()
            
            if self.snake.score % 50 == 0:
                self.speed = min(self.speed + 1, 20)
    
    def run(self):
        paused = False
        
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                elif event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        pygame.quit()
                        sys.exit()
                    elif not self.snake.is_alive and event.key == pygame.K_r:
                        self.snake.reset()
                        self.food.randomize_position()
                        self.speed = FPS
                    elif self.snake.is_alive:
                        if event.key == pygame.K_UP:
                            self.snake.change_direction(UP)
                        elif event.key == pygame.K_DOWN:
                            self.snake.change_direction(DOWN)
                        elif event.key == pygame.K_LEFT:
                            self.snake.change_direction(LEFT)
                        elif event.key == pygame.K_RIGHT:
                            self.snake.change_direction(RIGHT)
                        elif event.key == pygame.K_p:
                            paused = not paused
                        elif event.key == pygame.K_SPACE:
                            self.speed = min(self.speed + 2, 20)
            
            self.screen.fill(BACKGROUND)
            
            self.draw_grid()
            self.draw_score()
            self.draw_instructions()
            
            if self.snake.is_alive and not paused:
                self.snake.update()
                self.check_collision()
            
            self.snake.render(self.screen)
            self.food.render(self.screen)
            
            if not self.snake.is_alive:
                self.draw_game_over()
            elif paused:
                pause_text = self.font.render("游戏暂停", True, (220, 220, 100))
                self.screen.blit(pause_text, (WIDTH // 2 - pause_text.get_width() // 2, HEIGHT // 2))
                continue_text = self.small_font.render("按 P 键继续", True, TEXT_COLOR)
                self.screen.blit(continue_text, (WIDTH // 2 - continue_text.get_width() // 2, HEIGHT // 2 + 50))
            
            pygame.display.flip()
            self.clock.tick(self.speed)
if __name__ == "__main__":
    game = Game()
    game.run()

posted @ 2025-06-22 13:27  木立青  阅读(11)  评论(0)    收藏  举报