You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何限制Pygame点击器游戏中按钮的长按重复触发?

Fixing the Long-Press Continuous Count Issue in Your Pygame Clicker Game

Hey there! The problem you're running into is that your current code checks every frame if the mouse is held down over the button. Since pygame.mouse.get_pressed() returns True for every frame the button is held, your money variable increments nonstop during a long press. Let's fix this with two straightforward solutions:

This is the cleanest approach because Pygame's event system is designed for one-time user interactions like a single click. Instead of checking the mouse state every frame, we'll listen for the exact moment the left mouse button is pressed.

Here's the revised code with this approach:

import pygame, sys
from pygame.locals import *
pygame.init()
light_gray=(211,211,211)
black=(0,0,0)
white=(255,255,255)

def terminate():
    pygame.quit()
    sys.exit()

def drawText(text, font, screen, x, y, color):
    textobj = font.render(text, True, color)
    textrect = textobj.get_rect(center=(x,y))
    screen.blit(textobj, textrect)

class Button(object):
    def __init__(self, x, y, width, height, color):
        self.rect = pygame.Rect(x, y, width, height)  # Using pygame.Rect makes collision checks easier
        self.color = color
    
    def is_clicked(self, mouse_pos):
        # Check if the mouse position is inside the button's rectangle
        return self.rect.collidepoint(mouse_pos)

clock = pygame.time.Clock()
font = pygame.font.SysFont(None, 50)
screen_width = 1300
screen_height = 700
screen = pygame.display.set_mode([screen_width, screen_height])
pygame.display.set_caption('Clicker')
done = False
money = 0
button = Button(25, screen_height-125, 500, 100, light_gray)

while not done:
    for event in pygame.event.get():
        if event.type == QUIT:
            terminate()
        # Listen for left mouse button press events
        if event.type == MOUSEBUTTONDOWN and event.button == 1:
            if button.is_clicked(event.pos):
                money += 1

    screen.fill(light_gray)
    pygame.draw.rect(screen, button.color, button.rect)
    pygame.draw.rect(screen, black, button.rect, 3)
    drawText('Click!', font, screen, button.rect.centerx, button.rect.centery, black)
    drawText(f'${money}', font, screen, screen_width/2, 25, black)
    pygame.display.flip()
    clock.tick(15)
pygame.quit()

Solution 2: Add a Press State Flag (Minimal Changes)

If you want to keep most of your original code structure, you can add a flag to track whether the button was already pressed in the last frame. This way, we only count the first frame of the press, not every frame during a long hold.

Modified Button class:

class Button(object):
    def __init__(self, x, y, width, height, color):
        self.rect=(x,y,width,height)
        self.image=pygame.draw.rect(screen, color,(self.rect),)
        self.x=x
        self.y=y
        self.width=width
        self.height=height
        self.was_pressed = False  # Tracks if the button was held last frame

    def check(self):
        mouse = pygame.mouse.get_pos()
        current_pressed = pygame.mouse.get_pressed()[0]
        in_bounds = self.x + self.width > mouse[0] > self.x and self.y + self.height > mouse[1] > self.y
        
        # Only return True if we just pressed the button (not holding it)
        if in_bounds and current_pressed and not self.was_pressed:
            self.was_pressed = True
            return True
        # Reset the flag when the mouse is released
        if not current_pressed:
            self.was_pressed = False
        return False

Keep your main loop the same—this change will make each click only increment money once, even if you hold the mouse down.

Why These Work:

  • Solution 1 uses Pygame's built-in event system, which fires exactly once when the mouse is clicked, so we don't have to worry about repeated counts.
  • Solution 2 tracks the transition from "not pressed" to "pressed", ensuring we only count the initial click, not the entire hold duration.

内容的提问来源于stack exchange,提问作者gnaw

火山引擎 最新活动