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))
1 Answer 1
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))
mouse_on_button
function \$\endgroup\$DISPLAY_HEIGHT
andDISPLAY_WIDTH
global constant values? \$\endgroup\$