如何在Pygame中同时检测鼠标左键和右键

时间:2017-03-16 04:40:03

标签: python python-2.7 pygame

我使用python-2.7和pygame来构建扫雷。它几乎完成了,只有一个重要的功能可以实现。当按下鼠标左键和右键时,它会扫描周围的块并做一些事情。但我无法弄清楚如何同时检测两次点击。 在pygame的网站上,有

  

注意,在X11上,一些XServer使用中间按钮模拟。当您同时单击按钮1和3时,可以发出2按钮事件。

但它对我没有用。

3 个答案:

答案 0 :(得分:3)

您可以为文档中列出的方案编写代码(按钮2鼠标在按钮1和按钮3上按下时会触发)。

left_mouse_down = False
right_mouse_down = False
while True:
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                left_mouse_down = True
                if right_mouse_down:
                    print("perform action")
                else:
                    print("action for single left click")
            if event.button == 3:
                right_mouse_down = True
                if left_mouse_down:
                    print("perform action")
                else:
                    print("action for single right click")
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                left_mouse_down = False
            if event.button == 3:
                 right_mouse_down = False

请记住,使用pygame.mouse.get_pressed()通常会非常快速地触发,这意味着在释放鼠标键之前,if语句中的任何代码都会发生几次。这是因为get_pressed()始终返回所有鼠标按钮的状态。如果要跟踪正在按下的按钮,此方法很有用。

我会将解决方案编码到pygame.event.get()中。这只会在事件发生时触发,因此只会触发一次:

left_mouse_down = False
right_mouse_down = False
left_click_frame = 0  # keeps track of how long the left button has been down
right_click_frame = 0  # keeps track of how long the right button has been down
left_right_action_once = True  # perform the combo action only once
left_action_once = True  # perform the left action only once
right_action_once = True  # perform the right action only once
max_frame = 2  # The frames to wait to see if the other mouse button is pressed (can be tinkered with)
performing_left_right_action = False  # prevents the off chance one of the single button actions running on top of the combo action
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    mouse_pressed = pygame.mouse.get_pressed()
    if mouse_pressed[0]:  # left click
        left_click_frame += 1
        left_mouse_down = True
    else:
        left_action_once = True
        left_mouse_down = False
        left_click_frame = 0

    if mouse_pressed[2]:  # right click
        right_click_frame += 1
        right_mouse_down = True
    else:
        right_action_once = True
        right_mouse_down = False
        right_click_frame = 0

    if not mouse_pressed[0] and not mouse_pressed[2]:
        left_right_action_once = True
        performing_left_right_action = False

    if left_mouse_down and right_mouse_down and abs(left_click_frame - right_click_frame) <= max_frame:
        if left_right_action_once:
            print("performing right/left action")
            left_right_action_once = False
            performing_left_right_action = True
    elif left_mouse_down and left_click_frame > max_frame and not performing_left_right_action and not right_mouse_down:
        if left_action_once:
            print("perform single left click action")
            left_action_once = False
    elif right_mouse_down and right_click_frame > max_frame and not performing_left_right_action and not left_mouse_down:
        if right_action_once:
            print("perform single right click action")
            right_action_once = False

更新 - 模拟鼠标左键三次鼠标

上述代码有效但如果您接受单个向右或向左动作也会触发的事实,但在组合(左/右)动作之前。如果这适用于您的游戏设计,请使用它。如果这是不可接受的,那么以下内容将起作用(尽管更深入一些):

{{1}}

关于这个问题的困难之处在于,一次只能发生一个事件,因此您必须知道左键单击是否被按下,而不是评估它,直到您确定也不会按下右键单击。您可以通过跟踪帧来完成此操作,如果左右发生在一定数量的帧(max_frames)内,则您可以右键/左键单击。否则你有左或右。

action_once变量很重要,因为pygame.mouse.get_pressed()每次通过游戏循环都会检查每个鼠标按钮的状态,你需要一个标志来防止你的动作在按下按钮时多次运行(即使在短暂的点击期间)。游戏循环比鼠标点击快。

因此涵盖了所有三种情况:左单,右单,左右组合。换句话说,它模拟了鼠标双击鼠标的“第三次”....虽然解决方案相当笨重

答案 1 :(得分:0)

您应该同时测试pygame.mouse.get_pressed()[0](鼠标左键)和pygame.mouse.get_pressed()[2](鼠标左键)的值。

http://www.pygame.org/docs/ref/mouse.html#pygame.mouse.get_pressed

此测试应该与pygame.event.get() for循环处于同一级别,并且不包含在此循环中。您可以测试此脚本以查看我的意思:

import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((800, 500), RESIZABLE)
running = True
while(running):
    mousebuttons = pygame.mouse.get_pressed()
    if mousebuttons[0] == 1 and mousebuttons[2] == 1:
        print("Both left and rigth mouse buttons are pressed.")
    for event in pygame.event.get():
        if event.type == QUIT:
            running = False

答案 2 :(得分:0)

如果您只想在按下两个按钮后执行一次代码,请在运行代码后将right_mouse_downleft_mouse_down设置为False

left_mouse_down = False
right_mouse_down = False
while True:
    for event in pygame.event.get():
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                left_mouse_down = True
                if right_mouse_down:
                    print("perform action")
                    right_mouse_down = False
                    left_mouse_down = True
            if event.button == 3:
                right_mouse_down = False
                if left_mouse_down:
                    print("perform action")
                    right_mouse_down = False
                    left_mouse_down = False
        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:
                left_mouse_down = False
            if event.button == 3:
                 right_mouse_down = False

现在,在删除并重新单击两个鼠标按钮之前,此代码将永远不会再运行。我建议使用pygame.mouse.get_pressed()来检查按钮的状态,以便在第一次设置标志时只需要代码发生。

done_the_thing = False
while not done: # Main game loop
    buttons = pygame.mouse.get_pressed()

    if buttons[0] and buttons[2] and not done_the_thing:
        do_the_thing() # This is just your function
        done_the_thing = True

    if not buttons[0] and not buttons[2]:
        done_the_thing = False

这将允许更大的灵活性,因此如果您想要添加更多鼠标事件,每个帧都会发生或改变您当前正在做的事情,您可以将所有这些事件保持在一起并清理。