I have created a button class in pygame and although the button itself is displaying, my text is not showing up. Also I have some conditions to change the colour when the mouse is over the button. I have achieved the desired result using hard coded values in my main function, however I want to use a class the handle my various button as I might have quite a few buttons.
Given below are some classes that I’m using
Fonts
class Fonts:
def __init__(self, font, antialias, text, color, x, y):
self.font = font
self.antialias = antialias
self.text = text
self.color = color
self.x = x
self.y = y
def draw(self, win):
win.blit(self.font.render(self.text, self.antialias, (self.color)), (self.x, self.y))
Button
class Button:
def __init__(self, color, x, y, width, height, text, fontsize):
self.color = color
self.x = x
self.y = y
self.width = width
self.height = height
self.text = text
self.fontsize = fontsize
self.courier_button_font = pygame.font.SysFont("Courier", self.fontsize)
def draw(self, pos):
x, y = pos
text_width, text_height = self.courier_button_font.size(self.text)
if self.x < x < self.width and self.y < y < self.height:
pygame.draw.rect(screen, (211, 211, 211), (self.x, self.y, self.width, self.height))
buttontext = Fonts(courier_font, True, f"{self.text}", BLACK,
int(self.width / 2 - text_width / 2), int(self.height / 2 - text_height / 2))
buttontext.draw(screen)
else:
pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))
buttontext = Fonts(courier_font, True, f"{self.text}", BLACK,
(self.width / 2 - text_width / 2), (self.height / 2 - text_height / 2))
buttontext.draw(screen)
def isOver(self, pos):
x, y = pos
if self.x < x < self.width and self.y < y < self.height:
return True
else:
pass
FireTowerButton = Button(BLACK, 810, 200, 80, 30, "Fire Tower", 20)
def ShowTowers(mouse):
mousex, mousey = mouse
screen.fill((147, 207, 14))
FireTowerButton.draw(mouse)
def main():
run = True
screen.fill(BLACK)
# screen.blit(enemy1, (90, 90))
while run:
mouse = pygame.mouse.get_pos()
ShowTowers(mouse)
screen.blit(money_image, (790, 0))
screen.blit(background_image, (0, 0))
enemy1_spawn(wave_number)
pygame.draw.rect(screen, BLACK, (770, 75, 30, 90))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
clock.tick(FPS)
pygame.display.update()
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
The condition
if self.x < x < self.width and self.y < y < self.height:
is wrong. You have to evaluate if x < self.x + self.width and y < self.y + self.height:
if self.x < x < self.x + self.width and self.y < y < self.y + self.height:
# [...]
Anyway, I recommend to pygame.Rect / collidepoint() for the collision test:
button_rect = pygame.Rect(self.x, self.y, self.width, self.height)
if button_rect.collidepoint((x, y):
# [...]
button_rect can be used further for drawing the rectangle:
pygame.draw.rect(screen, (211, 211, 211), button_rect)
The code can be simplified a lot by the use of an attribute rect rather than the separate attributes x, y, width, height:
class Button:
def __init__(self, color, x, y, width, height, text, fontsize):
self.color = color
self.rect = pygame.Rect(x, y, width, height)
self.text = text
self.fontsize = fontsize
self.courier_button_font = pygame.font.SysFont("Courier", self.fontsize)
def draw(self, pos):
button_color = (211, 211, 211) if self.rect.collidepoint(pos) else self.color
pygame.draw.rect(screen, button_color, self.rect)
text_width, text_height = self.courier_button_font.size(self.text)
textpos = (self.rect.centerx - text_width // 2, self.rect.centery - text_height // 2)
buttontext = Fonts(courier_font, True, self.text, BLACK, textpos)
buttontext.draw(screen)
def isOver(self, pos):
return self.rect.collidepoint(pos)
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0