C++版:
代码说明:
- main.cpp:实现了贪吃蛇游戏的核心逻辑,包括游戏初始化、界面绘制、用户输入处理、游戏状态更新等功能
- Makefile:提供项目编译配置,支持通过make命令编译生成可执行文件
- 游戏特性:经典的贪吃蛇玩法,支持WASD控制方向,X键退出游戏,实时显示得分,碰撞检测(边界和自身)
#include <iostream> #include <conio.h> #include <windows.h> #include <deque> #include <ctime> #include <cstdlib> using namespace std; // 游戏区域大小 const int WIDTH = 30; const int HEIGHT = 20; // 方向枚举 enum Direction { STOP = 0, LEFT, RIGHT, UP, DOWN }; // 蛇的坐标点结构体 struct Point { int x; int y; }; // 全局变量 bool gameOver; Point food; deque<Point> snake; // 使用双端队列存储蛇身 Direction dir; int score; // 初始化游戏 void Setup() { gameOver = false; dir = STOP; // 初始化蛇头位置 Point head = {WIDTH / 2, HEIGHT / 2}; snake.push_front(head); // 随机生成食物位置 srand((unsigned) time(NULL)); food.x = rand() % WIDTH; food.y = rand() % HEIGHT; score = 0; } // 绘制游戏界面 void Draw() { system("cls"); // 清屏 // 绘制上边界 for (int i = 0; i < WIDTH+2; i++) cout << "#"; cout << endl; for (int i = 0; i < HEIGHT; i++) { for (int j = 0; j < WIDTH; j++) { // 绘制左边界 if (j == 0) cout << "#"; // 绘制蛇头或身体 bool isSnake = false; for (int k = 0; k < snake.size(); k++) { if (snake[k].x == j && snake[k].y == i) { if (k == 0) // 蛇头 cout << "O"; else // 蛇身 cout << "o"; isSnake = true; break; } } // 绘制食物 if (!isSnake) { if (j == food.x && i == food.y) cout << "F"; else cout << " "; } // 绘制右边界 if (j == WIDTH - 1) cout << "#"; } cout << endl; } // 绘制下边界 for (int i = 0; i < WIDTH+2; i++) cout << "#"; cout << endl; // 显示分数 cout << "Score: " << score << endl; } // 处理用户输入 void Input() { if (_kbhit()) { switch (_getch()) { case 'a': case 'A': if (dir != RIGHT) dir = LEFT; break; case 'd': case 'D': if (dir != LEFT) dir = RIGHT; break; case 'w': case 'W': if (dir != DOWN) dir = UP; break; case 's': case 'S': if (dir != UP) dir = DOWN; break; case 'x': case 'X': gameOver = true; break; } } } // 游戏逻辑更新 void Logic() { // 根据方向移动蛇头 Point newHead = snake.front(); switch (dir) { case LEFT: newHead.x--; break; case RIGHT: newHead.x++; break; case UP: newHead.y--; break; case DOWN: newHead.y++; break; default: break; } // 检查碰撞边界 if (newHead.x >= WIDTH || newHead.x < 0 || newHead.y >= HEIGHT || newHead.y < 0) gameOver = true; // 检查碰撞自身 for (int i = 0; i < snake.size(); i++) { if (snake[i].x == newHead.x && snake[i].y == newHead.y) gameOver = true; } // 添加新头部 snake.push_front(newHead); // 检查是否吃到食物 if (newHead.x == food.x && newHead.y == food.y) { score += 10; // 重新生成食物 food.x = rand() % WIDTH; food.y = rand() % HEIGHT; } else { // 移除尾部(没有吃到食物) snake.pop_back(); } } int main() { Setup(); while (!gameOver) { Draw(); Input(); Logic(); Sleep(100); // 控制游戏速度 } cout << "Game Over! Final Score: " << score << endl; return 0; }python版:
代码说明:
- snake_game.py:实现了完整的贪吃蛇游戏逻辑,包括蛇的移动、食物生成、碰撞检测、分数计算等功能
- requirements.txt:项目依赖配置文件,指定了pygame版本要求
- 游戏特性:支持方向键控制、自动边界循环、碰撞检测、实时分数显示、游戏结束提示和重新开始功能
- 界面设计:采用网格背景、不同颜色区分蛇头蛇身、清晰的UI提示和操作说明
import pygame import sys import random import math # 初始化Pygame pygame.init() # 游戏常量 WINDOW_WIDTH = 800 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) GREEN = (0, 255, 0) RED = (255, 0, 0) BLUE = (0, 0, 255) YELLOW = (255, 255, 0) PURPLE = (128, 0, 128) GRAY = (128, 128, 128) DARK_GREEN = (0, 200, 0) # 方向常量 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 = RIGHT self.score = 0 self.grow_to = 3 self.is_alive = True def get_head_position(self): return self.positions[0] def update(self): if not self.is_alive: return 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, pos in enumerate(self.positions): rect = pygame.Rect(pos[0] * GRID_SIZE, pos[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE) if i == 0: # 蛇头 pygame.draw.rect(surface, DARK_GREEN, rect) pygame.draw.rect(surface, BLACK, rect, 1) else: # 蛇身 pygame.draw.rect(surface, GREEN, rect) pygame.draw.rect(surface, BLACK, rect, 1) def change_direction(self, direction): # 防止蛇反向移动 if (direction[0] * -1, direction[1] * -1) != self.direction: self.direction = direction class Food: def __init__(self): self.position = (0, 0) self.color = RED 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, self.color, rect) pygame.draw.rect(surface, BLACK, rect, 1) class Game: def __init__(self): self.window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_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.game_state = "playing" # playing, game_over def handle_events(self): for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() if event.type == pygame.KEYDOWN: if self.game_state == "playing": 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 self.game_state == "game_over": if event.key == pygame.K_SPACE: self.restart_game() def update(self): if self.game_state == "playing": self.snake.update() # 检查蛇是否存活 if not self.snake.is_alive: self.game_state = "game_over" return # 检查是否吃到食物 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() def render(self): self.window.fill(BLACK) # 绘制网格背景 for x in range(0, WINDOW_WIDTH, GRID_SIZE): pygame.draw.line(self.window, GRAY, (x, 0), (x, WINDOW_HEIGHT), 1) for y in range(0, WINDOW_HEIGHT, GRID_SIZE): pygame.draw.line(self.window, GRAY, (0, y), (WINDOW_WIDTH, y), 1) # 绘制游戏对象 self.snake.render(self.window) self.food.render(self.window) # 绘制分数 score_text = self.font.render(f"分数: {self.snake.score}", True, WHITE) self.window.blit(score_text, (10, 10)) # 绘制游戏状态信息 if self.game_state == "game_over": game_over_text = self.font.render("游戏结束!", True, RED) restart_text = self.small_font.render("按空格键重新开始", True, WHITE) # 居中显示文本 game_over_rect = game_over_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 - 30)) restart_rect = restart_text.get_rect(center=(WINDOW_WIDTH//2, WINDOW_HEIGHT//2 + 10)) self.window.blit(game_over_text, game_over_rect) self.window.blit(restart_text, restart_rect) # 绘制操作说明 if self.game_state == "playing": instructions = [ "使用方向键控制蛇的移动", "吃掉红色食物来增长身体和得分", "避免撞到自己的身体" ] for i, instruction in enumerate(instructions): text = self.small_font.render(instruction, True, YELLOW) self.window.blit(text, (WINDOW_WIDTH - text.get_width() - 10, 10 + i * 25)) pygame.display.flip() def restart_game(self): self.snake.reset() self.food.randomize_position() self.game_state = "playing" def run(self): while True: self.handle_events() self.update() self.render() self.clock.tick(10) # 控制游戏速度 if __name__ == "__main__": game = Game() game.run()