使用CodeBuddy基于Pygame模块实现贪吃蛇游戏
本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴
前言
作为一个天天和代码死磕的程序员,上班时间真的就像在打仗!需求文档一堆接一堆,代码改了又改,眼睛盯着屏幕久了都快成斗鸡眼了。在这种高压下,我居然在上班摸鱼的时候,用 CodeBuddy 搞出了个基于 Pygame 的贪吃蛇游戏,
每天一打开电脑,看着那密密麻麻的代码,脑子就开始嗡嗡响。有时候改个 bug,改着改着都怀疑人生了。这时候摸鱼搞贪吃蛇游戏,简直就是我的 “救命稻草”!打开 CodeBuddy,从零开始捣鼓游戏,从设计游戏窗口大小,到让贪吃蛇在屏幕上动起来,整个人瞬间就沉浸进去了。看着自己一点点搭建的贪吃蛇在屏幕上扭来扭去,那种成就感,真的无敌了,下面就展示下如何从0到1实现这款游戏的
使用CodeBuddy进行实操
Codebuddy 最戳我的就是它超快的代码生成速度。就拿贪吃蛇游戏来说,要是自己从零开始敲代码,光是搭个基础框架,就得吭哧吭哧写好一会儿,还不一定能写得顺。但在 Codebuddy 里,只要我用大白话输入需求,比如 “搞个 Pygame 的贪吃蛇游戏窗口”,它唰地一下就能给我甩出一段能用的代码。这效率,直接把摸鱼开发的时间成本砍了一大半,四舍五入就是多摸了半小时鱼啊!
我们打开vscode进入到拓展中直接搜索CodeBuddy,点击安装这个插件就行了
我们先在chat模式生成出我们需要的对应的README文件
然后在去Craft进行实际代码的生成
测试下效果
实现代码如下,感兴趣的可以去实现下
import pygameimport randomimport sysimport pygame.freetypeimport reimport datetimepygame.init() # 初始化py_game模块fl = pygame.freetype.Font("C://Windows//Fonts//simsun.ttc", 30) # 加载字体 如果此处报错请修改路径为本地字体库screen = pygame.display.set_mode((1186, 668)) # 界面大小pygame.display.set_caption("贪吃蛇") # 修改名称clock = pygame.time.Clock() # 游戏时钟GOLD = 255, 251, 0 # 颜色设定RED = pygame.Color('red')WHITE = 255, 255, 255class Snake:body_list = [] # 记录蛇身位置的列表center_1 = None # 小食物中心center_2 = None # 大食物中心center_2_key = False # 大食物控制钥匙big_time = Nonescore = 0 # 分数记录long = 0 # 蛇身记录fs = 0 # 最终得分WALL = False # 墙 不存在def __init__(self):self.r = 5 # 食物半径self.FOOD_SIZE = 21self.old_pop = None # 尾巴列表self.switch = (0, 0) # 防止撞头开关self.big_food_time_1 = None # 大豆豆时间self.eat_big_food_key = 0 # 大豆豆增长钥匙Snake.body_list = [] # 记录蛇身位置的列表Snake.center_1 = None # 小食物中心Snake.center_2 = None # 大食物中心Snake.center_2_key = False # 大食物控制钥匙Snake.big_time = NoneSnake.score = 0 # 分数记录Snake.long = 7 # 蛇的长度self.SNAKE_SIZE = 21 # 每一块🐍的大小self.x_speech = 0self.y_speech = 0self.speech = (0, 0)self.head_rect = [15, 12] # 蛇头的相对位置self.__draw_head() # 绘制蛇头for p in range(Snake.long): # 绘制蛇身if p != 0:pygame.draw.rect(screen, WHITE, (81 + (self.head_rect[0] - p) * self.SNAKE_SIZE + 1, 66 + self.head_rect[1] * self.SNAKE_SIZE + 1,self.SNAKE_SIZE - 1,self.SNAKE_SIZE - 1))Snake.body_list.append((self.head_rect[0] - p, self.head_rect[1]))def Speech(self, p, switch_1):if switch_1 == 0:self.switch = self.speechswitch_1 = 1if p.type == pygame.KEYDOWN:if p.key == pygame.K_UP:if self.speech != (0, 1) and self.switch != (0, 1):self.y_speech = -1self.x_speech = 0elif p.key == pygame.K_DOWN:if self.speech != (0, -1) and self.switch != (0, -1):self.y_speech = 1self.x_speech = 0elif p.key == pygame.K_RIGHT:if self.speech != (-1, 0) and self.switch != (-1, 0):self.x_speech = 1self.y_speech = 0elif p.key == pygame.K_LEFT:if self.speech != (1, 0) and self.switch != (1, 0) and self.speech != (0, 0):self.x_speech = -1self.y_speech = 0self.speech = (self.x_speech, self.y_speech)return switch_1def move(self):if self.x_speech or self.y_speech != 0:Snake.body_list = [(self.head_rect[0], self.head_rect[1])] + Snake.body_listself.__draw_body()# 位置移动区块self.head_rect[0] += self.speech[0]self.head_rect[1] += self.speech[1]self.__wall() # 墙面传送self.__draw_head() # 绘制蛇头# 判断蛇头吃豆豆if self.head_rect == list(Snake.center_1):Snake.long += 1self.draw_new_food()Snake.score += 10if self.eat_big_food_key > 0:self.old_pop = Snake.body_list.pop()self.eat_big_food_key += 1else:pygame.draw.rect(screen, WHITE, (81 + Snake.body_list[Snake.long - 2][0] * self.SNAKE_SIZE + 1,66 + Snake.body_list[Snake.long - 2][1] * self.SNAKE_SIZE + 1,self.SNAKE_SIZE - 1, self.SNAKE_SIZE - 1)) # 身体增长elif self.x_speech or self.y_speech != 0:self.old_pop = Snake.body_list.pop()self.draw_new_food(False)if Snake.center_2_key: # 大豆豆的时间控制 与 吃到大豆豆的变化if self.head_rect == list(Snake.center_2):Snake.long += 3 # 长度+3Snake.score += 50 # 分数+50self.eat_big_food_key = 3 # 大豆豆增长钥匙Snake.center_2 = None # 清空大豆豆列表Snake.center_2_key = Falsefl.render_to(screen, (560, 80), str(8 - Snake.big_time), (0, 0, 0), size=40)fl.render_to(screen, (560, 80), str(9 - Snake.big_time), (0, 0, 0), size=40)self.big_food_time()if self.eat_big_food_key > 0:Snake.body_list.append(self.old_pop)self.eat_big_food_key -= 1pygame.draw.rect(screen, WHITE, (81 + Snake.body_list[Snake.long - 2 - self.eat_big_food_key][0] * self.SNAKE_SIZE + 1,66 + Snake.body_list[Snake.long - 2 - self.eat_big_food_key][1] * self.SNAKE_SIZE + 1,self.SNAKE_SIZE - 1, self.SNAKE_SIZE - 1))# 判断头吃身体if tuple(self.head_rect) in Snake.body_list:self.speech = (0, 0)self.x_speech = self.y_speech = 0# 游戏结束return 1# 判断头撞地形if AllMap.map_list[AllMap.numb] is not None:if tuple(self.head_rect) in AllMap.map_list[AllMap.numb]:self.speech = (0, 0)self.x_speech = self.y_speech = 0return 1def __draw_head(self):pygame.draw.rect(screen, RED, (81 + self.head_rect[0] * self.SNAKE_SIZE + 1, 66 + self.head_rect[1] * self.SNAKE_SIZE + 1,self.SNAKE_SIZE - 1,self.SNAKE_SIZE - 1))def __draw_body(self):# 覆盖老蛇头pygame.draw.rect(screen, WHITE, (81 + Snake.body_list[0][0] * self.SNAKE_SIZE + 1, 66 + Snake.body_list[0][1] * self.SNAKE_SIZE + 1,self.SNAKE_SIZE - 1,self.SNAKE_SIZE - 1))# 删除蛇尾if self.eat_big_food_key <= 0:pygame.draw.rect(screen, (0, 0, 0), (81 + Snake.body_list[Snake.long - 1][0] * self.SNAKE_SIZE + 1,66 + Snake.body_list[Snake.long - 1][1] * self.SNAKE_SIZE + 1,self.SNAKE_SIZE, self.SNAKE_SIZE))@staticmethoddef __Center():"""随机生成豆豆位置"""center = (random.randint(0, 24), random.randint(0, 24)) # 随机生成食物的相对位置# 判断随机数是否与蛇身重合,并处理while True:if center in Snake.body_list:center = (random.randint(0, 24), random.randint(0, 24))elif center == Snake.center_1 or center == Snake.center_2:center = (random.randint(0, 24), random.randint(0, 24))elif AllMap.map_list[AllMap.numb] is not None and center in AllMap.map_list[AllMap.numb]:center = (random.randint(0, 24), random.randint(0, 24))else:return centerdef draw_new_food(self, key=True):if key:Snake.center_1 = Snake.__Center()pygame.draw.circle(screen, WHITE,(81 + Snake.center_1[0] * self.FOOD_SIZE + 11, 66 + Snake.center_1[1] * self.FOOD_SIZE + 11),self.r)if Snake.long % 12 == 0 and key:Snake.center_2 = Snake.__Center()pygame.draw.circle(screen, GOLD,(81 + Snake.center_2[0] * self.FOOD_SIZE + 11,66 + Snake.center_2[1] * self.FOOD_SIZE + 11),self.r + 2)Snake.center_2_key = Trueself.big_food_time_1 = int(pygame.time.get_ticks() / 1000)def big_food_time(self):time_2 = int(pygame.time.get_ticks() / 1000)Snake.big_time = time_2 - self.big_food_time_1if time_2 - self.big_food_time_1 >= 8:pygame.draw.circle(screen, (0, 0, 0),(81 + Snake.center_2[0] * self.FOOD_SIZE + 11,66 + Snake.center_2[1] * self.FOOD_SIZE + 11),self.r + 2)fl.render_to(screen, (560, 80), '1', (0, 0, 0), size=40)Snake.center_2 = NoneSnake.center_2_key = Falsedef __wall(self):"""判断是否有墙及传送"""if Snake.WALL:if self.head_rect[0] == 25 or self.head_rect[0] == -1 or self.head_rect[1] == 25 or self.head_rect[1] == -1: # 判断撞墙over()else:if self.head_rect[0] == 25: # 墙面传送self.head_rect[0] = 0elif self.head_rect[1] == 25:self.head_rect[1] = 0elif self.head_rect[0] == -1:self.head_rect[0] = 24elif self.head_rect[1] == -1:self.head_rect[1] = 24class GameSpeed:game_fps_min_speed = 5game_fps_high_speed = 10game_fps_max_speed = 24class AllMap:GAME_WINDOW_NO = (80, 65, 529, 529)GAME_WINDOW_HA = (78, 63, 532, 532)WALL = False # 无墙map_list = [None,((2, 2), (2, 4), (2, 5), (2, 19), (2, 20), (2, 21), (2, 22), (1, 1), (1, 2), (1, 4), (1, 5), (2, 1),(4, 1), (5, 1), (3, 19), (3, 20), (3, 21), (3, 22), (4, 2), (4, 4), (4, 5), (4, 19), (4, 20), (4, 21),(4, 22), (19, 1), (20, 1), (5, 2), (5, 4), (5, 5), (5, 19), (5, 20), (5, 21), (5, 22), (19, 2),(19, 4), (19, 5), (22, 1), (23, 1), (23, 2), (19, 19), (19, 20), (19, 21), (19, 22), (20, 2), (20, 4),(20, 5), (20, 19), (20, 20), (23, 4), (23, 5), (20, 21), (20, 22), (21, 19), (21, 20), (21, 21),(21, 22), (22, 2), (22, 4), (22, 5), (22, 19), (22, 20), (22, 21), (22, 22), (7, 7), (8, 7), (9, 7),(10, 7), (11, 7), (12, 7), (13, 7), (14, 7), (15, 7), (16, 7), (17, 7), (7, 8), (8, 8), (9, 8),(10, 8), (11, 8), (12, 8), (13, 8), (14, 8), (15, 8), (16, 8), (17, 8), (7, 16), (8, 16), (9, 16),(10, 16), (11, 16), (12, 16), (13, 16), (14, 16), (15, 16), (16, 16), (17, 16), (7, 17), (8, 17),(9, 17), (10, 17), (11, 17), (12, 17), (13, 17), (14, 17), (15, 17), (16, 17), (17, 17)),((1, 10), (2, 9), (3, 8), (4, 7), (5, 6), (6, 5), (7, 4), (8, 3), (9, 2), (10, 1), (2, 10), (3, 9),(4, 8), (5, 7), (6, 6), (7, 5), (8, 4), (9, 3), (10, 2), (14, 1), (15, 2), (16, 3), (17, 4), (18, 5),(19, 6), (20, 7), (21, 8), (22, 9), (23, 10), (14, 2), (15, 3), (16, 4), (17, 5), (18, 6), (19, 7),(20, 8), (21, 9), (22, 10), (6, 15), (6, 16), (6, 17), (6, 18), (6, 19), (6, 20), (6, 21), (6, 22),(6, 23), (6, 24), (7, 17), (7, 18), (7, 19), (7, 20), (7, 21), (7, 22), (7, 23), (7, 24), (17, 17),(17, 18), (17, 19), (17, 20), (17, 21), (17, 22), (17, 23), (17, 24), (18, 15), (18, 16), (18, 17),(18, 18), (18, 19), (18, 20), (18, 21), (18, 22), (18, 23), (18, 24), (8, 15), (9, 15), (10, 15),(11, 15), (12, 15), (13, 15), (14, 15), (15, 15), (16, 15)),((3, 7), (4, 7), (7, 7), (8, 7), (3, 8), (4, 8), (7, 8), (8, 8), (3, 9), (4, 9), (7, 9), (8, 9),(3, 10), (4, 10), (7, 10), (8, 10), (3, 11), (4, 11), (7, 11), (8, 11), (3, 12), (4, 12), (7, 12),(8, 12), (3, 13), (4, 13), (7, 13), (8, 13), (3, 14), (4, 14), (7, 14), (8, 14), (3, 15), (4, 15),(7, 15), (8, 15), (3, 16), (4, 16), (7, 16), (8, 16), (3, 18), (4, 18), (7, 18), (8, 18), (3, 19),(4, 19), (7, 19), (8, 19), (18, 1), (18, 2), (18, 3), (18, 6), (18, 7), (18, 8), (21, 1), (21, 2),(21, 3), (21, 6), (21, 7), (21, 8), (16, 3), (17, 3), (22, 3), (23, 3), (23, 6), (22, 6), (17, 6),(16, 6))] # 地图列表 只内置了两个地图,不喜可在此列表中删除,也可以将ini文件中自定义的元组复制到此处防止自定义的地图丢失numb = 0 # 地图选择def __init__(self):map_file = open('gamer_map.ini', 'a+') # 创建地图文件map_file.seek(0)map_fl_read = map_file.read() # 将读取到的地图合并到map_listlien = re.findall('<([\s\S]*?)>', map_fl_read)for i in lien:AllMap.map_list.append(eval(i))map_file.close()@classmethoddef draw_window(cls, mode):if mode:pygame.draw.rect(screen, GOLD, cls.GAME_WINDOW_HA, 5)else:pygame.draw.rect(screen, (0, 0, 0), cls.GAME_WINDOW_HA, 5)pygame.draw.rect(screen, GOLD, cls.GAME_WINDOW_NO, 1)@classmethoddef draw_map(cls):"""绘制地图"""pygame.draw.rect(screen, (0, 0, 0), (81, 66, 526, 526))Snake()if AllMap.numb == len(AllMap.map_list):fl.render_to(screen, (250, 250), "绘制地图", fgcolor=(255, 0, 255), bgcolor=(0, 0, 0, 60), size=50)elif cls.map_list[AllMap.numb] is not None:for i in cls.map_list[AllMap.numb]:pygame.draw.rect(screen, (0, 255, 255), (81 + i[0] * 21 + 1, 66 + i[1] * 21 + 1, 20, 20))@classmethoddef gamer_draw_map(cls):pointer_place = (12, 10) # 指针位置列表new_map_list = [] # 创建一个空列表while True:pygame.draw.rect(screen, (0, 0, 0), (81 + pointer_place[0] * 21, 66 + pointer_place[1] * 21, 22, 22), 1)if int(pygame.time.get_ticks() / 100) % 10 < 5: # 指针闪烁效果color_set = REDelse:color_set = (0, 255, 255)for i in pygame.event.get(): # 获取监听事件if i.type == pygame.QUIT:sys.exit()elif i.type == pygame.KEYDOWN: # 按键操作if i.key == pygame.K_UP:pointer_place = (pointer_place[0], pointer_place[1] - 1)if pointer_place[1] < 0:pointer_place = (pointer_place[0], 24)elif i.key == pygame.K_DOWN:pointer_place = (pointer_place[0], pointer_place[1] + 1)if pointer_place[1] > 24:pointer_place = (pointer_place[0], 0)elif i.key == pygame.K_LEFT:pointer_place = (pointer_place[0] - 1, pointer_place[1])if pointer_place[0] < 0:pointer_place = (24, pointer_place[1])elif i.key == pygame.K_RIGHT:pointer_place = (pointer_place[0] + 1, pointer_place[1])if pointer_place[0] > 24:pointer_place = (0, pointer_place[1])elif i.key == pygame.K_SPACE and pointer_place not in (Snake.body_list + [(15, 12)]): # 绘制地形# 判断是否在列表中,不在则添加,在则删除 并绘制if pointer_place in new_map_list:new_map_list.remove(pointer_place)pygame.draw.rect(screen, (0, 0, 0),(81 + pointer_place[0] * 21 + 1,66 + pointer_place[1] * 21 + 1, 20, 20))else:new_map_list.append(pointer_place)pygame.draw.rect(screen, (0, 255, 255),(81 + pointer_place[0] * 21 + 1,66 + pointer_place[1] * 21 + 1, 20, 20))elif i.key == pygame.K_ESCAPE: # 返回上层,此次绘制无效maps()elif i.key == pygame.K_KP_ENTER or i.key == pygame.K_RETURN: # 完成绘制# 提醒是否绘制完成fl.render_to(screen, (220, 110), '保存并开始', fgcolor=WHITE, size=50, bgcolor=(0, 0, 0, 60))fl.render_to(screen, (240, 180), '确定 取消', fgcolor=WHITE, bgcolor=(0, 0, 0, 60))yx_list = [(230, 195), (365, 195)]yx_key = 0switch_key = Truewhile switch_key:pygame.draw.circle(screen, (0, 0, 0), yx_list[yx_key], 6)for p in pygame.event.get(): # 获取监听事件if p.type == pygame.QUIT:sys.exit()elif p.type == pygame.KEYDOWN:if p.key == pygame.K_LEFT or p.key == pygame.K_RIGHT:if yx_key == 0:yx_key = 1else:yx_key = 0elif p.key == pygame.K_KP_ENTER or p.key == pygame.K_RETURN:pygame.draw.rect(screen, (0, 0, 0), (220, 110, 250, 100))for j in new_map_list:pygame.draw.rect(screen, (0, 255, 255), (81 + j[0] * 21 + 1, 66 + j[1] * 21 + 1, 20, 20))if yx_key == 0: # 保存并开始if len(new_map_list) != 0:AllMap.map_list.append(tuple(new_map_list))map_file = open('gamer_map.ini', 'a+') # 追加写入创建的地图map_file.write('<')map_file.write(str(tuple(new_map_list)))map_file.write('>\n')map_file.close()else:AllMap.numb = 0action()else: # 继续绘制switch_key = Falseif switch_key:pygame.draw.circle(screen, (255, 0, 255), yx_list[yx_key], 6)pygame.display.update() # 刷新屏幕clock.tick(30) # 游戏时钟pygame.draw.rect(screen, color_set, (81 + pointer_place[0] * 21, 66 + pointer_place[1] * 21, 22, 22), 1)pygame.display.update() # 刷新屏幕clock.tick(30) # 游戏时钟def single_move(sin_rect, p, mode=1):"""选项移动:param sin_rect: 三角坐标:param p: 按键检测:param mode: 模式:return: 三角坐标"""if mode == 1:if p.key == pygame.K_UP:for j in sin_rect:j[1] -= 80elif p.key == pygame.K_DOWN:for j in sin_rect:j[1] += 80elif p.key == pygame.K_RETURN or p.key == pygame.K_KP_ENTER:pygame.draw.rect(screen, (0, 0, 0), (100, 70, 500, 500))if sin_rect[0][1] == 200: # 开始游戏 选择地图maps()elif sin_rect[0][1] == 280: # 速度设置speed_setting()elif sin_rect[0][1] == 360: # 历史高分high_score()elif sin_rect[0][1] == 440: # 退出游戏sys.exit()if sin_rect[0][1] < 200:for j in sin_rect:j[1] += 320elif sin_rect[0][1] > 440:for j in sin_rect:j[1] -= 320return sin_rectelif mode == 2:if p.key == pygame.K_UP:for j in sin_rect:j[1] -= 50elif p.key == pygame.K_DOWN:for j in sin_rect:j[1] += 50elif p.key == pygame.K_RETURN or p.key == pygame.K_KP_ENTER:pygame.draw.rect(screen, (0, 0, 0), (81, 66, 526, 526))if sin_rect[0][1] == 310:AllMap.draw_map()action()elif sin_rect[0][1] == 360:star()if sin_rect[0][1] < 310:for j in sin_rect:j[1] += 100elif sin_rect[0][1] > 360:for j in sin_rect:j[1] -= 100return sin_rectelif mode == 3:if p.key == pygame.K_UP and sin_rect[0][0][0] == 210: # 指针位置for j in sin_rect[0]:j[1] -= 140for j in sin_rect[1]:j[1] -= 140elif p.key == pygame.K_DOWN and sin_rect[0][0][0] == 210:for j in sin_rect[0]:j[1] += 140for j in sin_rect[1]:j[1] += 140elif p.key == pygame.K_LEFT:if sin_rect[0][0][1] == 185:GameSpeed.game_fps_min_speed -= 1if GameSpeed.game_fps_min_speed < 1:GameSpeed.game_fps_min_speed = GameSpeed.game_fps_high_speedelif sin_rect[0][0][1] == 325:GameSpeed.game_fps_high_speed -= 1if GameSpeed.game_fps_high_speed < GameSpeed.game_fps_min_speed:GameSpeed.game_fps_high_speed = GameSpeed.game_fps_max_speed - 1elif sin_rect[0][0][1] == 465:GameSpeed.game_fps_max_speed -= 1if GameSpeed.game_fps_max_speed <= GameSpeed.game_fps_high_speed:GameSpeed.game_fps_max_speed = 35elif p.key == pygame.K_RIGHT:if sin_rect[0][0][1] == 185:GameSpeed.game_fps_min_speed += 1if GameSpeed.game_fps_min_speed > GameSpeed.game_fps_high_speed:GameSpeed.game_fps_min_speed = 1elif sin_rect[0][0][1] == 325:GameSpeed.game_fps_high_speed += 1if GameSpeed.game_fps_high_speed > GameSpeed.game_fps_max_speed - 1:GameSpeed.game_fps_high_speed = GameSpeed.game_fps_min_speedelif sin_rect[0][0][1] == 465:GameSpeed.game_fps_max_speed += 1if GameSpeed.game_fps_max_speed > 35:GameSpeed.game_fps_max_speed = GameSpeed.game_fps_high_speed + 1elif p.key == pygame.K_RETURN or p.key == pygame.K_KP_ENTER:if sin_rect[0][0][1] == 120:sin_rect = [[[410, 185], [410, 215], [410 + (30 ** 2 - 15 ** 2) ** 0.5, 200]],[[290, 185], [290, 215], [290 - (30 ** 2 - 15 ** 2) ** 0.5, 200]]]elif sin_rect[0][0][1] == 260:sin_rect = [[[410, 325], [410, 355], [410 + (30 ** 2 - 15 ** 2) ** 0.5, 340]],[[290, 325], [290, 355], [290 - (30 ** 2 - 15 ** 2) ** 0.5, 340]]]elif sin_rect[0][0][1] == 400:sin_rect = [[[410, 465], [410, 495], [410 + (30 ** 2 - 15 ** 2) ** 0.5, 480]],[[290, 465], [290, 495], [290 - (30 ** 2 - 15 ** 2) ** 0.5, 480]]]elif sin_rect[0][0][1] == 540: # 回主页pygame.draw.rect(screen, (0, 0, 0), (100, 70, 500, 520))star()elif sin_rect[0][0][1] == 185:sin_rect = [[[210, 120], [210, 150], [210 + (30 ** 2 - 15 ** 2) ** 0.5, 135]],[[486, 120], [486, 150], [486 - (30 ** 2 - 15 ** 2) ** 0.5, 135]]]elif sin_rect[0][0][1] == 325:sin_rect = [[[210, 260], [210, 290], [210 + (30 ** 2 - 15 ** 2) ** 0.5, 275]],[[486, 260], [486, 290], [486 - (30 ** 2 - 15 ** 2) ** 0.5, 275]]]elif sin_rect[0][0][1] == 465:sin_rect = [[[210, 400], [210, 430], [210 + (30 ** 2 - 15 ** 2) ** 0.5, 415]],[[486, 400], [486, 430], [486 - (30 ** 2 - 15 ** 2) ** 0.5, 415]]]if sin_rect[0][0][1] < 120: # 指针位置循环for j in sin_rect[0] + sin_rect[1]:j[1] += 560elif sin_rect[1][0][1] > 540:for j in sin_rect[0] + sin_rect[1]:j[1] -= 560return sin_rectelif mode == 4:if p.key == pygame.K_LEFT: # 左切换地图AllMap.numb -= 1if AllMap.numb < 0:AllMap.numb = len(AllMap.map_list)AllMap.draw_map()elif p.key == pygame.K_RIGHT: # 右切换地图AllMap.numb += 1if AllMap.numb > len(AllMap.map_list):AllMap.numb = 0AllMap.draw_map()elif p.key == pygame.K_RETURN or p.key == pygame.K_KP_ENTER:if AllMap.numb == len(AllMap.map_list): # 进入绘图模式pygame.draw.rect(screen, (0, 0, 0), (250, 250, 200, 50))pygame.draw.polygon(screen, (0, 0, 0), ([73, 315], [73, 345], [73 - (30 ** 2 - 15 ** 2) ** 0.5, 330]))pygame.draw.polygon(screen, (0, 0, 0), ([615, 315], [615, 345], [615 + (30 ** 2 - 15 ** 2) ** 0.5, 330]))pygame.draw.rect(screen, (0, 0, 0), (666, 66, 500, 530))fl.render_to(screen, (670, 110), '绘制地图:', fgcolor=WHITE, size=50)fl.render_to(screen, (670, 180), ' 使用 "←" "→" "↑" ', fgcolor=WHITE, size=40)fl.render_to(screen, (670, 250), '"↓" 移动,空格键绘制', fgcolor=WHITE, size=40)fl.render_to(screen, (670, 320), '地图,再次使用空格键可', fgcolor=WHITE, size=40)fl.render_to(screen, (670, 390), '撤销,"←┘"键完成绘', fgcolor=WHITE, size=40)fl.render_to(screen, (670, 460), '制,ESC键取消绘制。', fgcolor=WHITE, size=40)fl.render_to(screen, (670, 520), ' 提示: 请勿将封闭的几何图形留', fgcolor=WHITE, size=25)fl.render_to(screen, (670, 560), '空,否则食物有可能随机产生在其中!', fgcolor=WHITE, size=25)AllMap.gamer_draw_map()else: # 开始游戏pygame.draw.polygon(screen, (0, 0, 0), ([73, 315], [73, 345], [73 - (30 ** 2 - 15 ** 2) ** 0.5, 330]))pygame.draw.polygon(screen, (0, 0, 0), ([615, 315], [615, 345], [615 + (30 ** 2 - 15 ** 2) ** 0.5, 330]))pygame.draw.rect(screen, (0, 0, 0), (650, 65, 520, 600))action()elif p.key == pygame.K_SPACE:AllMap.WALL = not AllMap.WALLSnake.WALL = not Snake.WALLAllMap.draw_window(AllMap.WALL)elif p.key == pygame.K_ESCAPE:pygame.draw.rect(screen, (0, 0, 0), (81, 66, 526, 526))pygame.draw.polygon(screen, (0, 0, 0), ([73, 315], [73, 345], [73 - (30 ** 2 - 15 ** 2) ** 0.5, 330]))pygame.draw.polygon(screen, (0, 0, 0), ([615, 315], [615, 345], [615 + (30 ** 2 - 15 ** 2) ** 0.5, 330]))star()def star(fps=60):single_rect = [[220, 200], [220, 230], [220 + (30 ** 2 - 15 ** 2) ** 0.5, 215]]fl.render_to(screen, (260, 190), "开始游戏", fgcolor=GOLD, size=50)fl.render_to(screen, (260, 270), "速度设置", fgcolor=GOLD, size=50)fl.render_to(screen, (260, 350), "历史高分", fgcolor=GOLD, size=50)fl.render_to(screen, (260, 430), "退出游戏", fgcolor=GOLD, size=50)pygame.draw.rect(screen, (0, 0, 0), (650, 65, 520, 600))fl.render_to(screen, (700, 180), ' 使用 "↑"', fgcolor=WHITE, size=40)fl.render_to(screen, (700, 270), '"↓" 键选择模式,', fgcolor=WHITE, size=40)fl.render_to(screen, (700, 360), '"←┘" 键确认。', fgcolor=WHITE, size=40)"""开始界面"""while True:pygame.draw.rect(screen, (0, 0, 0), (220, single_rect[0][1], 26, 31))for i in pygame.event.get():if i.type == pygame.QUIT:sys.exit()elif i.type == pygame.KEYDOWN:single_rect = single_move(single_rect, i, mode=1)pygame.draw.polygon(screen, RED, single_rect)pygame.display.update() # 刷新屏幕clock.tick(fps) # 游戏时钟def action(fps=GameSpeed.game_fps_min_speed):snake = Snake()pygame.draw.rect(screen, (0, 0, 0), (650, 420, 500, 300))fl.render_to(screen, (682, 470), '游戏说明:', fgcolor=WHITE)fl.render_to(screen, (682, 520), ' 使用 "↑" "↓" "←" "→"', fgcolor=WHITE)fl.render_to(screen, (682, 570), '键控制方向,长按空格键加速移', fgcolor=WHITE)fl.render_to(screen, (682, 620), '动。', fgcolor=WHITE)action_time = int(pygame.time.get_ticks() / 1000)snake.draw_new_food()while True:"""游戏主循环"""switch = 0for i in pygame.event.get():if i.type == pygame.QUIT:sys.exit()else:switch = snake.Speech(i, switch)fps = GameSpeed.game_fps_min_speed + int(Snake.long / 15)if fps >= GameSpeed.game_fps_high_speed:fps = GameSpeed.game_fps_high_speedif i.type == pygame.KEYDOWN:if i.key == pygame.K_SPACE:fps = GameSpeed.game_fps_max_speeda = snake.move() # 蛇身移动Snake.fs = Snake.score - (int(pygame.time.get_ticks() / 1000) - action_time) // 5 * 3pygame.draw.rect(screen, (0, 0, 0), (650, 65, 520, 355))fl.render_to(screen, (680, 70), "得 分:%5d" % Snake.fs,fgcolor=WHITE, size=60)fl.render_to(screen, (682, 270), "当前速度:%2dm/s" % fps, fgcolor=WHITE, size=60)fl.render_to(screen, (682, 370), "游戏时长:%4ds" % (int(pygame.time.get_ticks() / 1000) - action_time),fgcolor=WHITE, size=60)fl.render_to(screen, (682, 170), "蛇身长度:%4dm" % Snake.long, fgcolor=WHITE, size=60)if Snake.center_2_key:fl.render_to(screen, (560, 80), str(8 - Snake.big_time + 1), (0, 0, 0), size=40)fl.render_to(screen, (560, 80), str(8 - Snake.big_time), (0, 0, 0), size=40)fl.render_to(screen, (560, 80), str(8 - Snake.big_time), (250, 250, 0), size=40)pygame.display.update() # 刷新屏幕clock.tick(fps) # 游戏时钟if a == 1: # 判断结束游戏write_score()over()def over(fps_s=30):"""结束界面"""single_rect = [[200, 310], [200, 330], [200 + (20 ** 2 - 10 ** 2) ** 0.5, 320]]fl.render_to(screen, (240, 250), "GAME OVER", fgcolor=GOLD, size=50)fl.render_to(screen, (240, 310), "重新开始", fgcolor=WHITE, bgcolor=(0, 0, 0, 60))fl.render_to(screen, (240, 360), "返回主页", fgcolor=WHITE, bgcolor=(0, 0, 0, 60))while True:pygame.draw.rect(screen, (0, 0, 0), (200, single_rect[0][1], 26, 31))for i in pygame.event.get():if i.type == pygame.QUIT:sys.exit()elif i.type == pygame.KEYDOWN:single_rect = single_move(single_rect, i, mode=2)pygame.draw.polygon(screen, RED, single_rect)pygame.display.update() # 刷新屏幕clock.tick(fps_s) # 游戏时钟def speed_setting():"""速度设置"""single_rect = [[[210, 120], [210, 150], [210 + (30 ** 2 - 15 ** 2) ** 0.5, 135]],[[486, 120], [486, 150], [486 - (30 ** 2 - 15 ** 2) ** 0.5, 135]]]fl.render_to(screen, (250, 110), "初始速度", fgcolor=WHITE, size=50)fl.render_to(screen, (250, 250), "最大速度", fgcolor=WHITE, size=50)fl.render_to(screen, (250, 390), "加速速度", fgcolor=WHITE, size=50)fl.render_to(screen, (250, 530), "返回主页", fgcolor=WHITE, size=50)pygame.draw.rect(screen, (0, 0, 0), (650, 65, 520, 600))fl.render_to(screen, (700, 150), ' 使用 "↑",', fgcolor=WHITE, size=40)fl.render_to(screen, (700, 240), '"↓"键选择模式,', fgcolor=WHITE, size=40)fl.render_to(screen, (700, 330), '"←","→"键调节,', fgcolor=WHITE, size=40)fl.render_to(screen, (700, 420), '"←┘" 键确认。', fgcolor=WHITE, size=40)while True:pygame.draw.rect(screen, (0, 0, 0), (single_rect[0][0][0], single_rect[0][0][1], 26, 31))pygame.draw.rect(screen, (0, 0, 0), (single_rect[1][0][0], single_rect[1][0][1], -26, 31))pygame.draw.rect(screen, WHITE, (300, 175, 100, 50))pygame.draw.rect(screen, WHITE, (300, 315, 100, 50))pygame.draw.rect(screen, WHITE, (300, 455, 100, 50))fl.render_to(screen, (340, 186), "%2d" % GameSpeed.game_fps_min_speed, fgcolor=(0, 0, 0), bgcolor=WHITE, size=40) # 初始速度fl.render_to(screen, (340, 326), "%2d" % GameSpeed.game_fps_high_speed, fgcolor=(0, 0, 0), bgcolor=WHITE, size=40) # 最大速度fl.render_to(screen, (340, 466), "%2d" % GameSpeed.game_fps_max_speed, fgcolor=(0, 0, 0), bgcolor=WHITE, size=40) # 加速速度for i in pygame.event.get():if i.type == pygame.QUIT:sys.exit()elif i.type == pygame.KEYDOWN:single_rect = single_move(single_rect, i, mode=3)pygame.draw.polygon(screen, RED, single_rect[0])pygame.draw.polygon(screen, RED, single_rect[1])pygame.display.update() # 刷新屏幕clock.tick(60) # 游戏时钟def maps(fps=20):"""地图选择"""pygame.draw.rect(screen, (0, 0, 0), (81, 66, 527, 527))pygame.draw.rect(screen, (0, 0, 0), (666, 66, 500, 530))Snake()AllMap.draw_map()fl.render_to(screen, (670, 160), '"←" "→"键切换地图,', fgcolor=WHITE, size=40)fl.render_to(screen, (670, 260), '空格键切换无墙模式,', fgcolor=WHITE, size=40)fl.render_to(screen, (670, 360), '"←┘"键开始游戏,', fgcolor=WHITE, size=40)fl.render_to(screen, (670, 460), 'ESC 键返回主页', fgcolor=WHITE, size=40)single_rect = [[[73, 315], [73, 345], [73 - (30 ** 2 - 15 ** 2) ** 0.5, 330]],[[615, 315], [615, 345], [615 + (30 ** 2 - 15 ** 2) ** 0.5, 330]]]pygame.draw.polygon(screen, RED, single_rect[0])pygame.draw.polygon(screen, RED, single_rect[1])while True:for i in pygame.event.get():if i.type == pygame.QUIT:sys.exit()elif i.type == pygame.KEYDOWN:single_move(single_rect, i, mode=4)pygame.display.update() # 刷新屏幕clock.tick(fps) # 游戏时钟def high_score(fps=10):score_lists = []score_fl = open('score_history.txt', 'r+')score_str = score_fl.read()score_list = re.findall("<([\s\S]*?)>", score_str)for i in score_list:score_lists.append((int(re.findall("(\d+?),", i)[0]), int(re.findall("long: *(\d+?),", i)[0]), re.findall("time:([\s\S]*?);", i)[0]))score_lists.sort(reverse=True)score_fl.seek(0)for i in score_lists:score_fl.write("<score:%5d, long:%3d, time:%s;>\n" % (i[0], i[1], i[2]))score_fl.close()i = 0j = len(score_lists)if j >= 6:j = 6while i < j:fl.render_to(screen, (105, 100 + i * 78), "NO.%d—分数:%5d 长度:%3d" %(i + 1, score_lists[i][0], score_lists[i][1]), fgcolor=WHITE, size=(40 - i * 2))fl.render_to(screen, (180, 140 + i * 76), "时期: %s" % score_lists[i][2], fgcolor=WHITE, size=(34 - i * 2))i += 1while True:for i in pygame.event.get():if i.type == pygame.QUIT:sys.exit()elif i.type == pygame.KEYDOWN:if i.key == pygame.K_RETURN or i.key == pygame.K_KP_ENTER:pygame.draw.rect(screen, (0, 0, 0), (81, 66, 527, 527))star()pygame.display.update() # 刷新屏幕clock.tick(fps) # 游戏时钟def write_score():"""记录分数"""now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')score_fl = open('score_history.txt', 'a+')score_fl.write("<score:%5d, long:%3d, time:%s;>\n" % (Snake.fs, Snake.long, now_time))score_fl.close()AllMap()AllMap.draw_window(AllMap.WALL)score_file = open('score_history.txt', 'a+') # 检测分数记录文件score_file.close()star()
总结
在上班时间用 CodeBuddy 搞贪吃蛇游戏,一开始我还有点小愧疚,但现在回头想想,这简直是我打工人生活里的高光时刻!既能缓解压力,又能激发创造力、提升技术,妥妥的 “摸鱼赢家”!下次摸鱼,我准备再整点新花样,搞个俄罗斯方块啥的,美滋滋!