简体   繁体   English

鼠标悬停在物体上时的音效?

[英]Sound effect when mouse hovers over object?

So i'm trying to set up this thing where a sound effect is made whenever the player "hovers" their mouse above a label.所以我试图设置这个东西,每当玩家将鼠标“悬停”在标签上方时就会产生声音效果。 This is the image: https://gyazo.com/ca251495b348ab8cd27f7328c84518e8这是图片: https : //gyazo.com/ca251495b348ab8cd27f7328c84518e8

I've tried looking for solutions, I have found one previously but it did not work when adding sound to it.我试过寻找解决方案,我以前找到过一个,但是在向它添加声音时它不起作用。

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

What I'm expecting is a sound effect to be made whenever the mouse goes over a label, however, the output from the program is that nothing plays or happens.我期望的是每当鼠标经过标签时都会产生声音效果,但是,程序的输出是没有任何播放或发生。

I think the issue is the processing of the events in event_handler() , which consumes all the events.我认为问题在于event_handler()中的事件处理,它消耗了所有事件。 Then the Button class handle_event() function is starved of events (also this function is never called).然后Buttonhandle_event()函数缺乏事件(这个函数也永远不会被调用)。 It's a good idea to handle events in a single place in the code, and call out from there.在代码中的一个地方处理事件并从那里调用是一个好主意。

If the OP's code did work, it looks to be constantly re-playing the sounds too.如果 OP 的代码确实有效,它看起来也在不断地重新播放声音。 The mouse-move generates a lot of events, so the triggering of playing the sound needs to only play on the initial entry into the button's rectangle.鼠标移动会产生很多事件,因此播放声音的触发只需要在按钮矩形的初始入口处播放。 Whereas the mouse movement handler is re-playing on every event inside the button's rect .而鼠标移动处理程序正在按钮的rect内的每个事件上重新播放。

Below is some example code where I took your buttons, and modified them to handle the hovering in a "edge-triggered" manner.下面是一些示例代码,我在其中使用了您的按钮,并对其进行了修改,以“边缘触发”的方式处理悬停。 This means it only triggers when the "hovered" state first becomes true, not while it's true (which would be "level-triggered")这意味着它只在“悬停”状态第一次变为真时触发,不是它为真时(这将是“水平触发”)

Note: It does not actually play the sound, as I don't have a sound-file handy.注意:它实际上并不播放声音,因为我手边没有声音文件。 It just does a print() .它只是做一个print()

import pygame

#initialising python
pygame.init()
#pygame.mixer.init()
pygame.mixer.pre_init(44100,16,2,4096)
pygame.mixer.init()

#define display
W, H = 200, 200
HW, HH = (W/2), (H/2)
AREA = W * H

#initialising display
CLOCK = pygame.time.Clock()
DS = pygame.display.set_mode((W, H))
#pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
pygame.display.set_mode((0, 0) )
FPS = 54

#define some colours
BLACK = (0,0,0,255)
WHITE = (255,255,255,255)
green = (0,140,0)
grey = (180,180,180)


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(grey)
        self.image  = self.image_normal
        self.rect   = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

        self.hovered= False  # is the mouse over this button?

    def update(self):
        pass

    def handleMouseOver( self, mouse_position ):
        """ If the given co-ordinate inside our rect,
            Do all the mouse-hovering work             """
        # Check button position against mouse
        # Change the state *once* on entry/exit
        if ( self.mouseIsOver( mouse_position ) ):
            if ( self.hovered == False ):
                self.image = self.image_hovered
                self.hovered = True   # edge-triggered, not level triggered
                # Do we want to check pygame.mixer.get_busy() ?
                if ( pygame.mixer.get_busy() == False ):
                    print( self.text + " DO buttonsound1.play() ")
        else:
            if ( self.hovered == True ):
                self.image = self.image_normal
                self.hovered = False

    def mouseIsOver( self, mouse_position ):
        """ Is the given co-ordinate inside our rect """
        return self.rect.collidepoint( mouse_position )

    def draw(self, surface):

        surface.blit(self.image, self.rect)


def main_menu():

    run = True
    btn1 = Button('Hello1',  50,  50, 40, 40)
    btn2 = Button('World2', 100,  50, 40, 40)
    btn3 = Button('Hello3',  50, 100, 40, 40)
    btn4 = Button('World4', 100, 100, 40, 40)

    # Put the buttons into a list so we can loop over them, simply
    buttons = [ btn1, btn2, btn3, btn4 ]

    while run:

        # draw the buttons
        for b in buttons:
            b.draw( DS ) # --- draws ---

        # Handle events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            if event.type == pygame.MOUSEMOTION:
                mouse_position = event.pos
                for b in buttons:
                    b.handleMouseOver( mouse_position )
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_position = event.pos
                for b in buttons:
                    if ( b.mouseIsOver( mouse_position ) ):
                        print('Clicked:', b.text)
                        #if b.command:
                        #    b.command()


        pygame.display.update()



main_menu()
pygame.quit()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 更改一个类,以便当鼠标悬停在它上面时,它会改变颜色 - Pygame - Changing a class so that when the mouse hovers over it, it changes colour - Pygame 如何在鼠标悬停在精灵上时为精灵添加边框,并在鼠标停止后将其删除? - How do I add a border to a sprite when the mouse hovers over it, and delete it after the mouse stops? 检测鼠标悬停并在鼠标悬停时发出声音? - Detecting mouseover and making a sound when the mouse is over it? 使用 QFileSystemModel 将鼠标悬停在此 QTreeView 中的项目上时如何打印文件路径 - How to print the file path when the mouse hovers over an item in this QTreeView with QFileSystemModel 当鼠标在游戏中徘徊时如何遮挡一个盒子? - How to shade a box when mouse hovers in pygame? Tkinter:如何创建一个在用户将鼠标悬停在其上时突出显示的输入框? - Tkinter: How do I create an entry box that highlights as a user hovers their mouse over it? 当鼠标悬停在对象上时,Pyopengl 中是否有任何 Inbuild 函数可以选择对象? - Is there any Inbuild function in Pyopengl that selects the object when mouse is hovered over it? PyQt5 鼠标跟踪 QLabel 对象 - PyQt5 Mouse Tracking Over QLabel Object pygame检测鼠标光标在对象上 - pygame detecting mouse cursor over object 在Tkinter中按下按钮时播放声音效果 - Play sound effect when you press a Button in Tkinter
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM