鱼C论坛

 找回密码
 立即注册
查看: 1864|回复: 2

pygame贪吃蛇问题(又又又是我)

[复制链接]
发表于 2023-11-24 19:29:23 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#贪吃蛇.py
import pygame
import sys
from pygame.locals import *
import 金币
import 蛇身
pygame.init()
size = width, height = 600, 400
bg = (255, 255, 255)
YELLOW = (255, 255, 0)
snake = (0, 255, 0)
BLACK = (0, 0, 0)
Sbody = {}
fanxiang = 'right'
left = 300
top = 200

screen = pygame.display.set_mode(size)
pygame.display.set_caption('贪吃蛇')
move = USEREVENT
pygame.time.set_timer(move, 1 * 100)
money = USEREVENT + 1
pygame.time.set_timer(money, 5 * 1000)
score = 0
score_font = pygame.font.Font(None, 20)

Money = pygame.sprite.Group()
snakebody = pygame.sprite.Group()

while True:
   
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == move:
            if fanxiang == 'left':
                Sbody[0] = [left, top]
                left -= 11
               
            elif fanxiang == 'top':
                Sbody[0] = [left, top]
                top -= 11
               
            elif fanxiang == 'right':
                Sbody[0] = [left, top]
                left += 11
               
            elif fanxiang == 'bottom':
                Sbody[0] = [left, top]
                top += 11
               
        
        #生成金币
        elif event.type == money:
            
            m = 金币.money()
            Money.add(m)
   
    key_pressed = pygame.key.get_pressed()
   
    #控制方向
    if key_pressed[K_w] or key_pressed[K_UP]:
        fanxiang = 'top'
    if key_pressed[K_s] or key_pressed[K_DOWN]:
        fanxiang = 'bottom'
    if key_pressed[K_d] or key_pressed[K_RIGHT]:
        fanxiang = 'right'
    if key_pressed[K_a] or key_pressed[K_LEFT]:
        fanxiang = 'left'


   
        

    screen.fill(bg)
    #蛇身机制
    for b in snakebody:
        lastnumber = b.number - 1
        nextnumber = b.number + 1
        Sbody[b.number] = [b.width, b.height]
        b.width = Sbody[lastnumber][0]
        b.height = Sbody[lastnumber][1]
        b.rect = pygame.Rect(b.width, b.height, 10, 10)
        pygame.draw.rect(screen, snake, b.rect, 0)
        
    #金币机制
    for i in Money:
        pygame.draw.rect(screen, YELLOW, i.rect, 0)
        if i.rect.colliderect(pygame.Rect(left, top, 10, 10)):
            score+=1000
            thousand = score / 1000
            #增加长度
            s = 蛇身.body(int(Sbody[thousand - 1][0]), int(Sbody[thousand - 1][1]), thousand)
            snakebody.add(s)
            Money.remove(i)
    #绘制贪吃蛇
    pygame.draw.rect(screen, snake, (left, top, 10, 10), 0)
       #显示字迹
    score_text = score_font.render(f'Score:{score}', True, BLACK)
    screen.blit(score_text, (10, 5))
    pygame.display.flip()

#蛇身.py
import pygame
class body(pygame.sprite.Sprite):
    def __init__(self, width, height, number):
        pygame.sprite.Sprite.__init__(self)
        self.width = width
        self.height = height
        self.rect = pygame.Rect(self.width, self.height, 10, 10)
        self.number = number
想请教一下如何做到蛇身完全加长且不有bug(吃了两个金币后才有bug)?

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-11-24 19:30:19 | 显示全部楼层
你好,根据你的代码,我发现在处理蛇身加长的逻辑上存在一些问题。目前的逻辑是在吃到金币后直接增加蛇身的长度,这种方法可能会导致蛇身的增长出现一些bug。

为了解决这个问题,你可以尝试调整蛇身增长的逻辑。一种常见的方法是在蛇头移动的时候,将新的蛇身位置添加到一个队列中,然后在每一帧更新蛇身的位置。当蛇吃到金币时,再根据队列中记录的位置来增加蛇身的长度。

下面是一个示例代码来说明这种方法:
  1. # 在贪吃蛇.py中
  2. # 在初始化部分添加一个队列用来记录蛇身位置
  3. snake_queue = []
  4. # ... 其他部分代码不变 ...
  5. # 蛇身机制
  6. # 将蛇头的位置添加到队列中
  7. snake_queue.insert(0, (left, top))
  8. if len(snake_queue) > len(snakebody):
  9.     snake_queue.pop()
  10. # 金币机制
  11. for i in Money:
  12.     # ... 其他金币相关逻辑 ...
  13. # 绘制贪吃蛇
  14. for idx, body_pos in enumerate(snake_queue):
  15.     pygame.draw.rect(screen, snake, (body_pos[0], body_pos[1], 10, 10), 0)
  16. # 在贪吃蛇.py中其他地方将蛇的移动逻辑修改为更新蛇头位置后自动更新蛇身位置
  17. # 在蛇身.py中,不需要做太大的改动
复制代码

通过这种方法,你可以保证蛇身的长度能够完全增长且不会出现bug。希望对你有所帮助,如果还有其他问题欢迎继续提问。

回复来自于CHAT-GPT。回复仅供参考,如有人工回答,最佳答案请优先选择人工
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-24 19:31:12 | 显示全部楼层
问题出在你的贪吃蛇身体机制的实现上。当你吃到金币的时候,会增加一个蛇身体的实例,并把它加入到`snakebody`这个组中去。但是你并没有更新蛇身体实例之间的相对位置关系,导致后续的蛇身体实例无法正确跟随头部移动。

为了解决这个问题,你可以采取以下步骤:

1. 在`贪吃蛇.py`文件里面,在头部移动的代码前面,添加一个空列表`positions=[]`。
2. 在每次移动的事件里面,将当前头部的位置`(left, top)`添加到`positions`列表的第一个位置,同时删除最后一个位置,以保持列表的长度不变。
3. 在绘制蛇身体的部分代码中,遍历`snakebody`组中的所有身体实例,并根据其编号从`positions`列表中获取对应的位置,然后更新身体实例的位置。
4. 修改金币机制的代码,使得每次吃金币的时候,先判断是否已经有蛇身体实例,如果有的话,取最后一个身体实例的编号加1作为新身体实例的编号。如果没有蛇身体实例,编号设为1。

以下是修改后的代码示例:
  1. import pygame
  2. import sys
  3. from pygame.locals import *
  4. import 金币
  5. import 蛇身
  6. pygame.init()
  7. size = width, height = 600, 400
  8. bg = (255, 255, 255)
  9. YELLOW = (255, 255, 0)
  10. snake = (0, 255, 0)
  11. BLACK = (0, 0, 0)
  12. fanxiang = 'right'
  13. left = 300
  14. top = 200
  15. screen = pygame.display.set_mode(size)
  16. pygame.display.set_caption('贪吃蛇')
  17. move = USEREVENT
  18. pygame.time.set_timer(move, 1 * 100)
  19. money = USEREVENT + 1
  20. pygame.time.set_timer(money, 5 * 1000)
  21. score = 0
  22. score_font = pygame.font.Font(None, 20)
  23. Money = pygame.sprite.Group()
  24. snakebody = pygame.sprite.Group()
  25. positions = []
  26. while True:
  27.     for event in pygame.event.get():
  28.         if event.type == pygame.QUIT:
  29.             sys.exit()
  30.         elif event.type == move:
  31.             if fanxiang == 'left':
  32.                 left -= 11
  33.             elif fanxiang == 'top':
  34.                 top -= 11
  35.             elif fanxiang == 'right':
  36.                 left += 11
  37.             elif fanxiang == 'bottom':
  38.                 top += 11
  39.             positions.insert(0, (left, top))
  40.             positions.pop()
  41.         elif event.type == money:
  42.             m = 金币.money()
  43.             Money.add(m)
  44.             if snakebody:
  45.                 last_number = list(snakebody)[-1].number
  46.             else:
  47.                 last_number = 0
  48.             number = last_number + 1
  49.             s = 蛇身.body(int(positions[number-1][0]), int(positions[number-1][1]), number)
  50.             snakebody.add(s)
  51.     key_pressed = pygame.key.get_pressed()
  52.     if key_pressed[K_UP]:
  53.         fanxiang = 'top'
  54.     elif key_pressed[K_DOWN]:
  55.         fanxiang = 'bottom'
  56.     elif key_pressed[K_RIGHT]:
  57.         fanxiang = 'right'
  58.     elif key_pressed[K_LEFT]:
  59.         fanxiang = 'left'
  60.     screen.fill(bg)
  61.     for b in snakebody:
  62.         b.rect = pygame.Rect(positions[b.number-1][0], positions[b.number-1][1], 10, 10)
  63.         pygame.draw.rect(screen, snake, b.rect, 0)
  64.     for i in Money:
  65.         pygame.draw.rect(screen, YELLOW, i.rect, 0)
  66.         if i.rect.colliderect(pygame.Rect(left, top, 10, 10)):
  67.             score += 1000
  68.             thousand = score // 1000
  69.             s = 蛇身.body(int(positions[thousand-1][0]), int(positions[thousand-1][1]), thousand)
  70.             snakebody.add(s)
  71.             Money.remove(i)
  72.     pygame.draw.rect(screen, snake, (left, top, 10, 10), 0)
  73.     score_text = score_font.render(f'Score:{score}', True, BLACK)
  74.     screen.blit(score_text, (10, 5))
  75.     pygame.display.flip()
复制代码

请注意,上述代码仅解决了蛇身体不完全加长的问题。其他功能和逻辑你需要自己实现。
以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-24 08:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表