Reputation: 75
The buttons in my menu screen created with Pygame are sometimes unresponsive and require more than 1 click or holding LMB. What can I do to fix this?
def menu():
global clock
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
break
gameDisplay.fill(white)
print_to_screen("Tic Tac Toe", black, (200, 50), 50)
# button(display, color_1, color_2, rectangle, text, action):
button(gameDisplay, green, bright_green, (100, 120, 200, 60), "Start Game", game_loop)
button(gameDisplay, red, bright_red, (100, 220, 200, 60), "Quit", quit_game)
pygame.display.update()
clock.tick(15) # now changed to clock.tick(60)
def button(display, color_1, color_2, rectangle, text, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if rectangle[0] < mouse[0] < rectangle[0] + rectangle[2] and rectangle[1] < mouse[1] < rectangle[1] + rectangle[3]:
pygame.draw.rect(display, color_2, rectangle)
if click[0] == 1:
action()
else:
pygame.draw.rect(display, color_1, rectangle)
small_text = pygame.font.Font('freesansbold.ttf', 20)
text_surf, text_rect = text_objects(text, small_text, white)
text_rect.center = ((rectangle[0] + rectangle[2] / 2), rectangle[1] + rectangle[3] / 2)
gameDisplay.blit(text_surf, text_rect)
Upvotes: 3
Views: 132
Reputation: 3775
Because your event loop consumes and discards some mouse click events. You can solve problem by saving mouse click event and pass it to button function. Take a look at responsive_button
function. (Next time please share a full runnable code)
import numpy as np
import pygame
from pygame.locals import *
import time
import random
import math # trigonometry functions
# initialize pygame
pygame.init()
gameDisplay = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
# COLOR CONSTANTS
black = (0,0,0)
white = (255,255,255)
red = (200,0,0)
green = (0,200,0)
blue = (0, 0, 200)
bright_red = (255,0,0)
bright_green = (0,255,0)
def game_loop():
while True:
pass
def quit_game():
exit(0)
def menu():
global clock
while True:
gameDisplay.fill(white)
mouse_clicked = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
break
elif event.type == pygame.MOUSEBUTTONDOWN:
mouse_clicked = True
#button(gameDisplay, green, bright_green, (100, 120, 200, 60), "Start Game", game_loop)
#button(gameDisplay, red, bright_red, (100, 220, 200, 60), "Quit", quit_game)
responsive_button(gameDisplay, green, bright_green, (100, 120, 200, 60), "Start Game", mouse_clicked, game_loop)
responsive_button(gameDisplay, red, bright_red, (100, 220, 200, 60), "Quit", mouse_clicked, quit_game)
pygame.display.update()
clock.tick(15) # now changed to clock.tick(60)
def text_objects(text, font):
textSurface = font.render(text, True, black)
return textSurface, textSurface.get_rect()
def button(display, color_1, color_2, rectangle, text, action=None):
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if rectangle[0] < mouse[0] < rectangle[0] + rectangle[2] and rectangle[1] < mouse[1] < rectangle[1] + rectangle[3]:
pygame.draw.rect(display, color_2, rectangle)
if click[0] == 1:
action()
else:
pygame.draw.rect(display, color_1, rectangle)
small_text = pygame.font.Font('freesansbold.ttf', 20)
text_surf, text_rect = text_objects(text, small_text)
text_rect.center = ((rectangle[0] + rectangle[2] / 2), rectangle[1] + rectangle[3] / 2)
gameDisplay.blit(text_surf, text_rect)
def responsive_button(display, color_1, color_2, rectangle, text, mouse_clicked, action=None):
mouse = pygame.mouse.get_pos()
# determine whether button contains mouse
mouse_in_button = (rectangle[0] < mouse[0] < rectangle[0] + rectangle[2] and rectangle[1] < mouse[1] < rectangle[1] + rectangle[3])
if (mouse_in_button):
pygame.draw.rect(display, color_2, rectangle)
else:
pygame.draw.rect(display, color_1, rectangle)
# determine if clicked
if (mouse_in_button and mouse_clicked):
action()
small_text = pygame.font.Font('freesansbold.ttf', 20)
text_surf, text_rect = text_objects(text, small_text)
text_rect.center = ((rectangle[0] + rectangle[2] / 2), rectangle[1] + rectangle[3] / 2)
gameDisplay.blit(text_surf, text_rect)
menu()
Upvotes: 3