Reputation: 387
So im setting up a main menu for the program I'm making and I was planning to have a beeping sound for whenever a mouse hovers above a button. The thing is, I have the button labels on my image already, so i don't really know how i could incorporate this.
import math, random, sys
import enum
import pygame, time
from pygame.locals import*
from sys import exit
from pygame import mixer
#initialising python
pygame.init()
#pygame.mixer.init()
pygame.mixer.pre_init(44100,16,2,4096)
mixer.init()
#define display
W, H = 1600,900
HW, HH = (W/2), (H/2)
AREA = W * H
#bsound effects
buttonsound1 = pygame.mixer.Sound("ButtonSound1.wav")
#initialising display
CLOCK = pygame.time.Clock()
DS = pygame.display.set_mode((W, H))
pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
FPS = 54
progress = 0
background = pygame.Surface(DS.get_size())
smallfont = pygame.font.SysFont("century gothic",25)
#background image
bg = pygame.image.load("Daytime.jpg").convert()
loadingimg = pygame.image.load("LoadingScreen.png").convert()
pause = pygame.image.load("Pause screen.png").convert()
gameover = pygame.image.load("Game Over.png").convert()
mainmenu = pygame.image.load("Main_Menu4.png").convert()
#mainmenu = pygame.transform.smoothscale(mainmenu, (W,H))
loadingimg = pygame.transform.smoothscale(loadingimg, (W,H))
#define some colours
BLACK = (0,0,0,255)
WHITE = (255,255,255,255)
green = (0,140,0)
grey = (180,180,180)
walkLeft = [pygame.image.load('Moving1.png'), pygame.image.load('Moving2.png'), pygame.image.load('Moving3.png'), pygame.image.load('Moving4.png'), pygame.image.load('Moving5.png'), pygame.image.load('Moving6.png'), pygame.image.load('Moving7.png'), pygame.image.load('Moving8.png'), pygame.image.load('Moving9.png')]
walkRight = []
for i in walkLeft:
walkRight.append(pygame.transform.flip(i, True, False))
char = pygame.image.load('Moving1.png').convert_alpha()
char2 = pygame.image.load('Moving1.png').convert_alpha()
char2 = pygame.transform.flip(char2, True, False)
x = 0
y = 500
height = 40
width = 87
vel = 5
isJump = False
jumpCount = 10
left = False
right = False
walkCount = 0
run = True
# FUNCTIONS
def event_handler():
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
exit()
# === CLASSES === (CamelCase names)
class Button():
def __init__(self, text, x=0, y=0, width=100, height=50, command=None):
self.text = text
self.command = command
self.image_normal = pygame.Surface((width, height))
self.image_normal.fill(green)
self.image_hovered = pygame.Surface((width, height))
#buttonsound1.play()
self.image = self.image_normal
self.rect = self.image.get_rect()
font = pygame.font.Font('freesansbold.ttf', 15)
text_image = font.render(text, True, WHITE)
text_rect = text_image.get_rect(center = self.rect.center)
self.image_normal.blit(text_image, text_rect)
self.image_hovered.blit(text_image, text_rect)
# you can't use it before `blit`
self.rect.topleft = (x, y)
self.hovered = False
#self.clicked = False
def update(self):
if self.hovered:
buttonsound1.play()
else:
self.image = self.image_normal
def draw(self, surface):
surface.blit(self.image, self.rect)
def handle_event(self, event):
if event.type == pygame.MOUSEMOTION:
self.hovered = self.rect.collidepoint(event.pos)
buttonsound1.play()
elif event.type == pygame.MOUSEBUTTONDOWN:
if self.hovered:
buttonsound1.play()
print('Clicked:', self.text)
if self.command:
self.command()
class GameState( enum.Enum ):
Loading = 0
Menu = 1
Settings = 2
Playing = 3
GameOver = 4
#set the game state initially.
game_state = GameState.Loading
#LOADING
def text_objects(text, color, size):
if size == "small":
textSurface = smallfont.render(text, True, color)
return textSurface, textSurface.get_rect()
def loading(progress):
if progress < 100:
text = smallfont.render("Loading: " + str(int(progress)) + "%", True, WHITE)
else:
text = smallfont.render("Loading: " + str(100) + "%", True, WHITE)
DS.blit(text, [50, 660])
def message_to_screen(msh, color, y_displace = 0, size = "small"):
textSurf, textRect = text_objects(msg, color, size)
textRect.center = HW, HH + y_displace
DS.blit(textSurf, textRect)
while (progress/4) < 100:
event_handler()
DS.blit(loadingimg, (0,0))
time_count = (random.randint(1,1))
increase = random.randint(1,20)
progress += increase
pygame.draw.rect(DS, green, [50, 700, 402, 29])
pygame.draw.rect(DS, grey, [50, 701, 401, 27])
if (progress/4) > 100:
pygame.draw.rect(DS, green, [50, 700, 401, 28])
else:
pygame.draw.rect(DS, green, [50, 700, progress, 28])
loading(progress/4)
pygame.display.flip()
time.sleep(time_count)
#changing to menu
game_state = GameState.Menu
Menumusic = pygame.mixer.music.load("MainMenu.mp3")
Menumusic = pygame.mixer.music.play(-1, 0.0)
def main_menu():
DS.blit(mainmenu, (0, 0))
pygame.display.update()
btn1 = Button('Hello', 812.5, 250, 100, 50)
btn2 = Button('World', 825, 325, 100, 50)
btn3 = Button('Hello', 825, 450, 100, 50)
btn4 = Button('World', 825, 575, 100, 50)
btn5 = Button('World', 825, 675, 100, 50)
btn6 = Button('Hello', 825, 790, 100, 50)
while run:
event_handler()
btn1.update()
btn2.update()
# --- draws ---
btn1.draw(DS)
btn2.draw(DS)
btn3.draw(DS)
btn4.draw(DS)
btn5.draw(DS)
btn6.draw(DS)
pygame.display.update()
main_menu()
This is my whole code and I'm not sure what to do with adding buttons. My image: https://gyazo.com/ca251495b348ab8cd27f7328c84518e8
Upvotes: 1
Views: 614
Reputation: 143197
It doesn't matter where you have button label - you need only its positon and size (x,y,width,height)
or its pygame.Rect
to compare with mouse position.
Rect
has even function collidepoint to check collision with point and it can be mouse position.
if button_rect.collidepoint(mouse_position):
print("Mouse over button")
EDIT:
It is my code from GitHub with simple example with hovering button using class Button which changes color when mouse is over button (hover). It uses Rect.coolidepoint
in Button.handle_event()
. Maybe it can help you.
import pygame
# === CONSTANTS === (UPPER_CASE names)
BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = ( 0, 255, 0)
BLUE = ( 0, 0, 255)
SCREEN_WIDTH = 600
SCREEN_HEIGHT = 400
# === CLASSES === (CamelCase names)
class Button():
def __init__(self, text, x=0, y=0, width=100, height=50, command=None):
self.text = text
self.command = command
self.image_normal = pygame.Surface((width, height))
self.image_normal.fill(GREEN)
self.image_hovered = pygame.Surface((width, height))
self.image_hovered.fill(RED)
self.image = self.image_normal
self.rect = self.image.get_rect()
font = pygame.font.Font('freesansbold.ttf', 15)
text_image = font.render(text, True, WHITE)
text_rect = text_image.get_rect(center = self.rect.center)
self.image_normal.blit(text_image, text_rect)
self.image_hovered.blit(text_image, text_rect)
# you can't use it before `blit`
self.rect.topleft = (x, y)
self.hovered = False
#self.clicked = False
def update(self):
if self.hovered:
self.image = self.image_hovered
else:
self.image = self.image_normal
def draw(self, surface):
surface.blit(self.image, self.rect)
def handle_event(self, event):
if event.type == pygame.MOUSEMOTION:
self.hovered = self.rect.collidepoint(event.pos)
elif event.type == pygame.MOUSEBUTTONDOWN:
if self.hovered:
print('Clicked:', self.text)
if self.command:
self.command()
# === FUNCTIONS === (lower_case names)
# empty
# === MAIN === (lower_case names)
def main():
# --- init ---
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
screen_rect = screen.get_rect()
clock = pygame.time.Clock()
is_running = False
btn1 = Button('Hello', 200, 50, 100, 50)
btn2 = Button('World', 200, 150, 100, 50)
# --- mainloop --- (don't change it)
is_running = True
while is_running:
# --- events ---
for event in pygame.event.get():
# --- global events ---
if event.type == pygame.QUIT:
is_running = False
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
is_running = False
# --- objects events ---
btn1.handle_event(event)
btn2.handle_event(event)
# --- updates ---
btn1.update()
btn2.update()
# --- draws ---
screen.fill(BLACK)
btn1.draw(screen)
btn2.draw(screen)
pygame.display.update()
# --- FPS ---
clock.tick(25)
# --- the end ---
pygame.quit()
#----------------------------------------------------------------------
if __name__ == '__main__':
main()
EDIT: play sound only when mouse hovers over button
if event.type == pygame.MOUSEMOTION:
previous_value = self.hovered # remeber previus value
self.hovered = self.rect.collidepoint(event.pos) # get new value
# check both values
if previous_value is False and self.hovered is True:
buttonsound1.play()
# similar play sound when mouse unhovers button
#if previous_value is True and self.hovered is False:
# unhover_sound1.play()
Upvotes: 1