鱼C论坛

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

[已解决]pygame贪吃蛇问题

[复制链接]
发表于 2023-12-1 20:08:03 | 显示全部楼层 |阅读模式
20鱼币
  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. e = True
  37. clock = pygame.time.Clock()

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

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

  97.         screen.fill(bg)
  98.         #蛇身机制
  99.         for b in snakebody:
  100.             lastnumber = b.number - 1
  101.             nextnumber = b.number + 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.                 e = 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 e:
  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. 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]
复制代码
  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)
复制代码

我在测试失败界面时游戏突然卡了,麻烦各位看看是怎么回事,谢谢
最佳答案
2023-12-1 20:08:04
在下面这一段代码中,你没有处理退出命令:
  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()
复制代码

最佳答案

查看完整内容

在下面这一段代码中,你没有处理退出命令: 此外,强制等待1秒钟也会引起卡顿。 解决方案如下:

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2023-12-1 20:08:04 | 显示全部楼层    本楼为最佳答案   
在下面这一段代码中,你没有处理退出命令:
  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 20:08:41 | 显示全部楼层
在你的代码中,有几个地方可能导致游戏卡死:

1. 在生成金币时,使用了`print(left, top)`语句。如果你不断生成金币并打印坐标,会导致输出过多,可能会降低程序的运行速度甚至卡死。建议删除这一行。

2. 在控制方向的部分,你使用了类似`key_pressed or key_pressed`的判断条件。这是一个逻辑错误,建议根据你的实际需要修改为合适的按键判断条件。例如,判断是否按下了上箭头可以改为`if key_pressed[K_UP]:`。

此外,你还可以进行一些代码优化和改进,包括:

1. 将所有的导入语句放在代码开头,以提高代码的可读性。

2. 在游戏结束时,可以添加一个循环来等待用户的操作,例如按下某个键重新开始游戏或退出。可以使用`pygame.key.get_pressed()`来判断按键状态,根据需要进行相应的操作。

3. 在贪吃蛇的移动中,你可以使用一个变量来存储蛇头的位置,然后根据蛇头的位置计算身体部分的位置,而不是每次都遍历整个蛇身列表来更新每个身体部分的位置。

4. 可以考虑使用更加模块化的方式组织代码,将不同的功能(例如贪吃蛇、金币等)封装成不同的类和模块,便于管理和维护。

以下是对代码进行了一些修改和优化的示例:
  1. # 贪吃蛇.py
  2. import sys
  3. import pygame
  4. from pygame.locals import *
  5. import random
  6. import time
  7. # 定义颜色值
  8. bg = (0, 0, 255)
  9. YELLOW = (255, 255, 0)
  10. snake_color = (0, 255, 0)
  11. white = (255, 255, 255)
  12. # 初始化pygame
  13. pygame.init()
  14. size = width, height = 600, 400
  15. screen = pygame.display.set_mode(size)
  16. pygame.display.set_caption('贪吃蛇')
  17. # 加载音效
  18. pygame.mixer.init()
  19. pygame.mixer.music.load('game_music.ogg')
  20. pygame.mixer.music.set_volume(1)
  21. eat_sound = pygame.mixer.Sound('upgrade.wav')
  22. # 设置定时器事件
  23. move_event = USEREVENT
  24. money_event = USEREVENT + 1
  25. pygame.time.set_timer(move_event, 100)  # 设置移动事件间隔为100毫秒
  26. pygame.time.set_timer(money_event, 5000)  # 设置生成金币事件间隔为5秒
  27. # 创建字体对象
  28. score_font = pygame.font.Font(None, 20)
  29. game_over_font = pygame.font.Font(None, 100)
  30. # 定义游戏状态
  31. GAME_RUNNING = 0
  32. GAME_OVER = 1
  33. class SnakeBodyPart(pygame.sprite.Sprite):
  34.     def __init__(self, x, y):
  35.         pygame.sprite.Sprite.__init__(self)
  36.         self.rect = pygame.Rect(x, y, 10, 10)
  37. class Money(pygame.sprite.Sprite):
  38.     def __init__(self):
  39.         pygame.sprite.Sprite.__init__(self)
  40.         self.rect = pygame.Rect(random.randint(0, width - 10), random.randint(0, height - 10), 10, 10)
  41. def game_over():
  42.     screen.fill(bg)
  43.     game_over_text = game_over_font.render('Game Over', True, white)
  44.     screen.blit(game_over_text, (100, 100))
  45.     pygame.display.flip()
  46.     time.sleep(1)
  47.     return
  48. def main():
  49.     pygame.mixer.music.play(-1)  # 无限循环播放背景音乐
  50.     snake_body_parts = []
  51.     direction = 'right'
  52.     score = 0
  53.     game_state = GAME_RUNNING
  54.     while True:
  55.         for event in pygame.event.get():
  56.             if event.type == QUIT:
  57.                 pygame.quit()
  58.                 sys.exit()
  59.             elif event.type == move_event:
  60.                 if game_state == GAME_RUNNING:
  61.                     if direction == 'left':
  62.                         head_x = snake_body_parts[0].rect.x - 11
  63.                         head_y = snake_body_parts[0].rect.y
  64.                     elif direction == 'top':
  65.                         head_x = snake_body_parts[0].rect.x
  66.                         head_y = snake_body_parts[0].rect.y - 11
  67.                     elif direction == 'right':
  68.                         head_x = snake_body_parts[0].rect.x + 11
  69.                         head_y = snake_body_parts[0].rect.y
  70.                     elif direction == 'bottom':
  71.                         head_x = snake_body_parts[0].rect.x
  72.                         head_y = snake_body_parts[0].rect.y + 11
  73.                     new_body_part = SnakeBodyPart(head_x, head_y)
  74.                     snake_body_parts.insert(0, new_body_part)
  75.                     if len(snake_body_parts) > 1:
  76.                         snake_body_parts[-1].rect.x = snake_body_parts[-2].rect.x
  77.                         snake_body_parts[-1].rect.y = snake_body_parts[-2].rect.y
  78.                     # 移动后判断是否撞到自身或边界
  79.                     if head_x < 0 or head_x >= width or head_y < 0 or head_y >= height:
  80.                         game_state = GAME_OVER
  81.                     for body_part in snake_body_parts[1:]:
  82.                         if body_part.rect.colliderect(new_body_part.rect):
  83.                             game_state = GAME_OVER
  84.                     # 判断是否吃到金币
  85.                     for money in money_group:
  86.                         if new_body_part.rect.colliderect(money.rect):
  87.                             score += 1000
  88.                             eat_sound.play()
  89.                             money.kill()
  90.             elif event.type == money_event:
  91.                 if game_state == GAME_RUNNING:
  92.                     new_money = Money()
  93.                     money_group.add(new_money)
  94.         key_pressed = pygame.key.get_pressed()
  95.         if key_pressed[K_LEFT] and direction != 'right':
  96.             direction = 'left'
  97.         elif key_pressed[K_UP] and direction != 'bottom':
  98.             direction = 'top'
  99.         elif key_pressed[K_RIGHT] and direction != 'left':
  100.             direction = 'right'
  101.         elif key_pressed[K_DOWN] and direction != 'top':
  102.             direction = 'bottom'
  103.         if game_state == GAME_RUNNING:
  104.             screen.fill(bg)
  105.             score_text = score_font.render(f'Score: {score}', True, white)
  106.             screen.blit(score_text, (10, 5))
  107.             for body_part in snake_body_parts:
  108.                 pygame.draw.rect(screen, snake_color, body_part.rect)
  109.             for money in money_group:
  110.                 pygame.draw.rect(screen, YELLOW, money.rect)
  111.             pygame.display.flip()
  112.         else:
  113.             game_over()
  114.         clock.tick(10)
  115. if __name__ == '__main__':
  116.     clock = pygame.time.Clock()
  117.     money_group = pygame.sprite.Group()
  118.     main()
复制代码

上述代码对你的原始代码进行了修改和优化,增加了游戏状态的判断,使得游戏结束后可以显示"Game Over"并停留一段时间。另外,将生成金币和绘制游戏界面的部分进行了拆分,并使用了精灵组来管理金币。同时,在每次移动后判断是否撞到自身或边界,并增加了吃到金币的逻辑。希望以上修改能够解决你遇到的问题。

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

使用道具 举报

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

本版积分规则

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

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

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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