当前位置: 首页 > news >正文

贪吃蛇游戏demo

   在本教程中,我们将探索如何使用Python与Pygame库构建一个经典的贪吃蛇游戏。我们不仅会涵盖游戏的基本逻辑,还会介绍一些更高级的功能,如AI模式、暂停功能以及记录最高分等。无论你是编程新手还是有经验的开发者,这篇指南都将为你提供有价值的信息。

准备工作

首先,确保你已经安装了Python和Pygame库。可以通过以下命令安装Pygame:

pip install pygame

游戏设计与实现

1. 初始化设置

我们首先需要导入必要的库,并初始化Pygame。同时,定义一些基本的颜色和游戏窗口尺寸。

import pygame
import random
import heapq
import jsonpygame.init()
font_style = pygame.font.Font("simhei.ttf", 25)
score_font = pygame.font.Font("simhei.ttf", 35)# 定义颜色
white = (255, 255, 255)
yellow = (255, 255, 102)
black = (0, 0, 0)
red = (213, 50, 80)
green = (0, 255, 0)
blue = (50, 153, 213)dis_width = 800
dis_height = 600
dis = pygame.display.set_mode((dis_width, dis_height))
pygame.display.set_caption('贪吃蛇游戏')

2. 游戏状态管理

GameState类用于管理游戏的状态,包括得分、最高分、游戏模式(手动或AI)等。

class GameState:def __init__(self):self.high_score = 0self.current_score = 0self.game_mode = "human"self.load_high_score()self.paused = False# 其他方法...

3. 路径寻找算法 - A*搜索

为了给AI模式提供路径规划能力,我们实现了A*算法。该算法帮助AI找到从蛇头到食物的最佳路径。

class AStarNode:def __init__(self, position, parent=None):self.position = positionself.parent = parentself.g = 0self.h = 0self.f = 0def __lt__(self, other):return self.f < other.f

 

4. 主循环

游戏的核心部分是主循环,它负责处理用户输入、更新游戏状态、检测碰撞等。

def game_loop(game_state):# 游戏逻辑...

5. AI模式与暂停功能

通过引入AI模式和暂停功能,增加了游戏的趣味性和复杂性。玩家可以选择手动操作或者让电脑自动玩。

if game_state.game_mode == "ai" and not game_state.paused:# AI控制逻辑...
elif event.key == pygame.K_SPACE:game_state.paused = not game_state.paused

 6.完整代码

import pygame
import random
import heapq
import jsonpygame.init()
# simhei.ttf 在与脚本相同的目录下
font_style = pygame.font.Font("simhei.ttf", 25)  # 使用黑体字体,大小为25
score_font = pygame.font.Font("simhei.ttf", 35)  # 使用黑体字体,大小为35# 定义颜色
white = (255, 255, 255)
yellow = (255, 255, 102)
black = (0, 0, 0)
red = (213, 50, 80)
green = (0, 255, 0)
blue = (50, 153, 213)# 游戏窗口大小
dis_width = 800
dis_height = 600dis = pygame.display.set_mode((dis_width, dis_height))
pygame.display.set_caption('贪吃蛇游戏')clock = pygame.time.Clock()
snake_block = 10
snake_speed = 15# 记录文件
HIGH_SCORE_FILE = "snake_score.json"class GameState:def __init__(self):self.high_score = 0self.current_score = 0self.game_mode = "human"  # human/aiself.load_high_score()self.paused = False  # 新增暂停状态def load_high_score(self):try:with open(HIGH_SCORE_FILE, 'r') as f:data = json.load(f)self.high_score = data.get('high_score', 0)except:self.high_score = 0def save_high_score(self):with open(HIGH_SCORE_FILE, 'w') as f:json.dump({'high_score': self.high_score}, f)def update_score(self, points):self.current_score += pointsif self.current_score > self.high_score:self.high_score = self.current_scoreclass AStarNode:def __init__(self, position, parent=None):self.position = positionself.parent = parentself.g = 0self.h = 0self.f = 0def __lt__(self, other):return self.f < other.fdef get_menu_selection():selected = 0options = ["人工模式", "AI模式"]while True:dis.fill(blue)y_pos = dis_height // 2 - 50for i, option in enumerate(options):color = red if i == selected else whitetext = font_style.render(option, True, color)dis.blit(text, [dis_width // 2 - 50, y_pos])y_pos += 50pygame.display.update()for event in pygame.event.get():if event.type == pygame.KEYDOWN:if event.key == pygame.K_DOWN:selected = (selected + 1) % 2elif event.key == pygame.K_UP:selected = (selected - 1) % 2elif event.key == pygame.K_RETURN:return "human" if selected == 0 else "ai"elif event.type == pygame.QUIT:pygame.quit()quit()def find_path(start, end, obstacles):start_node = AStarNode(start)end_node = AStarNode(end)open_list = []closed_list = set()heapq.heappush(open_list, start_node)while open_list:current_node = heapq.heappop(open_list)closed_list.add(current_node.position)if current_node.position == end_node.position:path = []current = current_nodewhile current is not None:path.append(current.position)current = current.parentreturn path[::-1]for direction in [(0, snake_block), (0, -snake_block),(snake_block, 0), (-snake_block, 0)]:node_position = (current_node.position[0] + direction[0],current_node.position[1] + direction[1])if (node_position in closed_list ornode_position in obstacles ornode_position[0] < 0 or node_position[0] >= dis_width ornode_position[1] < 0 or node_position[1] >= dis_height):continuenew_node = AStarNode(node_position, current_node)new_node.g = current_node.g + snake_blocknew_node.h = abs(end[0] - node_position[0]) + abs(end[1] - node_position[1])new_node.f = new_node.g + new_node.hheapq.heappush(open_list, new_node)return Nonedef game_loop(game_state):game_over = Falsegame_close = Falsex1 = dis_width / 2y1 = dis_height / 2x1_change = 0y1_change = 0snake_list = []length_of_snake = 1foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0foody = round(random.randrange(0, dis_height - snake_block) / 10.0) * 10.0ai_path = []last_direction = Nonewhile not game_over:current_head = (x1, y1)obstacles = set(tuple(segment) for segment in snake_list[:-1])if game_state.game_mode == "ai" and not game_state.paused:if not ai_path or current_head != ai_path[-1]:path = find_path(current_head, (foodx, foody), obstacles)if path and len(path) > 1:  # 确保有路径且路径长度大于1ai_path = pathnext_pos = ai_path[1]  # 取下一个位置而不是当前位置x1_change = next_pos[0] - current_head[0]y1_change = next_pos[1] - current_head[1]else:# 如果没有找到路径,尝试随机移动possible_directions = [(0, snake_block), (0, -snake_block),(snake_block, 0), (-snake_block, 0)]random.shuffle(possible_directions)for direction in possible_directions:new_pos = (current_head[0] + direction[0], current_head[1] + direction[1])if (new_pos not in obstacles and0 <= new_pos[0] < dis_width and0 <= new_pos[1] < dis_height):x1_change, y1_change = directionbreakwhile game_close:dis.fill(blue)game_state.save_high_score()msg = score_font.render(f"得分: {game_state.current_score} 最高记录: {game_state.high_score}", True, yellow)dis.blit(msg, [dis_width / 2 - 150, dis_height / 2 - 50])msg = font_style.render("按C重新开始 按Q退出", True, white)dis.blit(msg, [dis_width / 2 - 100, dis_height / 2 + 50])pygame.display.update()for event in pygame.event.get():if event.type == pygame.KEYDOWN:if event.key == pygame.K_q:game_over = Truegame_close = Falseif event.key == pygame.K_c:game_loop(game_state)for event in pygame.event.get():if event.type == pygame.QUIT:game_over = Trueif event.type == pygame.KEYDOWN:if event.key == pygame.K_SPACE:game_state.paused = not game_state.paused  # 切换暂停状态if game_state.game_mode == "human" and not game_state.paused:if event.key == pygame.K_LEFT and x1_change == 0:x1_change = -snake_blocky1_change = 0elif event.key == pygame.K_RIGHT and x1_change == 0:x1_change = snake_blocky1_change = 0elif event.key == pygame.K_UP and y1_change == 0:y1_change = -snake_blockx1_change = 0elif event.key == pygame.K_DOWN and y1_change == 0:y1_change = snake_blockx1_change = 0if game_state.paused:# 显示暂停信息pause_text = score_font.render("游戏暂停", True, red)dis.blit(pause_text, [dis_width / 2 - 70, dis_height / 2 - 20])pygame.display.update()clock.tick(snake_speed)continue# 边界检测 - 碰到边界游戏结束if x1 >= dis_width or x1 < 0 or y1 >= dis_height or y1 < 0:game_close = True# 更新蛇的位置x1 += x1_changey1 += y1_changedis.fill(blue)pygame.draw.rect(dis, green, [foodx, foody, snake_block, snake_block])snake_head = [x1, y1]snake_list.append(snake_head)if len(snake_list) > length_of_snake:del snake_list[0]# 碰撞检测for segment in snake_list[:-1]:if segment == snake_head:game_close = True# 绘制蛇身our_snake(snake_block, snake_list)# 显示分数score_text = score_font.render(f"得分: {game_state.current_score} 最高: {game_state.high_score}", True, yellow)dis.blit(score_text, [10, 10])# 显示模式mode_text = font_style.render(f"模式: {'人工' if game_state.game_mode == 'human' else 'AI'}", True, white)dis.blit(mode_text, [dis_width - 150, 10])pygame.display.update()# 吃食物逻辑if x1 == foodx and y1 == foody:foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0foody = round(random.randrange(0, dis_height - snake_block) / 10.0) * 10.0length_of_snake += 1game_state.update_score(10)clock.tick(snake_speed)pygame.quit()quit()def our_snake(snake_block, snake_list):for x in snake_list:pygame.draw.rect(dis, black, [x[0], x[1], snake_block, snake_block])if __name__ == "__main__":game_state = GameState()game_state.game_mode = get_menu_selection()game_loop(game_state)

7.最终效果

相关文章:

  • 重塑编程体验边界:明基RD280U显示器深度体验
  • Git和Gitlab的部署和操作
  • 小球在摆线上下落的物理过程MATLAB代码
  • Kotlin中的also、apply、invoke用法详解
  • 【音视频】SDL事件
  • 操作系统:计算机世界的基石与演进
  • 内耗型选手如何能做到不内耗?
  • 力扣4-最长公共前缀
  • 每天五分钟深度学习框架pytorch:使用visdom绘制损失函数图像
  • LCD1602液晶显示屏详解(STM32)
  • 误触网络重置,笔记本电脑wifi连接不上解决方法(Win10,Win11通用)
  • react slot传递
  • django filter 日期大于当前日期的
  • 游戏引擎学习第247天:简化DEBUG_VALUE
  • 游戏引擎学习第248天:清理数据块显示
  • HQChart k线图配置
  • (七)RestAPI 毛子(Http 缓存/乐观锁/Polly/Rate limiting)
  • MIT XV6 - 1.1 Lab: Xv6 and Unix utilities - sleep
  • springboot不连接数据库启动(原先连接了mysql数据库)
  • 【Axure高保真原型】3级多选下拉列表
  • 美大学建“私人联盟”对抗政府:学校已存在300年,特朗普才上任3个月
  • 宣称防老年痴呆的“原装进口”保健品McPee被指涉假,未获澳方销售批准
  • 习近平在中共中央政治局第二十次集体学习时强调,坚持自立自强,突出应用导向,推动人工智能健康有序发展
  • 安徽一交通事故责任认定引质疑:民警和司法鉴定人被处罚,已中止诉讼
  • 去年立案侦办侵权假冒案件3.7万起,公安部公布13起案例
  • 夜读丨修车与“不凑合”