贪吃蛇(有点快

点击查看代码
import pygame
import sys
import random
import os
from pygame.locals import *

# 初始化pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
GRID_SIZE = 20
GRID_WIDTH = SCREEN_WIDTH // GRID_SIZE
GRID_HEIGHT = SCREEN_HEIGHT // GRID_SIZE
FPS = 10

# 方向常量
UP = (0, -1)
DOWN = (0, 1)
LEFT = (-1, 0)
RIGHT = (1, 0)

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 50, 50)
GREEN = (50, 255, 50)
BLUE = (50, 100, 255)
YELLOW = (255, 255, 50)
PURPLE = (180, 50, 230)
WALL_COLOR = (80, 80, 100)
BACKGROUND = (20, 20, 30)
TEXT_COLOR = (220, 220, 220)
HIGHLIGHT = (255, 200, 50)

# 随机蛇颜色
SNAKE_COLORS = [GREEN, BLUE, YELLOW, PURPLE]

class Snake:
    def __init__(self):
        self.reset()
        # 随机选择蛇的颜色
        self.color = random.choice(SNAKE_COLORS)
        self.head_color = (
            min(self.color[0] + 50, 255),
            min(self.color[1] + 50, 255),
            min(self.color[2] + 50, 255)
        )
    
    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.color = random.choice(SNAKE_COLORS)
        self.head_color = (
            min(self.color[0] + 50, 255),
            min(self.color[1] + 50, 255),
            min(self.color[2] + 50, 255)
        )
    
    def get_head_position(self):
        return self.positions[0]
    
    def update(self):
        head = self.get_head_position()
        x, y = self.direction
        new_position = (((head[0] + x) % GRID_WIDTH), (head[1] + y) % GRID_HEIGHT)
        
        # 检查是否撞墙
        if (new_position[0] == 0 or new_position[0] == GRID_WIDTH - 1 or 
            new_position[1] == 0 or new_position[1] == GRID_HEIGHT - 1):
            return False  # 游戏结束
        
        # 检查是否撞到自己
        if new_position in self.positions[1:]:
            return False  # 游戏结束
        
        self.positions.insert(0, new_position)
        if len(self.positions) > self.length:
            self.positions.pop()
        return True
    
    def draw(self, surface):
        for i, p in enumerate(self.positions):
            # 绘制蛇身
            rect = pygame.Rect((p[0] * GRID_SIZE, p[1] * GRID_SIZE), (GRID_SIZE, GRID_SIZE))
            if i == 0:  # 蛇头
                pygame.draw.rect(surface, self.head_color, rect)
                pygame.draw.rect(surface, HIGHLIGHT, rect, 1)
            else:  # 蛇身
                pygame.draw.rect(surface, self.color, rect)
                pygame.draw.rect(surface, (self.color[0]//2, self.color[1]//2, self.color[2]//2), rect, 1)

class Apple:
    def __init__(self):
        self.position = (0, 0)
        self.color = RED
        self.randomize_position()
    
    def randomize_position(self, snake_positions=None):
        if snake_positions is None:
            snake_positions = []
        
        # 生成不在墙内和蛇身上的位置
        while True:
            self.position = (
                random.randint(2, GRID_WIDTH - 3),
                random.randint(2, GRID_HEIGHT - 3)
            )
            if self.position not in snake_positions:
                break
    
    def draw(self, surface):
        rect = pygame.Rect((self.position[0] * GRID_SIZE, self.position[1] * GRID_SIZE), (GRID_SIZE, GRID_SIZE))
        pygame.draw.rect(surface, self.color, rect)
        pygame.draw.rect(surface, (255, 150, 150), rect, 2)
        
        # 绘制苹果梗
        pygame.draw.line(surface, (100, 50, 0), 
                         (self.position[0] * GRID_SIZE + GRID_SIZE//2, self.position[1] * GRID_SIZE - 2),
                         (self.position[0] * GRID_SIZE + GRID_SIZE//2 - 3, self.position[1] * GRID_SIZE - 6), 2)
        
        # 绘制苹果叶子
        leaf_points = [
            (self.position[0] * GRID_SIZE + GRID_SIZE//2, self.position[1] * GRID_SIZE - 5),
            (self.position[0] * GRID_SIZE + GRID_SIZE//2 + 4, self.position[1] * GRID_SIZE - 8),
            (self.position[0] * GRID_SIZE + GRID_SIZE//2 + 2, self.position[1] * GRID_SIZE - 10)
        ]
        pygame.draw.polygon(surface, (50, 200, 50), leaf_points)

def draw_walls(surface):
    # 绘制四周的墙
    for x in range(GRID_WIDTH):
        for y in range(GRID_HEIGHT):
            if (x == 0 or x == GRID_WIDTH - 1 or y == 0 or y == GRID_HEIGHT - 1):
                rect = pygame.Rect((x * GRID_SIZE, y * GRID_SIZE), (GRID_SIZE, GRID_SIZE))
                pygame.draw.rect(surface, WALL_COLOR, rect)
                pygame.draw.rect(surface, (60, 60, 80), rect, 1)

def draw_score(surface, score, high_score):
    # 绘制分数面板
    score_panel = pygame.Rect(SCREEN_WIDTH - 200, 10, 190, 70)
    pygame.draw.rect(surface, (40, 40, 60), score_panel)
    pygame.draw.rect(surface, (100, 100, 140), score_panel, 2)
    
    # 绘制分数文本
    font = pygame.font.SysFont('arial', 24, bold=True)
    score_text = font.render(f'分数: {score}', True, TEXT_COLOR)
    high_score_text = font.render(f'最高分: {high_score}', True, HIGHLIGHT)
    
    surface.blit(score_text, (SCREEN_WIDTH - 180, 25))
    surface.blit(high_score_text, (SCREEN_WIDTH - 180, 55))

def draw_game_over(surface, score):
    # 绘制游戏结束面板
    overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
    overlay.set_alpha(180)
    overlay.fill((0, 0, 0))
    surface.blit(overlay, (0, 0))
    
    font_large = pygame.font.SysFont('arial', 72, bold=True)
    font_medium = pygame.font.SysFont('arial', 36)
    font_small = pygame.font.SysFont('arial', 24)
    
    game_over_text = font_large.render('游戏结束!', True, RED)
    score_text = font_medium.render(f'最终分数: {score}', True, HIGHLIGHT)
    restart_text = font_small.render('按 R 键重新开始', True, TEXT_COLOR)
    quit_text = font_small.render('按 ESC 键退出', True, TEXT_COLOR)
    
    surface.blit(game_over_text, (SCREEN_WIDTH//2 - game_over_text.get_width()//2, SCREEN_HEIGHT//2 - 100))
    surface.blit(score_text, (SCREEN_WIDTH//2 - score_text.get_width()//2, SCREEN_HEIGHT//2))
    surface.blit(restart_text, (SCREEN_WIDTH//2 - restart_text.get_width()//2, SCREEN_HEIGHT//2 + 80))
    surface.blit(quit_text, (SCREEN_WIDTH//2 - quit_text.get_width()//2, SCREEN_HEIGHT//2 + 120))

def main():
    # 设置屏幕
    screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
    pygame.display.set_caption('贪吃蛇游戏')
    clock = pygame.time.Clock()
    
    # 加载最高分
    high_score = 0
    if os.path.exists('high_score.txt'):
        try:
            with open('high_score.txt', 'r') as f:
                high_score = int(f.read())
        except:
            pass
    
    # 创建游戏对象
    snake = Snake()
    apple = Apple()
    apple.randomize_position(snake.positions)
    
    game_over = False
    
    # 主游戏循环
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                # 保存最高分
                with open('high_score.txt', 'w') as f:
                    f.write(str(high_score))
                pygame.quit()
                sys.exit()
            
            if event.type == KEYDOWN:
                if game_over:
                    if event.key == K_r:  # 重新开始
                        snake.reset()
                        apple.randomize_position(snake.positions)
                        game_over = False
                    elif event.key == K_ESCAPE:  # 退出游戏
                        with open('high_score.txt', 'w') as f:
                            f.write(str(high_score))
                        pygame.quit()
                        sys.exit()
                else:
                    # 方向控制
                    if event.key == K_UP and snake.direction != DOWN:
                        snake.direction = UP
                    elif event.key == K_DOWN and snake.direction != UP:
                        snake.direction = DOWN
                    elif event.key == K_LEFT and snake.direction != RIGHT:
                        snake.direction = LEFT
                    elif event.key == K_RIGHT and snake.direction != LEFT:
                        snake.direction = RIGHT
        
        if not game_over:
            # 更新蛇的位置
            if not snake.update():
                game_over = True
                if snake.score > high_score:
                    high_score = snake.score
            
            # 检查是否吃到苹果
            if snake.get_head_position() == apple.position:
                snake.length += 1
                snake.score += 10
                apple.randomize_position(snake.positions)
        
        # 绘制背景
        screen.fill(BACKGROUND)
        
        # 绘制网格(背景)
        for x in range(0, SCREEN_WIDTH, GRID_SIZE):
            pygame.draw.line(screen, (30, 30, 40), (x, 0), (x, SCREEN_HEIGHT))
        for y in range(0, SCREEN_HEIGHT, GRID_SIZE):
            pygame.draw.line(screen, (30, 30, 40), (0, y), (SCREEN_WIDTH, y))
        
        # 绘制墙
        draw_walls(screen)
        
        # 绘制苹果
        apple.draw(screen)
        
        # 绘制蛇
        snake.draw(screen)
        
        # 绘制分数
        draw_score(screen, snake.score, high_score)
        
        # 绘制游戏结束画面
        if game_over:
            draw_game_over(screen, snake.score)
        
        pygame.display.update()
        clock.tick(FPS)

if __name__ == "__main__":
    main()

posted @ 2025-06-23 00:56  昔桯  阅读(17)  评论(0)    收藏  举报