鱼C论坛

 找回密码
 立即注册
查看: 1940|回复: 14

[已解决]pygame贪吃蛇问题

[复制链接]
发表于 2023-12-1 19:01:27 | 显示全部楼层 |阅读模式
1鱼币
  1. #贪吃蛇.py
  2. import pygame
  3. import sys
  4. from pygame.locals import *
  5. import 金币
  6. import 蛇身
  7. pygame.init()
  8. pygame.mixer.init()
  9. size = width, height = 600, 400
  10. bg = (0, 0, 255)
  11. YELLOW = (255, 255, 0)
  12. snake = (0, 255, 0)
  13. white = (255, 255, 255)
  14. Sbody = {}
  15. fanxiang = 'right'
  16. left = 300
  17. top = 200
  18. pygame.mouse.set_visible(False)
  19. #pygame.mixer.music.load('Ximalaya-4.0.0_99B_sc100006.exe')
  20. pygame.mixer.music.load('game_music.ogg')
  21. pygame.mixer.music.set_volume(1)
  22. a = pygame.mixer.Sound('upgrade.wav')
  23. screen = pygame.display.set_mode(size)
  24. pygame.display.set_caption('贪吃蛇')
  25. move = USEREVENT
  26. money = USEREVENT + 1
  27. pygame.time.set_timer(move, 1 * 100)        
  28. pygame.time.set_timer(money, 5 * 1000)
  29. score = 0
  30. score_font = pygame.font.Font(None, 20)
  31. GameOver_font = pygame.font.Font(None, 100)
  32. Money = pygame.sprite.Group()
  33. snakebody = pygame.sprite.Group()
  34. pygame.mixer.music.play()
  35. running = True
  36. clock = pygame.time.Clock()



  37. while True:
  38.     if running:
  39.         for event in pygame.event.get():
  40.             if event.type == pygame.QUIT:
  41.                 sys.exit()
  42.             elif event.type == move:
  43.                 if fanxiang == 'left':
  44.                     Sbody[0] = [left, top]
  45.                     left -= 11
  46.                     for b in snakebody:
  47.                         Sbody[int(b.number)] = [b.width, b.height]
  48.                     
  49.                     
  50.                 elif fanxiang == 'top':
  51.                     Sbody[0] = [left, top]
  52.                     top -= 11
  53.                     for b in snakebody:
  54.                         Sbody[int(b.number)] = [b.width, b.height]
  55.                     
  56.                     
  57.                 elif fanxiang == 'right':
  58.                     Sbody[0] = [left, top]
  59.                     left += 11
  60.                     for b in snakebody:
  61.                         Sbody[int(b.number)] = [b.width, b.height]
  62.                     
  63.                     
  64.                 elif fanxiang == 'bottom':
  65.                     Sbody[0] = [left, top]
  66.                     top += 11
  67.                     for b in snakebody:
  68.                         Sbody[int(b.number)] = [b.width, b.height]
  69.                     
  70.                     
  71.             
  72.             #生成金币
  73.             elif event.type == money:
  74.                 print(left, top)
  75.                 m = 金币.money()
  76.                 Money.add(m)
  77.         
  78.         key_pressed = pygame.key.get_pressed()
  79.         
  80.         #控制方向
  81.         if key_pressed[K_w] or key_pressed[K_UP]:
  82.             fanxiang = 'top'
  83.         elif key_pressed[K_s] or key_pressed[K_DOWN]:
  84.             fanxiang = 'bottom'
  85.         elif key_pressed[K_d] or key_pressed[K_RIGHT]:
  86.             fanxiang = 'right'
  87.         elif key_pressed[K_a] or key_pressed[K_LEFT]:
  88.             fanxiang = 'left'

  89.         if left <= 0 or left >= 600 or top <= 0 or top >= 400:
  90.             pygame.mixer.music.stop()
  91.             #raise OSError('不能碰到身体或边缘!!!')
  92.             running = False
  93.             #GameOver = True
  94.             

  95.         screen.fill(bg)
  96.         #蛇身机制
  97.         for b in snakebody:
  98.             lastnumber = b.number - 1
  99.             nextnumber = b.number + 1
  100.             
  101.             #pygame.time.delay(1)
  102.             #print(Sbody)
  103.             b.width = Sbody[lastnumber][0]
  104.             b.height = Sbody[lastnumber][1]
  105.             b.rect = pygame.Rect(b.width, b.height, 10, 10)
  106.             pygame.draw.rect(screen, snake, b.rect, 0)
  107.             if b.rect.colliderect(pygame.Rect(left, top, 10, 10)):
  108.                 pygame.mixer.music.stop()
  109.                 #raise OSError('不能碰到身体或边缘!!!')
  110.                 running = False
  111.                 #GameOver = True
  112.                
  113.             
  114.         #金币机制
  115.         for i in Money:
  116.             if running:
  117.                 pygame.draw.rect(screen, YELLOW, i.rect, 0)
  118.             if i.rect.colliderect(pygame.Rect(left, top, 10, 10)):
  119.                 score+=1000
  120.                 thousand = score / 1000
  121.                 last = thousand - 1
  122.                 #增加长度
  123.                 s = 蛇身.body(int(Sbody[last][0]), int(Sbody[last][1]), thousand, size)
  124.                 snakebody.add(s)
  125.                 Money.remove(i)
  126.                 a.play()
  127.         #绘制贪吃蛇
  128.         pygame.draw.rect(screen, snake, (left, top, 10, 10), 0)
  129.            #显示字迹
  130.         score_text = score_font.render(f'Score:{score}', True, white)
  131.         screen.blit(score_text, (10, 5))
  132.         pygame.display.flip()

  133.     elif not running:
  134.         GameOver_text = GameOver_font.render('Game Over', True, white)
  135.         screen.blit(GameOver_text, (100, 100))
  136.         pygame.time.delay(1000)
  137.         pygame.display.flip()
  138.         clock.tick(10)
复制代码
  1. #金币.py
  2. import pygame
  3. import random
  4. class money(pygame.sprite.Sprite):
  5.     def __init__(self):
  6.         pygame.sprite.Sprite.__init__(self)
  7.         self.rect = pygame.Rect(random.randint(0, 590), random.randint(0, 390), 10, 10)
复制代码
  1. #蛇身.py
  2. import pygame
  3. class body(pygame.sprite.Sprite):
  4.     def __init__(self, width, height, number, bg_size):
  5.         pygame.sprite.Sprite.__init__(self)
  6.         self.width = width
  7.         self.height = height
  8.         self.rect = pygame.Rect(self.width, self.height, 10, 10)
  9.         self.number = number
  10.         self.left = bg_size[0]
  11.         self.top = bg_size[1]
复制代码

我在测试失败界面时游戏忽然就卡了,麻烦各位帮忙看看是怎么回事,谢谢
最佳答案
2023-12-1 19:01:28
Game Over 的时候还在 While True 循环里没有跳出来导致的。

加个 break 跳出循环即可:

  1. ...
  2.     elif not running:
  3.         GameOver_text = GameOver_font.render('Game Over', True, white)
  4.         screen.blit(GameOver_text, (100, 100))
  5.         pygame.time.delay(1000)
  6.         pygame.display.flip()
  7.         break

  8. pygame.quit()
  9. sys.exit()
复制代码

最佳答案

查看完整内容

Game Over 的时候还在 While True 循环里没有跳出来导致的。 加个 break 跳出循环即可:
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-1 19:01:28 | 显示全部楼层    本楼为最佳答案   
Game Over 的时候还在 While True 循环里没有跳出来导致的。

加个 break 跳出循环即可:

  1. ...
  2.     elif not running:
  3.         GameOver_text = GameOver_font.render('Game Over', True, white)
  4.         screen.blit(GameOver_text, (100, 100))
  5.         pygame.time.delay(1000)
  6.         pygame.display.flip()
  7.         break

  8. pygame.quit()
  9. sys.exit()
复制代码

点评

我很赞同!: 5.0
我很赞同!: 5
  发表于 2023-12-2 22:57
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-1 19:01:43 | 显示全部楼层
在你的代码中,有一个问题可能导致游戏卡住。在检测是否碰到边缘的部分:
  1. if left = 600 or top = 400:
  2.     pygame.mixer.music.stop()
  3.     running = False
复制代码

这里使用了赋值操作符 `=` 来判断条件,应该使用相等操作符 `==`。修改为:
  1. if left == 600 or top == 400:
  2.     pygame.mixer.music.stop()
  3.     running = False
复制代码

另外,你的代码中还存在其他一些小问题:

1. 在控制方向的部分,判断键盘按键的代码逻辑不正确。你可以使用 `pygame.KEYDOWN` 事件来获取按键按下的信息。例如:

  
  1. for event in pygame.event.get():
  2.        if event.type == pygame.KEYDOWN:
  3.            if event.key == pygame.K_UP:
  4.                fanxiang = 'top'
  5.            elif event.key == pygame.K_DOWN:
  6.                fanxiang = 'bottom'
  7.            elif event.key == pygame.K_RIGHT:
  8.                fanxiang = 'right'
  9.            elif event.key == pygame.K_LEFT:
  10.                fanxiang = 'left'
复制代码

2. 在创建蛇身长度的部分,你没有为新生成的蛇身设置正确的位置。可以添加以下代码:

  
  1. s.rect.left = snakebody.sprites()[last].rect.left
  2.    s.rect.top = snakebody.sprites()[last].rect.top
复制代码

   这样每次生成新的蛇身时,它的位置会和上一个蛇身的位置相同。

希望以上说明可以帮助你解决问题。如果还有其他疑问,请随时提问。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-1 19:13:54 | 显示全部楼层
FishC_GPT 发表于 2023-12-1 19:01
在你的代码中,有一个问题可能导致游戏卡住。在检测是否碰到边缘的部分:

你回答的问题不太对,请仔细阅读代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-1 19:14:05 | 显示全部楼层
flyps 发表于 2023-12-01 19:13
你回答的问题不太对,请仔细阅读代码

非常抱歉,我理解错了你提出的问题。经过仔细阅读代码,我发现一个可能导致游戏卡住的问题。在处理蛇身移动的部分,你在注释中使用了 `pygame.time.delay(1)`,这会导致游戏暂停了1毫秒。由于每次移动时都有这个延迟,当蛇身长度增加后,每个蛇身都会进行这个延迟操作,造成游戏卡顿。请尝试将注释中的这行代码删除,重新运行游戏。这应该可以解决游戏卡住的问题。如果还有其他疑问,请随时提问。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-1 19:47:38 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-1 19:47:52 | 显示全部楼层

非常抱歉之前的回答中可能有误导,确实没有仔细阅读你的代码。经过仔细查看你的代码,我发现以下问题可能引起游戏卡死:

1. 在处理蛇身移动的部分,你只更新了 `Sbody` 的值,但并没有更新 `Sbody` 对象的位置。你应该在更新完 `Sbody` 的值后,将其赋值给蛇身对象的 `width` 和 `height` 属性。修改如下:
  1. for b in snakebody:
  2.     b.width = Sbody  # 更新蛇身宽度
  3.     b.height = Sbody  # 更新蛇身高度
  4.     b.rect = pygame.Rect(b.width, b.height, 10, 10)  # 更新蛇身矩形位置
  5.     pygame.draw.rect(screen, snake, b.rect, 0)
复制代码

2. 在控制方向的部分,你使用了两个 `if` 语句,但是条件判断部分却是相同的,这样会导致只有最后一个 `if` 生效。你应该将条件判断放在同一个 `if-elif` 语句中,修改如下:
  1. if key_pressed[pygame.K_UP]:
  2.     fanxiang = 'top'
  3. elif key_pressed[pygame.K_DOWN]:
  4.     fanxiang = 'bottom'
  5. elif key_pressed[pygame.K_RIGHT]:
  6.     fanxiang = 'right'
  7. elif key_pressed[pygame.K_LEFT]:
  8.     fanxiang = 'left'
复制代码

3. 在生成金币的部分,你调用了 `print(left, top)`,这会在 console 中输出坐标值。如果输出过于频繁,可能导致游戏卡顿,建议注释掉或删除该行代码。

希望以上修改能够解决游戏卡住的问题。如果还有其他疑问,请随时提问。再次对之前的回答失误表示歉意。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-1 19:48:12 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-1 19:48:43 | 显示全部楼层

很抱歉之前回答中的错误,以下是我对您提供的代码进行修改后的版本,修复了可能导致游戏卡死的问题:
  1. import pygame
  2. import sys
  3. from pygame.locals import *
  4. import random
  5. pygame.init()
  6. pygame.mixer.init()
  7. size = width, height = 600, 400
  8. bg = (0, 0, 255)
  9. YELLOW = (255, 255, 0)
  10. snake_color = (0, 255, 0)
  11. white = (255, 255, 255)
  12. fanxiang = 'right'
  13. left = 300
  14. top = 200
  15. pygame.mouse.set_visible(False)
  16. pygame.mixer.music.load('game_music.ogg')
  17. pygame.mixer.music.set_volume(1)
  18. a = pygame.mixer.Sound('upgrade.wav')
  19. screen = pygame.display.set_mode(size)
  20. pygame.display.set_caption('贪吃蛇')
  21. move = USEREVENT
  22. money = USEREVENT + 1
  23. pygame.time.set_timer(move, 100)  # 每100毫秒触发一次移动事件
  24. pygame.time.set_timer(money, 5000)  # 每5000毫秒触发一次生成金币事件
  25. score = 0
  26. score_font = pygame.font.Font(None, 20)
  27. GameOver_font = pygame.font.Font(None, 100)
  28. class Money(pygame.sprite.Sprite):
  29.     def __init__(self):
  30.         pygame.sprite.Sprite.__init__(self)
  31.         self.rect = pygame.Rect(random.randint(0, 59) * 10, random.randint(0, 39) * 10, 10, 10)
  32. class SnakeBody(pygame.sprite.Sprite):
  33.     def __init__(self, x, y):
  34.         pygame.sprite.Sprite.__init__(self)
  35.         self.rect = pygame.Rect(x, y, 10, 10)
  36. snakebody = pygame.sprite.Group()
  37. MoneyGroup = pygame.sprite.Group()
  38. def game_over():
  39.     pygame.mixer.music.stop()  # 停止背景音乐
  40.     GameOver_text = GameOver_font.render('Game Over', True, white)
  41.     screen.blit(GameOver_text, (100, 100))
  42.     pygame.display.flip()
  43.     pygame.time.delay(1000)  # 延迟1秒显示游戏结束界面
  44. running = True
  45. clock = pygame.time.Clock()
  46. while running:
  47.     for event in pygame.event.get():
  48.         if event.type == pygame.QUIT:
  49.             sys.exit()
  50.         elif event.type == move:
  51.             if fanxiang == 'left':
  52.                 left -= 10
  53.             elif fanxiang == 'top':
  54.                 top -= 10
  55.             elif fanxiang == 'right':
  56.                 left += 10
  57.             elif fanxiang == 'bottom':
  58.                 top += 10
  59.             if left >= width or left < 0 or top >= height or top < 0:  # 判断是否触碰到边缘
  60.                 running = False  # 游戏结束
  61.         elif event.type == money:
  62.             m = Money()
  63.             MoneyGroup.add(m)
  64.     key_pressed = pygame.key.get_pressed()
  65.     if key_pressed[pygame.K_UP]:
  66.         fanxiang = 'top'
  67.     elif key_pressed[pygame.K_DOWN]:
  68.         fanxiang = 'bottom'
  69.     elif key_pressed[pygame.K_RIGHT]:
  70.         fanxiang = 'right'
  71.     elif key_pressed[pygame.K_LEFT]:
  72.         fanxiang = 'left'
  73.     screen.fill(bg)
  74.     # 绘制贪吃蛇身体
  75.     for b in snakebody:
  76.         pygame.draw.rect(screen, snake_color, b.rect, 0)
  77.     # 移动蛇身
  78.     new_head = SnakeBody(left, top)
  79.     snakebody.add(new_head)
  80.     if len(snakebody) > score // 1000 + 1:  # 根据得分增加蛇身的长度
  81.         snakebody.remove(snakebody.sprites()[0])
  82.     # 检测是否吃到金币
  83.     for m in MoneyGroup:
  84.         pygame.draw.rect(screen, YELLOW, m.rect, 0)
  85.         if new_head.rect.colliderect(m.rect):
  86.             score += 1000
  87.             a.play()
  88.             MoneyGroup.remove(m)
  89.             # 生成新的金币
  90.             new_money = Money()
  91.             MoneyGroup.add(new_money)
  92.     # 绘制贪吃蛇头部
  93.     pygame.draw.rect(screen, snake_color, (left, top, 10, 10), 0)
  94.     # 显示分数
  95.     score_text = score_font.render(f'Score: {score}', True, white)
  96.     screen.blit(score_text, (10, 5))
  97.     pygame.display.flip()
  98.     clock.tick(10)  # 控制游戏帧率
  99. game_over()
复制代码

请尝试使用修复后的代码,看看问题是否解决了。如果还有其他疑问,请随时提问。非常抱歉之前的回答引起的困惑。

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-1 20:14:54 | 显示全部楼层

帮你@一些人罢,最近我可能没空@python爱好者. @歌者文明清理员 @sfqxx_小
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-1 21:02:51 | 显示全部楼层
(在上个帖子里已经回答了,这里再重复一遍)
在下面这一段代码中,你没有处理退出命令:
  1. elif not e:
  2.     GameOver_text = GameOver_font.render('Game Over', True, white)
  3.     screen.blit(GameOver_text, (100, 100))
  4.     pygame.time.delay(1000)
  5.     pygame.display.flip()
  6.     clock.tick(10)
复制代码

此外,强制等待1秒钟也会引起卡顿。
解决方案如下:
  1. elif not e:
  2.     GameOver_text = GameOver_font.render('Game Over', True, white)
  3.     screen.blit(GameOver_text, (100, 100))
  4.     pygame.display.flip()
  5.     clock.tick(10)
  6.     for event in pygame.event.get():
  7.         if event.type == pygame.QUIT:
  8.             pygame.quit()
  9.             sys.exit()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-1 22:54:20 | 显示全部楼层
我想知道 金币.py 蛇身.py 的代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-10 17:58:49 | 显示全部楼层
cjjJasonchen 发表于 2023-12-1 20:14
帮你@一些人罢,最近我可能没空@python爱好者. @歌者文明清理员 @sfqxx_小

我一般小号不在线,请@大号
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-12-11 07:00:56 From FishC Mobile | 显示全部楼层
sfqxx_小 发表于 2023-12-10 17:58
我一般小号不在线,请@大号

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-24 04:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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