MY PYTHON VERSION IS 3.10
I'm trying to reference a method defined in the Button class (is_clicked()) in the Game class. The problem is the when I do it the way I'm doing it, the command prompt tells me:
if Button.is_clicked(event.pos):
TypeError: Button.is_clicked() missing 1 required positional argument: 'mouse_pos'
So I suppose that this error is the 'event.pos' argument is actually getting passed as self and not as mouse_pos. The question is that if there's a way to kind of "ignore" the self argument so that I can include the is_clicked() method as an event in my event_check() from the Game class. The thing is I'd like to reference every instance I create of the Button class but using Button.is_clicked() outside the Button class seems to not do the trick. Any help is pretty much appreciated
import pygame, sys
class Game:
def __init__(self, resolution: tuple, fps: int = 24):
pygame.init()
pygame.font.init()
self.clock = pygame.time.Clock()
self.resolution = resolution
self.screen = pygame.display.set_mode(self.resolution, pygame.RESIZABLE)
self.font = pygame.font.SysFont("Arial", 20)
self.fps = fps
def get_clock(self):
return self.clock
def get_screen(self):
return self.screen
def get_resolution(self):
return self.resolution
def get_font(self):
return self.font
def tick_screen(self):
pygame.display.flip()
self.clock.tick(self.fps)
def event_check(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
# problem here :(
if Button.is_clicked(event.pos): #REFERENCE THE BUTTON INSTANCE HERE
print("Button clicked!")
class Rect:
# Constructor
def __init__(self, x, y, width, height, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.color = color
# Draw the rectangle
def draw(self, screen):
pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))
class NarratingRect(Rect):
# Constructor
def __init__(self, x, y, width, height, color, font, text):
super().__init__(x, y, width, height, color)
self.font = font
self.text = text
# Draw the rectangle
def draw(self, screen):
super().draw(screen)
text = self.font.render(self.text, True, (0, 0, 0))
screen.blit(text, (self.x, self.y))
class Button(Rect):
# Constructor
def __init__(self, x, y, width, height, color, font, text):
super().__init__(x, y, width, height, color)
self.font = font
self.text = text
# Draw the button
def draw(self, screen):
super().draw(screen)
text = self.font.render(self.text, True, (0, 0, 0))
text_rect = text.get_rect()
text_rect.center = (self.x self.width // 2, self.y self.height // 2)
screen.blit(text, text_rect)
# Check if the button is clicked
def is_clicked(self, mouse_pos):
if self.x < mouse_pos[0] < self.x self.width and self.y < mouse_pos[1] < self.y self.height:
return True
else:
return False
CodePudding user response:
create instance to solve this issue, your methods are not static in that way.
buttonInstance = Button()
buttonInstance.is_clicked()
for more information you can check Class Methods and Static Methods
CodePudding user response:
Nevermind, I myself reached the conclusion at what I wanted to do. Here's what I did:
In the event_check() method I added a parameter as button_list, then with a for loop I check each button in the button_list list so that now it is an instance and therefore I can call the is_clicked() method.
This solution requires to register every button after its creation, as simple as making another method to append it to the button_list and that all.
if event.type == pygame.MOUSEBUTTONDOWN: if button_list is not None: for button in button_list: if button.is_clicked(event.pos): print("Button clicked!")
I dont think this is the fastest solution but i do think its a clever one.
def register_button(self, button, button_list: list = None):
if button_list is None:
print("No button list provided!")
return
button_list.append(button)