如何在Pygame贪吃蛇游戏中实现蛇的穿墙传送功能?
问题
刚接触编程,正在制作一款简易贪吃蛇游戏,参考了Edurika的教程,但教程未涵盖蛇的穿墙传送功能,自己无法实现。这是课程作业,希望有人帮忙解决该问题,也欢迎任何改进建议。以下是我的代码:
import pygame import time import random pygame.init() 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 = 400 dis_height = 500 dis = pygame.display.set_mode((dis_width, dis_height)) pygame.display.set_caption('SNELIAS') clock = pygame.time.Clock() snake_block = 10 snake_speed = 8 font_style = pygame.font.SysFont("bahnschrift", 25) score_font = pygame.font.SysFont("comicsansms", 35) def Your_score(score): value = score_font.render("Your Score: " + str(score), True, yellow) dis.blit(value, [0, 0]) 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]) def message(msg, color): mesg = font_style.render(msg, True, color) dis.blit(mesg, [dis_width / 6, dis_height / 3]) def gameLoop(): game_over = False game_close = False x1 = dis_width / 2 y1 = dis_height / 2 x1_change = 0 y1_change = 0 snake_List = [] Length_of_snake = 1 foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0 foody = round(random.randrange(0, dis_height - snake_block) / 10.0) * 10.0 image = pygame.image.load("snakegrnd.jpeg") screenUpdate = pygame.transform.scale(image, (dis_width, dis_height)) while not game_over: dis.blit(screenUpdate, (0, 0)) while game_close == True: message("You Lost! Press C-Play Again or Q-Quit", white) Your_score(Length_of_snake - 1) pygame.display.update() for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_q: game_over = True game_close = False if event.key == pygame.K_c: gameLoop() for event in pygame.event.get(): if event.type == pygame.QUIT: game_over = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: x1_change = -snake_block y1_change = 0 elif event.key == pygame.K_RIGHT: x1_change = snake_block y1_change = 0 elif event.key == pygame.K_UP: y1_change = -snake_block x1_change = 0 elif event.key == pygame.K_DOWN: y1_change = snake_block x1_change = 0 if x1 >= dis_width or x1 < 0 or y1 >= dis_height or y1 < 0: game_close = True x1 += x1_change y1 += y1_change pygame.draw.rect(dis, green, [foodx, foody, snake_block, snake_block]) snake_Head = [] snake_Head.append(x1) snake_Head.append(y1) snake_List.append(snake_Head) if len(snake_List) > Length_of_snake: del snake_List[0] for x in snake_List[:-1]: if x == snake_Head: game_close = True our_snake(snake_block, snake_List) Your_score(Length_of_snake - 1) pygame.display.update() if x1 == foodx and y1 == foody: foodx = round(random.randrange(0, dis_width - snake_block) / 10.0) * 10.0 foody = round(random.randrange(0, dis_height - snake_block) / 10.0) * 10.0 Length_of_snake += 1 clock.tick(snake_speed) pygame.quit() quit() gameLoop()
解决方案与改进建议
一、实现穿墙传送功能
原代码中碰到边界会直接触发游戏结束,只需替换边界判断逻辑为传送即可:
找到这段代码:
if x1 >= dis_width or x1 < 0 or y1 >= dis_height or y1 < 0: game_close = True x1 += x1_change y1 += y1_change
修改为:
# 先更新位置 x1 += x1_change y1 += y1_change # 穿墙传送逻辑 if x1 >= dis_width: x1 = 0 elif x1 < 0: x1 = dis_width - snake_block if y1 >= dis_height: y1 = 0 elif y1 < 0: y1 = dis_height - snake_block
说明:必须先更新位置再判断边界,这样蛇头完全超出边界后才会触发传送;x方向传送到对面时要减去snake_block,避免蛇头部分露出边界(因为蛇块大小是10,直接设为0或dis_width会导致绘制时出界)。
二、其他改进建议
- 避免递归重启游戏:原代码中按C重启时调用
gameLoop()属于递归,多次重启会导致栈溢出。建议把重启逻辑改成重置变量而非递归,比如:# 替换原来的if event.key == pygame.K_c: gameLoop() if event.key == pygame.K_c: # 重置所有游戏状态变量 x1 = dis_width / 2 y1 = dis_height / 2 x1_change = 0 y1_change = 0 snake_List = [] Length_of_snake = 1 foodx = round(random.randrange(0, dis_width - snake_block)/10.0)*10.0 foody = round(random.randrange(0, dis_height - snake_block)/10.0)*10.0 game_close = False - 防止食物生成在蛇身上:当前食物随机生成可能直接出现在蛇身,导致无法吃到。可以添加循环判断,直到食物位置不在蛇列表中:
# 生成食物时替换原代码 while True: foodx = round(random.randrange(0, dis_width - snake_block)/10.0)*10.0 foody = round(random.randrange(0, dis_height - snake_block)/10.0)*10.0 # 检查食物是否在蛇身上 if [foodx, foody] not in snake_List: break - 禁止反向移动:当前可以直接按相反方向键让蛇撞自己,比如向左走时按右键,蛇会立刻掉头撞身体。可以添加判断,禁止直接反向:
# 按键处理时修改 if event.key == pygame.K_LEFT: if x1_change != snake_block: # 当前不是向右移动 x1_change = -snake_block y1_change = 0 elif event.key == pygame.K_RIGHT: if x1_change != -snake_block: # 当前不是向左移动 x1_change = snake_block y1_change = 0 elif event.key == pygame.K_UP: if y1_change != snake_block: # 当前不是向下移动 y1_change = -snake_block x1_change = 0 elif event.key == pygame.K_DOWN: if y1_change != -snake_block: # 当前不是向上移动 y1_change = snake_block x1_change = 0 - 优化背景图加载:把背景图加载放到
gameLoop()外面,避免每次重启游戏都重新加载图片,提升性能。 - 添加音效:可以在吃到食物、游戏结束时添加简单音效,增强体验。
内容的提问来源于stack exchange,提问作者E_stkvs
相关产品推荐
相关产品推荐

