3
\$\begingroup\$

This is my first ever try at making reusable code. The function makes use of two images to give the illusion of turning on and turning off a button in pygame.

I would like to know what would you do differently and if I did a good job? Thanks everyone.

Also, this is assuming you already loaded your images and gave it a name using pygame.image.load() function in pygame.

"""
 The function `mouse_on_button() takes all the arguments needed 
to produce a light-able button. For example, you have an image 
of a thumbs up in grey and another image of a thumbs up in bright red and stack the on top of each other. 
They are called by clicking the position of the image. By clicking they dark image will get transformed into the lit up image and vice-versa.
thumbs_up_img = pygame.image.load('thumbsup.png')
thumbs_up_lit_up_img = pygame.image.load('thumbsupred.png')
thumbs_up = Buttons(60, 240, 50, 50) # X, Y, Width, Height
mouse_on_button(pygame, screen, thumbs_up_img, thumbs_up_lit_up_img,thumbs_up.btn_x, thumbs_up.btn_y, thumbs_up.width, thumbs_up.height, SCREEN_HEIGHT, SCREEN_WIDTH)
"""
class Buttons:
 """
 This class takes the x-position and the y-position, width and height of an image.
 """
 def __init__(self, btn_x, btn_y, width, height):
 self.btn_x = btn_x
 self.btn_y = btn_y
 self.width = width
 self.height = height
def mouse_on_button(pygame, screen, off_btn, on_btn, btn_x, btn_y, width, height, SCREEN_HEIGHT, SCREEN_WIDTH):
 """
 This function takes a dark image and a bright image to give the illusion of turning on a button.
 """
 # Get mouse position.
 mouse = pygame.mouse.get_pos()
 # Setting up the boundries to light up or turn off around the button.
 if (mouse[0] >= btn_x and mouse[0] <= btn_x + width) and (mouse[1] >= btn_y and mouse[1] <= btn_y + height):
 # This will return the ON value of an image in the screen.
 return screen.blit(on_btn,(btn_x, btn_y, SCREEN_HEIGHT, SCREEN_WIDTH))
 else:
 # This will return the OFF value of an image in the screen.
 return screen.blit(off_btn,(btn_x, btn_y, SCREEN_HEIGHT, SCREEN_WIDTH))
asked Oct 16, 2019 at 16:55
\$\endgroup\$
4
  • \$\begingroup\$ please post some context, usages/calling your mouse_on_button function \$\endgroup\$ Commented Oct 16, 2019 at 18:33
  • \$\begingroup\$ Added a comment describing the func through an example. \$\endgroup\$ Commented Oct 16, 2019 at 20:03
  • \$\begingroup\$ Are DISPLAY_HEIGHT and DISPLAY_WIDTH global constant values? \$\endgroup\$ Commented Oct 16, 2019 at 20:38
  • \$\begingroup\$ Yes, they describe the window size of the program. For example, 600px x 600px without the PX of course. I will take notes about all the missing info so it won't happen again. Edit: I should've said screen size for better readability. I will change it. \$\endgroup\$ Commented Oct 16, 2019 at 21:06

1 Answer 1

1
\$\begingroup\$

I think your button class should do more. It should know if a point is within it's boundaries or not and what its image(s) is (are). It should probably also have an update method that can optionally be called with the mouse position. I would also rename it to singular Button, since each instance of the class is a single button and not a collection of buttons.

class Button:
 """
 This class takes the x-position and the y-position, width and height of an image.
 """
 def __init__(self, x, y, width, height, image, hover_image=None):
 self.x = x
 self.y = y
 self.width = width
 self.height = height
 self.image = on_image
 self.hover_image = hover_image
def point_inside(self, pos=None):
 if pos is None:
 return False
 return (self.x <= pos[0] <= self.x + self.width \
 and self.y <= pos[1] <= self.y + self.height)
def update(self, screen, mouse_pos=None):
 if self.hover_image is not None and self.point_inside(mouse_pos):
 screen.blit(self.hover_image, (self.x, self.y, SCREEN_HEIGHT, SCREEN_WIDTH))
 else:
 screen.blit(self.image, (self.x, self.y, SCREEN_HEIGHT, SCREEN_WIDTH))
if __name__ == "__main__":
 thumbs_up_img = pygame.image.load('thumbsup.png')
 thumbs_up_lit_up_img = pygame.image.load('thumbsupred.png')
 thumbs_up = Button(60, 240, 50, 50, thumbs_up_img, thumbs_up_lit_up_img)
 # some pygame setup
 ...
 while True:
 mouse = pygame.mouse.get_pos()
 button.update(screen, mouse)
 pygame.display.flip()

This is a bit more generic, in that it allows a button not to have a hover image and it has an update method, which is quite common for objects in pygame. You could think about off-loading the point in button boundary check to a Rectangle class, which might help since you will probably encounter rectangles and checking if a point is inside quite often in pygame.

And would you look at that, there is already pygame.Rect, from which you could inherit. It even has the pygame.Rect.collidepoint method to check if a point is inside it.

class Button(pygame.Rect):
 """
 This class takes the x-position and the y-position, width and height of an image.
 """
 def __init__(self, x, y, width, height, image, hover_image=None):
 super().__init__(x, y, width, height)
 self.image = on_image
 self.hover_image = hover_image
def update(self, screen, mouse_pos=None):
 if self.hover_image is not None \
 and mouse_pos is not None \
 and self.collidepoint(mouse_pos):
 screen.blit(self.hover_image, (self.x, self.y, SCREEN_HEIGHT, SCREEN_WIDTH))
 else:
 screen.blit(self.image, (self.x, self.y, SCREEN_HEIGHT, SCREEN_WIDTH))
answered Oct 17, 2019 at 13:18
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.