python - 检测鼠标悬停并在鼠标悬停时发出声音?

标签 python python-3.x pygame

所以我正在为我正在制作的程序设置一个主菜单,并且我计划每当鼠标悬停在按钮上方时都会发出蜂鸣声。 问题是,我的图像上已经有了按钮标签,所以我真的不知道如何合并它。

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()

这是我的整个代码,我不知道如何添加按钮。 我的图片:https://gyazo.com/ca251495b348ab8cd27f7328c84518e8

最佳答案

按钮标签的位置并不重要 - 您只需要它的位置和大小 (x,y,width,height) 或其 pygame.Rect 即可与鼠标位置进行比较。

Rect 具有偶函数 collidepoint检查与点的碰撞,可以是鼠标位置。

if button_rect.collidepoint(mouse_position):
    print("Mouse over button")
<小时/>

编辑:

这是我来自 GitHub 的代码 simple example with hovering button using class Button当鼠标悬停在按钮上(悬停)时,它会改变颜色。它在 Button.handle_event() 中使用 Rect.coolidepoint。也许它可以帮助你。

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()
<小时/>

编辑:仅当鼠标悬停在按钮上时播放声音

  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()

关于python - 检测鼠标悬停并在鼠标悬停时发出声音?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55671029/

相关文章:

Python 请求不适用于 https 代理

python - Pygame 和线程 : locked when accessing to globals?

python - 为什么我不断收到位置参数错误?

python - 将高分文件检索到 PyInstaller 创建的 .exe

python - 我怎样才能近似 Pandas 时间序列的周期

python - 如何在 bool 值中返回最长连续出现的 "True",并将其他True替换为False?

python 装饰器代理不起作用

python - 使用 Typing.NewType 时避免 PyCharm 类型警告

python - os.makedirs 不会在 Windows 上创建文件夹

python - 递归未知深度的查询集列表