我将如何设置此按钮,使其仅记录一次单击

时间:2019-04-09 12:13:50

标签: python pygame

我使这个按钮类根据单击哪个按钮执行不同的操作。在单击按钮的那一刻,操作将多次运行。无论如何,它只能执行一次。

def action_button(x,y,w,h,ic,ac,text, text_colour,action=None):
    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(screen, ac,(x,y,w,h))

        if click[0] == 1 and action != None:
            action()
    else:
        pygame.draw.rect(screen, ic,(x,y,w,h))

    font = pygame.font.SysFont("arial black",20)
    text = font.render(text,True,(text_colour))
    screen.blit(text,[x+w/2-(text.get_rect().w/2),y+h/2-(text.get_rect().h/2)])

1 个答案:

答案 0 :(得分:1)

问题是pygame.mouse.get_pressed(),当您按住鼠标按钮时,它始终会给True。 Button踩它多次单击,并且执行功能多次。使用event可以捕获按钮从未按下状态变为按下状态的瞬间,这只是一瞬间,因此仅执行一次功能。

但是使用事件需要大量更改。如果将所有功能移至for event循环,则它将仅运行一次操作,但也将仅绘制一次按钮-当您单击应为按钮的区域时。

简便的方法是将此功能分为两个功能

  • action_button_draw仅绘制按钮并在旧地方使用
  • action_button_click仅执行操作并将其放入for event循环

        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1: # 1 = left button, 3 = right button
                action_button_click(x, y, w, h, action)
    

    或至少

        if event.type == pygame.MOUSEBUTTONDOWN:
            action_button_click(x, y, w, h, action)
    

功能:

def action_button_click(x, y, w, h, action=None):
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()

    if x+w > mouse[0] > x and y+h > mouse[1] > y:
        if click[0] == 1 and action != None:
            action()

def action_button_draw(x, y, w, h, ic, ac, text, text_colour):
    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(screen, ac,(x,y,w,h))
    else:
        pygame.draw.rect(screen, ic,(x,y,w,h))

    font = pygame.font.SysFont("arial black",20)
    text = font.render(text,True,(text_colour))
    screen.blit(text,[x+w/2-(text.get_rect().w/2),y+h/2-(text.get_rect().h/2)])

最小工作示例:

import pygame

# --- constants ---

WIDTH = 640
HEIGHT = 480

FPS = 5

# --- functions ---

def action_button_click(x, y, w, h, action=None):
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()

    if x+w > mouse[0] > x and y+h > mouse[1] > y:
        if click[0] == 1 and action != None:
            action()

def action_button_draw(x, y, w, h, ic, ac, text, text_colour):
    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(screen, ac,(x,y,w,h))
    else:
        pygame.draw.rect(screen, ic,(x,y,w,h))

    font = pygame.font.SysFont("arial black",20)
    text = font.render(text,True,(text_colour))
    screen.blit(text,[x+w/2-(text.get_rect().w/2),y+h/2-(text.get_rect().h/2)])

def test_action():
    print("clicked")

# --- main ---

# - init -

pygame.init()

screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen_rect = screen.get_rect()

# - mainloop -

clock = pygame.time.Clock()
running = True

while running:

    # - events -

    for event in pygame.event.get():

        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                running = False

        # MOUSEBUTTONDOWN is created only once,
        # when button changes state from "not-pressed" to "pressed"
        # so it is better for this job than "pygame.mouse.get_pressed()"
        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                action_button_click(100, 100, 100, 50, test_action)

    # --- draws ----

    screen.fill([0,0,0]) # clear screen

    action_button_draw(100, 100, 100, 50, [255,0,0], [0,255,0], "Hello", [0,0,0])

    pygame.display.flip()

    # - FPS -

    clock.tick(FPS)

# - end -

pygame.quit()

这两个函数也可以放在类中并像example-class.py

中那样使用类

仅当执行的动作从该区域中删除按钮(即,它删除菜单并开始游戏)时,原始功能才有效,但是当单击后按钮仍留在同一位置或您将新按钮放置在同一位置时,原始功能会出现问题。当您从菜单转到具有相同按钮的选项时