【问题标题】:Pygame buttons not workingPygame 按钮不起作用
【发布时间】:2018-10-10 06:45:30
【问题描述】:

我在我的游戏中创建了某种菜单导航系统。所有屏幕都被插入。“播放”、“退出”和“控制”按钮工作得很好,但是当我尝试从控制屏幕按下菜单时,什么也没有发生。在控制屏幕上,您可以隐约看到之前的第一个菜单屏幕。这可能是问题所在。我认为,由于返回菜单按钮位于前一个控件页面按钮之上,因此它以某种方式按下了之前的控件按钮。我的代码的按钮和菜单部分将被粘贴在这里,完整的东西将被粘贴到一个 pastebin 中。

def text_to_button(msg,color,buttonx,buttony,buttonwidth,buttonheight,size = "small"):
textSurf, textRect = text_objects(msg,color,size)
textRect.center = ((buttonx + buttonwidth/2)), buttony+(buttonheight/2)
gameDisplay.blit(textSurf, textRect)

def button(text,x,y,width,height,inactive_color,active_color,size = "small",action = None):
cur = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
#print(click)
if x + width > cur[0] > x and y + height > cur[1] > y:
    pygame.draw.rect(gameDisplay, active_color,(x,y,width,height))
    if click[0] == 1 and action != None:
        if action == "quit":
            pygame.quit()
            quit()
        if action == "controls":
            game_controls()

        if action == "play":
            gameLoop()
        if action == "main":
            game_intro()

else:
    pygame.draw.rect(gameDisplay, inactive_color,(x,y,width,height))
text_to_button(text,black,x,y,width,height,size)

def game_controls():
gcont = True
while gcont:
    gameDisplay.blit(cont,(0,0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()


    button("Play",150,500,100,50,white,gray,"small",action = "play")
    button("Main Menu",320,500,150,50,white,gray,"tiny", action = "main")
    button("Quit",550,500,100,50,white,gray,"small", action = "quit")


    pygame.display.update()
    clock.tick(15)

def game_intro():
intro = True
while intro:

    gameDisplay.blit(imggg,(0,0))

    button("Play",150,500,100,50,white,gray,"small",action = "play")
    button("ControLs",320,500,150,50,white,gray,"tiny", action = "controls")
    button("Quit",550,500,100,50,white,gray,"small", action = "quit")







    pygame.display.update()
    clock.tick(15)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
    if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_p:
            intro = False

完整代码:https://pastebin.com/jrd82gkJ

【问题讨论】:

    标签: python python-3.x pygame


    【解决方案1】:

    您将很难调试代码以实现您想要的行为,原因很简单:

    用于在提供不同功能的不同屏幕之间切换的逻辑会造成很多麻烦,如果您只运行游戏则无法直接看到。

    所以你会想:“哦……为什么按钮不起作用,按钮一定有问题”。

    您可能没有意识到这样一个事实:使用具有自己的 while 循环的函数,随着每次从一个视图切换到另一个视图,递归调用会越来越深入地进行递归调用 - 这不是 pygame 被认为是编程的方式。

    我建议您在代码中添加一些print() 命令,以在控制台输出中看到代码并没有真正按照您的预期执行,即使乍一看似乎没问题,因为它可以工作。

    然后我建议你重写你的整个代码,这样你就有一个主要的while notGameExit: 循环,并且不要在辅助函数中使用任何其他循环。如果你想在你的辅助函数中使用循环,至少不要从辅助函数调用另一个具有自己循环的函数(等等),而是使用显式的return 从它们返回以避免递归。

    如果您将主循环中的调用函数保留为 return,您的主循环将继续运行,并且根据某些开关,您可以在屏幕上显示不同的内容并对用户操作做出不同的反应。

    也许查看一个显示“动作”而不使用循环的最小工作 pygame 脚本,您将对 pygame 如何工作有更好的理解和一些深刻的“启示”,然后使用另一种方法开始完全重写您的游戏你在当前代码中使用过吗?如果您还有其他问题,请返回您已经取得的成果,但您可能不会有任何问题,因为如果代码变得更简单,自己调试会容易得多。

    import pygame
    
    pygame.init() # start PyGame (necessary because 'import pygame' doesn't start PyGame)
    winDisplay = pygame.display.set_mode((1024, 768)) # set PyGame window size to 1024x768 pixel
    
    pygame.display.set_caption("Minimal PyGame Test Script")
    # Time in pygame is measured in milliseconds (1/1000 seconds) (defined by TIMER_RESOLUTION constant):
    pygame.TIMER_RESOLUTION = 1000 # assure 1000 explicit, don't relay on default value 
    
    colorWhite = (255, 255, 255) # RGB color in Pygame format (valueRed=255, valueGreen=255, valueBlue=255)
    colorRed   = (255,   0,   0)
    colorGreen = (  0, 255,   0)
    colorBlue  = (  0,   0, 255)
    
    winDisplay.fill(colorWhite)
    pygame.display.update()
    pygame.time.wait(3000) # show the Pygame window for 3 seconds
    winDisplay.fill(colorRed)
    pygame.display.update()
    pygame.time.wait(3000) # show the Pygame window for 3 seconds
    winDisplay.fill(colorGreen)
    pygame.display.update()
    pygame.time.wait(3000) # show the Pygame window for 3 seconds
    winDisplay.fill(colorBlue)
    pygame.display.update()
    pygame.time.wait(3000) # show the Pygame window for 3 seconds
    winDisplay.fill(colorWhite)
    pygame.display.update()
    pygame.time.wait(3000) # show the Pygame window for 3 seconds
    

    【讨论】:

    • 非常感谢。我对编码还是有点陌生​​,从 2 个月前开始。我找到了为什么它没有工作。我已经让它工作了,但有时我必须按两下甚至三下按钮才能工作。我现在正在调试代码
    • 不客气。奇怪的行为来自于在按钮按下时发生的递归调用的随机时间(因此有时,两到三次,只是随机的)。它“看起来”可以正常工作,但是如果您经常切换视图,您将遇到“超出递归深度”错误(在实践中可能不会发生 - 您之前会厌倦切换视图)。
    猜你喜欢
    • 2013-11-26
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2016-04-27
    • 1970-01-01
    • 2011-12-02
    相关资源
    最近更新 更多