鱼C论坛

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

[已解决]pygame贪吃蛇问题

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

while running:
    if e:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                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('不能碰到身体或边缘!!!')
            e = False
            #GameOver = True
            

        screen.fill(bg)
        #蛇身机制
        for b in snakebody:
            lastnumber = b.number - 1
            nextnumber = b.number + 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('不能碰到身体或边缘!!!')
                e = 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 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)
#蛇身.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]
#金币.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)
我在测试失败界面时游戏突然卡了,麻烦各位看看是怎么回事,谢谢
最佳答案
2023-12-1 20:08:04
在下面这一段代码中,你没有处理退出命令:
 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()

最佳答案

查看完整内容

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

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2023-12-1 20:08:04 | 显示全部楼层    本楼为最佳答案   
在下面这一段代码中,你没有处理退出命令:
 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 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. 可以考虑使用更加模块化的方式组织代码,将不同的功能(例如贪吃蛇、金币等)封装成不同的类和模块,便于管理和维护。

以下是对代码进行了一些修改和优化的示例:
# 贪吃蛇.pyimport sysimport pygamefrom pygame.locals import *import randomimport time# 定义颜色值bg = (0, 0, 255)YELLOW = (255, 255, 0)snake_color = (0, 255, 0)white = (255, 255, 255)# 初始化pygamepygame.init()size = width, height = 600, 400screen = pygame.display.set_mode(size)pygame.display.set_caption('贪吃蛇')# 加载音效pygame.mixer.init()pygame.mixer.music.load('game_music.ogg')pygame.mixer.music.set_volume(1)eat_sound = pygame.mixer.Sound('upgrade.wav')# 设置定时器事件move_event = USEREVENTmoney_event = USEREVENT + 1pygame.time.set_timer(move_event, 100)  # 设置移动事件间隔为100毫秒pygame.time.set_timer(money_event, 5000)  # 设置生成金币事件间隔为5秒# 创建字体对象score_font = pygame.font.Font(None, 20)game_over_font = pygame.font.Font(None, 100)# 定义游戏状态GAME_RUNNING = 0GAME_OVER = 1class SnakeBodyPart(pygame.sprite.Sprite):    def __init__(self, x, y):        pygame.sprite.Sprite.__init__(self)        self.rect = pygame.Rect(x, y, 10, 10)class Money(pygame.sprite.Sprite):    def __init__(self):        pygame.sprite.Sprite.__init__(self)        self.rect = pygame.Rect(random.randint(0, width - 10), random.randint(0, height - 10), 10, 10)def game_over():    screen.fill(bg)    game_over_text = game_over_font.render('Game Over', True, white)    screen.blit(game_over_text, (100, 100))    pygame.display.flip()    time.sleep(1)    returndef main():    pygame.mixer.music.play(-1)  # 无限循环播放背景音乐    snake_body_parts = []    direction = 'right'    score = 0    game_state = GAME_RUNNING    while True:        for event in pygame.event.get():            if event.type == QUIT:                pygame.quit()                sys.exit()            elif event.type == move_event:                if game_state == GAME_RUNNING:                    if direction == 'left':                        head_x = snake_body_parts[0].rect.x - 11                        head_y = snake_body_parts[0].rect.y                    elif direction == 'top':                        head_x = snake_body_parts[0].rect.x                        head_y = snake_body_parts[0].rect.y - 11                    elif direction == 'right':                        head_x = snake_body_parts[0].rect.x + 11                        head_y = snake_body_parts[0].rect.y                    elif direction == 'bottom':                        head_x = snake_body_parts[0].rect.x                        head_y = snake_body_parts[0].rect.y + 11                    new_body_part = SnakeBodyPart(head_x, head_y)                    snake_body_parts.insert(0, new_body_part)                    if len(snake_body_parts) > 1:                        snake_body_parts[-1].rect.x = snake_body_parts[-2].rect.x                        snake_body_parts[-1].rect.y = snake_body_parts[-2].rect.y                    # 移动后判断是否撞到自身或边界                    if head_x < 0 or head_x >= width or head_y < 0 or head_y >= height:                        game_state = GAME_OVER                    for body_part in snake_body_parts[1:]:                        if body_part.rect.colliderect(new_body_part.rect):                            game_state = GAME_OVER                    # 判断是否吃到金币                    for money in money_group:                        if new_body_part.rect.colliderect(money.rect):                            score += 1000                            eat_sound.play()                            money.kill()            elif event.type == money_event:                if game_state == GAME_RUNNING:                    new_money = Money()                    money_group.add(new_money)        key_pressed = pygame.key.get_pressed()        if key_pressed[K_LEFT] and direction != 'right':            direction = 'left'        elif key_pressed[K_UP] and direction != 'bottom':            direction = 'top'        elif key_pressed[K_RIGHT] and direction != 'left':            direction = 'right'        elif key_pressed[K_DOWN] and direction != 'top':            direction = 'bottom'        if game_state == GAME_RUNNING:            screen.fill(bg)            score_text = score_font.render(f'Score: {score}', True, white)            screen.blit(score_text, (10, 5))            for body_part in snake_body_parts:                pygame.draw.rect(screen, snake_color, body_part.rect)            for money in money_group:                pygame.draw.rect(screen, YELLOW, money.rect)            pygame.display.flip()        else:            game_over()        clock.tick(10)if __name__ == '__main__':    clock = pygame.time.Clock()    money_group = pygame.sprite.Group()    main()
上述代码对你的原始代码进行了修改和优化,增加了游戏状态的判断,使得游戏结束后可以显示"Game Over"并停留一段时间。另外,将生成金币和绘制游戏界面的部分进行了拆分,并使用了精灵组来管理金币。同时,在每次移动后判断是否撞到自身或边界,并增加了吃到金币的逻辑。希望以上修改能够解决你遇到的问题。

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-21 17:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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