Pygame贪吃蛇实现吃食物后新增随机位置敌人的方法
问题核心原因
原代码用单个变量enemy_position存储敌人坐标,同一时间只能记录1个敌人的位置,自然无法实现敌人累加效果。只需要把单个敌人变量替换为存储所有敌人坐标的列表,对应修改生成、绘制、碰撞判定三个环节的逻辑即可实现需求。
具体修改点
- 替换原单个敌人变量为敌人列表,初始化时先放入1个初始敌人,对应0分时场上存在1个敌人的初始状态
- 吃到食物的逻辑分支中,新增生成新敌人坐标、追加到敌人列表的操作,保证每吃1个食物多1个敌人
- 把原来绘制单个敌人的逻辑改为遍历敌人列表,逐个绘制所有红色方块
- 把原来单个敌人的碰撞判定改为遍历敌人列表,只要蛇头碰到任意一个敌人就触发游戏结束
- 新增坐标合法性校验:生成敌人、食物时避开蛇身、已有物体的位置,避免出现刚生成就撞脸、重叠的bug
修改后完整可运行代码
import sys,pygame import random pygame.display.set_caption('Snake Game') screen_width, screen_height = 600,470 screen = pygame.display.set_mode((screen_width, screen_height)) fps = pygame.time.Clock() snake_speed = 22 # 修正原代码重复定义颜色的问题 white = pygame.Color(250, 250, 250) green = pygame.Color(0, 250, 0) blue = pygame.Color(0, 0, 255) black = pygame.Color(0, 0, 0) red = pygame.Color(255, 0, 0) pygame.init() snake_position = [100, 50] # 修正原代码蛇身初始坐标重复的笔误 snake_body = [ [150, 80], [100, 50], [90, 50], [80, 50] ] food_position = [random.randrange(1, (screen_width//10)) * 10, random.randrange(1, (screen_height//10)) * 10] food_spawn = True # 敌人列表存储所有敌人坐标,初始生成1个敌人 enemy_list = [] def generate_new_enemy(): while True: new_enemy = [random.randrange(1, (screen_width//10)) * 10, random.randrange(1, (screen_height//10)) * 10] if new_enemy not in snake_body and new_enemy not in enemy_list and new_enemy != food_position: return new_enemy enemy_list.append(generate_new_enemy()) direction = 'RIGHT' score = 0 def show_score(choice, color, font, size): score_font = pygame.font.SysFont(font, size) score_surface = score_font.render('Score : ' + str(score), True, color) score_rect = score_surface.get_rect() screen.blit(score_surface, score_rect) def game_over(): my_font = pygame.font.SysFont('comic sans', 50) game_over_surface = my_font.render('Your Score is : ' + str(score), True, red) game_over_rect = game_over_surface.get_rect() game_over_rect.midtop = (screen_width/2, screen_height/4) screen.blit(game_over_surface, game_over_rect) pygame.display.flip() while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() while True: change_to = direction for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: change_to = 'UP' if event.key == pygame.K_DOWN: change_to = 'DOWN' if event.key == pygame.K_LEFT: change_to = 'LEFT' if event.key == pygame.K_RIGHT: change_to = 'RIGHT' if change_to == 'UP' and direction != 'DOWN': direction = 'UP' if change_to == 'DOWN' and direction != 'UP': direction = 'DOWN' if change_to == 'LEFT' and direction != 'RIGHT': direction = 'LEFT' if change_to == 'RIGHT' and direction != 'LEFT': direction = 'RIGHT' if direction == 'UP': snake_position[1] -= 10 if direction == 'DOWN': snake_position[1] += 10 if direction == 'LEFT': snake_position[0] -= 10 if direction == 'RIGHT': snake_position[0] += 10 snake_body.insert(0, list(snake_position)) if snake_position[0] == food_position[0] and snake_position[1] == food_position[1]: score += 1 food_spawn = False # 吃到食物时追加1个新敌人 enemy_list.append(generate_new_enemy()) else: snake_body.pop() if not food_spawn: # 生成食物时避开蛇身和敌人 while True: food_position = [random.randrange(1, (screen_width//10)) * 10, random.randrange(1, (screen_height//10)) * 10] if food_position not in snake_body and food_position not in enemy_list: break food_spawn = True screen.fill(black) for pos in snake_body: pygame.draw.rect(screen, blue, pygame.Rect( pos[0], pos[1], 10, 10)) pygame.draw.rect(screen, green, pygame.Rect( food_position[0], food_position[1], 10, 10)) # 遍历绘制所有敌人 for enemy_pos in enemy_list: pygame.draw.rect(screen, red, pygame.Rect( enemy_pos[0], enemy_pos[1], 10, 10)) # 遍历判定和所有敌人的碰撞 for enemy_pos in enemy_list: if snake_position[0] == enemy_pos[0] and snake_position[1] == enemy_pos[1]: game_over() # 撞墙判定 if snake_position[0] < 0 or snake_position[0] > screen_width-10: game_over() if snake_position[1] < 0 or snake_position[1] > screen_height-10: game_over() # 撞自身判定 for block in snake_body[1:]: if snake_position[0] == block[0] and snake_position[1] == block[1]: game_over() show_score(1, white, 'comic sans', 20) pygame.display.update() fps.tick(snake_speed)
运行效果
- 初始场上固定1个红色敌人
- 每吃1个绿色食物加1分,同时在随机空位生成1个新的红色敌人,已生成的敌人永久保留
- 吃到5个食物时场上总计存在6个敌人,完全匹配需求
- 同步修复了原代码中颜色重复定义、蛇身初始坐标重复、食物可能刷在障碍物上的小问题
内容的提问来源于stack exchange,提问作者Idkmane
相关产品推荐
相关产品推荐

