Python pygame - 避免意外连续点击

时间:2017-12-11 11:08:07

标签: python button pygame

编辑:添加了更长的示例代码。

我在pygame中编码按钮有问题。我是pygame模块的新手,所以要温柔。

基本上,我们的目标是制作点击式游戏。玩家将获得每个游戏循环的两个选项,即"向左移动"或者"向右走"。因此,每个游戏循环中有两个按钮,它们都位于相同的坐标处。

这是功能:

import pygame
import os
import time

pygame.init()

display_width= 1280
display_height = 720

gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()

def button(msg,x, y, w, h, ic, ac, action=None): #message, x y location, width, height, inactive and active colour
    if action ==None:
        pygame.display.update()
        clock.tick(15)
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if x+w > mouse[0] > x and y+h > mouse[1] > y:
        pygame.draw.rect(gameDisplay, ac,(x,y,w,h))
        for event in pygame.event.get():
            if event.type == pygame.MOUSEBUTTONDOWN:
                pygame.display.update()
                clock.tick(15)
                if action == "left1":
                    game_loop("loop1-1.png",0,0,"left2","left2","","")
    else:
        pygame.draw.rect(gameDisplay, ic,(x,y,w,h))

    smallText = pygame.font.SysFont('timesnewroman',20)
    textSurf, textRect = text_objects(msg, smallText, silver)
    textRect.center = ( (x+(w/2)), (y+(h/2)) )
    gameDisplay.blit(textSurf, textRect)

def game_loop(pic,width,heigth,act1,act2,left,right):
    intro = True
    while intro:
        for event in pygame.event.get():
            print(event)
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()

        gameDisplay.fill(white)
        gameDisplay.blit(get_image(pic), (0, 0)) #MAIN MENU PIC

        button(left,440,450,width,heigth, dark_gray, gray, action=act1)#start nupp
        button(right,740,450,width,heigth, dark_gray, gray, action=act2)#exit nupp

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

当我不小心点击按钮时出现问题,这意味着如果我没有尽可能快地有意点击鼠标左键。一旦调用game_loop1并且如果我再点击一下,程序将在此game_loop1中再次读取第一次点击并运行下一个game_loop然后再运行下一个等等。这意味着玩家可能会意外跳过游戏循环。

有没有办法在第一次点击后延迟程序(无论多长时间)?或者也许是一种在函数中包含keyup的方法,因此它不会计算下一个游戏循环中的点击次数?

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为您的原始代码有点太复杂,无法修复它,我宁愿向您展示一些更好的方法来做您想做的事情。您需要finite-state machine才能在不同的状态/场景之间切换。您可以使用functions as scenes here找到一个简单的示例。

如果场景中的逻辑大致相同,您还可以尝试换出场景的数据,例如背景图像。每个州/场景都需要知道它可以切换到哪些新状态,因此我将数据放入字典词典中。嵌套的dicts包含场景的背景图像和连接的左右场景。当用户按下按钮/矩形时,我检查它是左按钮还是右按钮,然后切换到states字典中的相应场景(子画面)。

import pygame


pygame.init()

display_width= 1280
display_height = 720

gameDisplay = pygame.display.set_mode((display_width, display_height))
clock = pygame.time.Clock()

# Use uppercase names for constants that should never be changed.
DARK_GRAY = pygame.Color('gray13')
BACKGROUND1 = pygame.Surface((display_width, display_height))
BACKGROUND1.fill((30, 150, 90))
BACKGROUND2 = pygame.Surface((display_width, display_height))
BACKGROUND2.fill((140, 50, 0))
BACKGROUND3 = pygame.Surface((display_width, display_height))
BACKGROUND3.fill((0, 80, 170))

states = {
    'scene1': {'background': BACKGROUND1, 'left_scene': 'scene2', 'right_scene': 'scene3'},
    'scene2': {'background': BACKGROUND2, 'left_scene': 'scene1', 'right_scene': 'scene3'},
    'scene3': {'background': BACKGROUND3, 'left_scene': 'scene1', 'right_scene': 'scene2'},
    }

def game_loop():
    # The buttons are just pygame.Rects.
    left_button = pygame.Rect(440, 450, 60, 40)
    right_button = pygame.Rect(740, 450, 60, 40)
    # The current_scene is a dictionary with the relevant data.
    current_scene = states['scene1']

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            elif event.type == pygame.MOUSEBUTTONDOWN:
                # If the left button is clicked we switch to the 'left_scene'
                # in the `current_scene` dictionary.
                if left_button.collidepoint(event.pos):
                    current_scene = states[current_scene['left_scene']]
                    print(current_scene)
                # If the right button is clicked we switch to the 'right_scene'.
                elif right_button.collidepoint(event.pos):
                    current_scene = states[current_scene['right_scene']]
                    print(current_scene)

        # Blit the current background.
        gameDisplay.blit(current_scene['background'], (0, 0))
        # Always draw the button rects.
        pygame.draw.rect(gameDisplay, DARK_GRAY, left_button)
        pygame.draw.rect(gameDisplay, DARK_GRAY, right_button)
        pygame.display.update()
        clock.tick(30)  # 30 FPS feels more responsive.


game_loop()
pygame.quit()