Reputation: 51
I've got a pretty simple code up right now that just moves between two menu screens once the button for each is pressed. I know that you can mask images in pygame to get pixel perfect collision but not sure how I'd go about doing it for the buttons in this code (it's just pretty annoying that you can click slightly off and have it still transfer you to the other menu). A follow-up question I had was on how I could do fade transitions between the screens - I've seen some tutorials but they've all seemed overcomplicated.
import pygame, os, time, random, sys
width, height = 1600, 900
pygame.init()
mainMenu = True
resMenu = False
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()
fps = 120
bg = pygame.image.load("assets/mainMenu.jpg").convert()
bgRes = pygame.image.load("assets/resMenu.jpg").convert()
res_button_image = pygame.transform.scale2x(
pygame.image.load("assets/changeRes.png")
).convert_alpha()
back_button_image = pygame.transform.scale2x(
pygame.image.load("assets/backToMenu.png")
).convert_alpha()
class resolutionButton:
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(
image, (int(width * scale), int(height * scale))
)
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
def draw(self, surface):
action = False
# get mouse position
pos = pygame.mouse.get_pos()
# check mouseover and clicked conditions
if self.rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
self.clicked = True
action = True
if pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
# draw button on screen
surface.blit(self.image, (self.rect.x, self.rect.y))
return action
class backtoMenuButton:
def __init__(self, x, y, image, scale):
width = image.get_width()
height = image.get_height()
self.image = pygame.transform.scale(
image, (int(width * scale), int(height * scale))
)
self.rect = self.image.get_rect()
self.rect.topleft = (x, y)
self.clicked = False
def draw(self, surface):
action = False
# get mouse position
pos = pygame.mouse.get_pos()
# check mouseover and clicked conditions
if self.rect.collidepoint(pos):
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
self.clicked = True
action = True
if pygame.mouse.get_pressed()[0] == 0:
self.clicked = False
# draw button on screen
surface.blit(self.image, (self.rect.x, self.rect.y))
return action
while True:
while mainMenu:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
start_button = resolutionButton(100, 400, res_button_image, 1)
screen.blit(bg, (0, 0))
if start_button.draw(screen):
resMenu = True
mainMenu = False
pygame.display.update()
clock.tick(fps)
while resMenu:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
back_button = backtoMenuButton(100, 700, back_button_image, 1)
screen.blit(bgRes, (0, 0))
if back_button.draw(screen):
resMenu = False
mainMenu = True
pygame.display.update()
clock.tick(fps)
Upvotes: 3
Views: 186
Reputation: 210948
To test whether the mouse is on an icon, you need to create a mask from the image (pygame.Surface
) with pygame.mask.from_surface
:
image_mask = pygame.mask.from_surface(image)
Define the bounding rectangle of the icon. e.g.:
image_rect = image.get_rect(center = (x, y)
Test whether the mouse is on the image, calculate the coordinates of the pixel on which the mouse is located (mask_x
, mask_y
) and use pygame.mask.Mask.get_at
to test whether the mask is set at this point:
mouse_pos = pygame.mouse.get_pos()
if image_rect.collidepoint(mouse_pos):
mask_x = mouse_pos[0] - image_rect.left
mask_y = mouse_pos[1] - image_rect.top
if image_mask.get_at((mask_x, mask_y)):
print("hit")
Minimal example:
import pygame
pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
image = pygame.image.load('Banana.png')
image_rect = image.get_rect(center = window.get_rect().center)
image_mask = pygame.mask.from_surface(image)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
color = (0, 0, 0)
mouse_pos = pygame.mouse.get_pos()
if image_rect.collidepoint(mouse_pos):
mask_x = mouse_pos[0] - image_rect.left
mask_y = mouse_pos[1] - image_rect.top
if image_mask.get_at((mask_x, mask_y)):
color = (255, 0, 0)
window.fill(color)
window.blit(image, image_rect)
pygame.display.flip()
clock.tick(60)
pygame.quit()
exit()
Upvotes: 1