鱼C论坛

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

[已解决]pygame贪吃蛇问题

[复制链接]
发表于 2023-12-1 19:01:27 | 显示全部楼层 |阅读模式
1鱼币
#贪吃蛇.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[0] = [left, top]
                    left -= 11
                    for b in snakebody:
                        Sbody[int(b.number)] = [b.width, b.height]
                    
                    
                elif fanxiang == 'top':
                    Sbody[0] = [left, top]
                    top -= 11
                    for b in snakebody:
                        Sbody[int(b.number)] = [b.width, b.height]
                    
                    
                elif fanxiang == 'right':
                    Sbody[0] = [left, top]
                    left += 11
                    for b in snakebody:
                        Sbody[int(b.number)] = [b.width, b.height]
                    
                    
                elif fanxiang == 'bottom':
                    Sbody[0] = [left, top]
                    top += 11
                    for b in snakebody:
                        Sbody[int(b.number)] = [b.width, b.height]
                    
                    
            
            #生成金币
            elif event.type == money:
                print(left, top)
                m = 金币.money()
                Money.add(m)
        
        key_pressed = pygame.key.get_pressed()
        
        #控制方向
        if key_pressed[K_w] or key_pressed[K_UP]:
            fanxiang = 'top'
        elif key_pressed[K_s] or key_pressed[K_DOWN]:
            fanxiang = 'bottom'
        elif key_pressed[K_d] or key_pressed[K_RIGHT]:
            fanxiang = 'right'
        elif key_pressed[K_a] or key_pressed[K_LEFT]:
            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[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)
            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[last][0]), int(Sbody[last][1]), 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[0]
        self.top = bg_size[1]
我在测试失败界面时游戏忽然就卡了,麻烦各位帮忙看看是怎么回事,谢谢
最佳答案
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()

最佳答案

查看完整内容

Game Over 的时候还在 While True 循环里没有跳出来导致的。 加个 break 跳出循环即可:
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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()

点评

我很赞同!: 5.0
我很赞同!: 5
  发表于 2023-12-2 22:57
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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()[last].rect.left   s.rect.top = snakebody.sprites()[last].rect.top
   这样每次生成新的蛇身时,它的位置会和上一个蛇身的位置相同。

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

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

你回答的问题不太对,请仔细阅读代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-1 19:47:38 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

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[pygame.K_UP]:    fanxiang = 'top'elif key_pressed[pygame.K_DOWN]:    fanxiang = 'bottom'elif key_pressed[pygame.K_RIGHT]:    fanxiang = 'right'elif key_pressed[pygame.K_LEFT]:    fanxiang = 'left'
3. 在生成金币的部分,你调用了 `print(left, top)`,这会在 console 中输出坐标值。如果输出过于频繁,可能导致游戏卡顿,建议注释掉或删除该行代码。

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

以上回复来自 -- ChatGPT(FishC官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-12-1 19:48:12 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

很抱歉之前回答中的错误,以下是我对您提供的代码进行修改后的版本,修复了可能导致游戏卡死的问题:
import pygameimport sysfrom pygame.locals import *import randompygame.init()pygame.mixer.init()size = width, height = 600, 400bg = (0, 0, 255)YELLOW = (255, 255, 0)snake_color = (0, 255, 0)white = (255, 255, 255)fanxiang = 'right'left = 300top = 200pygame.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 = USEREVENTmoney = USEREVENT + 1pygame.time.set_timer(move, 100)  # 每100毫秒触发一次移动事件pygame.time.set_timer(money, 5000)  # 每5000毫秒触发一次生成金币事件score = 0score_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 = Trueclock = 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[pygame.K_UP]:        fanxiang = 'top'    elif key_pressed[pygame.K_DOWN]:        fanxiang = 'bottom'    elif key_pressed[pygame.K_RIGHT]:        fanxiang = 'right'    elif key_pressed[pygame.K_LEFT]:        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()[0])    # 检测是否吃到金币    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官方接口),如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

帮你@一些人罢,最近我可能没空@python爱好者. @歌者文明清理员 @sfqxx_小
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-12-1 22:54:20 | 显示全部楼层
我想知道 金币.py 蛇身.py 的代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

我一般小号不在线,请@大号
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

OK
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-11 10:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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