flyps 发表于 2023-12-1 19:01:27

pygame贪吃蛇问题

#贪吃蛇.py
import pygame
import sys
from pygame.locals import *
import 金币
import 蛇身
pygame.init()
pygame.mixer.init()
size = width, height = 600, 400
bg = (0, 0, 255)
YELLOW = (255, 255, 0)
snake = (0, 255, 0)
white = (255, 255, 255)
Sbody = {}
fanxiang = 'right'
left = 300
top = 200
pygame.mouse.set_visible(False)
#pygame.mixer.music.load('Ximalaya-4.0.0_99B_sc100006.exe')
pygame.mixer.music.load('game_music.ogg')
pygame.mixer.music.set_volume(1)
a = pygame.mixer.Sound('upgrade.wav')
screen = pygame.display.set_mode(size)
pygame.display.set_caption('贪吃蛇')
move = USEREVENT
money = USEREVENT + 1
pygame.time.set_timer(move, 1 * 100)      
pygame.time.set_timer(money, 5 * 1000)
score = 0
score_font = pygame.font.Font(None, 20)
GameOver_font = pygame.font.Font(None, 100)
Money = pygame.sprite.Group()
snakebody = pygame.sprite.Group()
pygame.mixer.music.play()
running = True
clock = pygame.time.Clock()



while True:
    if running:
      for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == move:
                if fanxiang == 'left':
                  Sbody =
                  left -= 11
                  for b in snakebody:
                        Sbody =
                  
                  
                elif fanxiang == 'top':
                  Sbody =
                  top -= 11
                  for b in snakebody:
                        Sbody =
                  
                  
                elif fanxiang == 'right':
                  Sbody =
                  left += 11
                  for b in snakebody:
                        Sbody =
                  
                  
                elif fanxiang == 'bottom':
                  Sbody =
                  top += 11
                  for b in snakebody:
                        Sbody =
                  
                  
            
            #生成金币
            elif event.type == money:
                print(left, top)
                m = 金币.money()
                Money.add(m)
      
      key_pressed = pygame.key.get_pressed()
      
      #控制方向
      if key_pressed or key_pressed:
            fanxiang = 'top'
      elif key_pressed or key_pressed:
            fanxiang = 'bottom'
      elif key_pressed or key_pressed:
            fanxiang = 'right'
      elif key_pressed or key_pressed:
            fanxiang = 'left'

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

      screen.fill(bg)
      #蛇身机制
      for b in snakebody:
            lastnumber = b.number - 1
            nextnumber = b.number + 1
            
            #pygame.time.delay(1)
            #print(Sbody)
            b.width = Sbody
            b.height = Sbody
            b.rect = pygame.Rect(b.width, b.height, 10, 10)
            pygame.draw.rect(screen, snake, b.rect, 0)
            if b.rect.colliderect(pygame.Rect(left, top, 10, 10)):
                pygame.mixer.music.stop()
                #raise OSError('不能碰到身体或边缘!!!')
                running = False
                #GameOver = True
               
            
      #金币机制
      for i in Money:
            if running:
                pygame.draw.rect(screen, YELLOW, i.rect, 0)
            if i.rect.colliderect(pygame.Rect(left, top, 10, 10)):
                score+=1000
                thousand = score / 1000
                last = thousand - 1
                #增加长度
                s = 蛇身.body(int(Sbody), int(Sbody), thousand, size)
                snakebody.add(s)
                Money.remove(i)
                a.play()
      #绘制贪吃蛇
      pygame.draw.rect(screen, snake, (left, top, 10, 10), 0)
         #显示字迹
      score_text = score_font.render(f'Score:{score}', True, white)
      screen.blit(score_text, (10, 5))
      pygame.display.flip()

    elif not running:
      GameOver_text = GameOver_font.render('Game Over', True, white)
      screen.blit(GameOver_text, (100, 100))
      pygame.time.delay(1000)
      pygame.display.flip()
      clock.tick(10)
#金币.py
import pygame
import random
class money(pygame.sprite.Sprite):
    def __init__(self):
      pygame.sprite.Sprite.__init__(self)
      self.rect = pygame.Rect(random.randint(0, 590), random.randint(0, 390), 10, 10)
#蛇身.py
import pygame
class body(pygame.sprite.Sprite):
    def __init__(self, width, height, number, bg_size):
      pygame.sprite.Sprite.__init__(self)
      self.width = width
      self.height = height
      self.rect = pygame.Rect(self.width, self.height, 10, 10)
      self.number = number
      self.left = bg_size
      self.top = bg_size
我在测试失败界面时游戏忽然就卡了,麻烦各位帮忙看看是怎么回事,谢谢

小甲鱼 发表于 2023-12-1 19:01:28

Game Over 的时候还在 While True 循环里没有跳出来导致的。

加个 break 跳出循环即可:

...
    elif not running:
      GameOver_text = GameOver_font.render('Game Over', True, white)
      screen.blit(GameOver_text, (100, 100))
      pygame.time.delay(1000)
      pygame.display.flip()
      break

pygame.quit()
sys.exit()

FishC_GPT 发表于 2023-12-1 19:01:43

在你的代码中,有一个问题可能导致游戏卡住。在检测是否碰到边缘的部分:

if left = 600 or top = 400:
    pygame.mixer.music.stop()
    running = False

这里使用了赋值操作符 `=` 来判断条件,应该使用相等操作符 `==`。修改为:

if left == 600 or top == 400:
    pygame.mixer.music.stop()
    running = False

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

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

   for event in pygame.event.get():
       if event.type == pygame.KEYDOWN:
         if event.key == pygame.K_UP:
               fanxiang = 'top'
         elif event.key == pygame.K_DOWN:
               fanxiang = 'bottom'
         elif event.key == pygame.K_RIGHT:
               fanxiang = 'right'
         elif event.key == pygame.K_LEFT:
               fanxiang = 'left'

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

   s.rect.left = snakebody.sprites().rect.left
   s.rect.top = snakebody.sprites().rect.top

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

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

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。

flyps 发表于 2023-12-1 19:13:54

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



你回答的问题不太对,请仔细阅读代码

FishC_GPT 发表于 2023-12-1 19:14:05

flyps 发表于 2023-12-01 19:13
你回答的问题不太对,请仔细阅读代码

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

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。

flyps 发表于 2023-12-1 19:47:38

@isdkz

FishC_GPT 发表于 2023-12-1 19:47:52

flyps 发表于 2023-12-01 19:47
@isdkz

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

1. 在处理蛇身移动的部分,你只更新了 `Sbody` 的值,但并没有更新 `Sbody` 对象的位置。你应该在更新完 `Sbody` 的值后,将其赋值给蛇身对象的 `width` 和 `height` 属性。修改如下:

for b in snakebody:
    b.width = Sbody# 更新蛇身宽度
    b.height = Sbody# 更新蛇身高度
    b.rect = pygame.Rect(b.width, b.height, 10, 10)# 更新蛇身矩形位置
    pygame.draw.rect(screen, snake, b.rect, 0)

2. 在控制方向的部分,你使用了两个 `if` 语句,但是条件判断部分却是相同的,这样会导致只有最后一个 `if` 生效。你应该将条件判断放在同一个 `if-elif` 语句中,修改如下:

if key_pressed:
    fanxiang = 'top'
elif key_pressed:
    fanxiang = 'bottom'
elif key_pressed:
    fanxiang = 'right'
elif key_pressed:
    fanxiang = 'left'

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

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

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。

flyps 发表于 2023-12-1 19:48:12

@cjjJasonchen

FishC_GPT 发表于 2023-12-1 19:48:43

flyps 发表于 2023-12-01 19:48
@cjjJasonchen

很抱歉之前回答中的错误,以下是我对您提供的代码进行修改后的版本,修复了可能导致游戏卡死的问题:

import pygame
import sys
from pygame.locals import *
import random

pygame.init()
pygame.mixer.init()

size = width, height = 600, 400
bg = (0, 0, 255)
YELLOW = (255, 255, 0)
snake_color = (0, 255, 0)
white = (255, 255, 255)

fanxiang = 'right'
left = 300
top = 200

pygame.mouse.set_visible(False)
pygame.mixer.music.load('game_music.ogg')
pygame.mixer.music.set_volume(1)

a = pygame.mixer.Sound('upgrade.wav')

screen = pygame.display.set_mode(size)
pygame.display.set_caption('贪吃蛇')

move = USEREVENT
money = USEREVENT + 1

pygame.time.set_timer(move, 100)# 每100毫秒触发一次移动事件
pygame.time.set_timer(money, 5000)# 每5000毫秒触发一次生成金币事件

score = 0
score_font = pygame.font.Font(None, 20)
GameOver_font = pygame.font.Font(None, 100)

class Money(pygame.sprite.Sprite):
    def __init__(self):
      pygame.sprite.Sprite.__init__(self)
      self.rect = pygame.Rect(random.randint(0, 59) * 10, random.randint(0, 39) * 10, 10, 10)

class SnakeBody(pygame.sprite.Sprite):
    def __init__(self, x, y):
      pygame.sprite.Sprite.__init__(self)
      self.rect = pygame.Rect(x, y, 10, 10)

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

def game_over():
    pygame.mixer.music.stop()# 停止背景音乐
    GameOver_text = GameOver_font.render('Game Over', True, white)
    screen.blit(GameOver_text, (100, 100))
    pygame.display.flip()
    pygame.time.delay(1000)# 延迟1秒显示游戏结束界面

running = True

clock = pygame.time.Clock()

while running:
    for event in pygame.event.get():
      if event.type == pygame.QUIT:
            sys.exit()
      elif event.type == move:
            if fanxiang == 'left':
                left -= 10
            elif fanxiang == 'top':
                top -= 10
            elif fanxiang == 'right':
                left += 10
            elif fanxiang == 'bottom':
                top += 10
            if left >= width or left < 0 or top >= height or top < 0:# 判断是否触碰到边缘
                running = False# 游戏结束

      elif event.type == money:
            m = Money()
            MoneyGroup.add(m)

    key_pressed = pygame.key.get_pressed()
    if key_pressed:
      fanxiang = 'top'
    elif key_pressed:
      fanxiang = 'bottom'
    elif key_pressed:
      fanxiang = 'right'
    elif key_pressed:
      fanxiang = 'left'

    screen.fill(bg)

    # 绘制贪吃蛇身体
    for b in snakebody:
      pygame.draw.rect(screen, snake_color, b.rect, 0)

    # 移动蛇身
    new_head = SnakeBody(left, top)
    snakebody.add(new_head)
    if len(snakebody) > score // 1000 + 1:# 根据得分增加蛇身的长度
      snakebody.remove(snakebody.sprites())

    # 检测是否吃到金币
    for m in MoneyGroup:
      pygame.draw.rect(screen, YELLOW, m.rect, 0)
      if new_head.rect.colliderect(m.rect):
            score += 1000
            a.play()
            MoneyGroup.remove(m)
            # 生成新的金币
            new_money = Money()
            MoneyGroup.add(new_money)

    # 绘制贪吃蛇头部
    pygame.draw.rect(screen, snake_color, (left, top, 10, 10), 0)

    # 显示分数
    score_text = score_font.render(f'Score: {score}', True, white)
    screen.blit(score_text, (10, 5))

    pygame.display.flip()

    clock.tick(10)# 控制游戏帧率

game_over()

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

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。

cjjJasonchen 发表于 2023-12-1 20:14:54

flyps 发表于 2023-12-1 19:48
@cjjJasonchen

帮你@一些人罢,最近我可能没空@python爱好者. @歌者文明清理员 @sfqxx_小

smallwh 发表于 2023-12-1 21:02:51

(在上个帖子里已经回答了,这里再重复一遍)
在下面这一段代码中,你没有处理退出命令:
elif not e:
    GameOver_text = GameOver_font.render('Game Over', True, white)
    screen.blit(GameOver_text, (100, 100))
    pygame.time.delay(1000)
    pygame.display.flip()
    clock.tick(10)
此外,强制等待1秒钟也会引起卡顿。
解决方案如下:
elif not e:
    GameOver_text = GameOver_font.render('Game Over', True, white)
    screen.blit(GameOver_text, (100, 100))
    pygame.display.flip()
    clock.tick(10)
    for event in pygame.event.get():
      if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

歌者文明清理员 发表于 2023-12-1 22:54:20

我想知道 金币.py 蛇身.py 的代码

sfqxx_小 发表于 2023-12-10 17:58:49

cjjJasonchen 发表于 2023-12-1 20:14
帮你@一些人罢,最近我可能没空@python爱好者. @歌者文明清理员 @sfqxx_小

我一般小号不在线,请@大号

cjjJasonchen 发表于 2023-12-11 07:00:56

sfqxx_小 发表于 2023-12-10 17:58
我一般小号不在线,请@大号

OK
页: [1]
查看完整版本: pygame贪吃蛇问题