Sound Stop Problem

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

Raiden93

Betreff: Sound Stop Problem

BeitragDo, Feb 03, 2011 22:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey,
ich habe in meinem Hauptmenü es so eingebaut, das wenn die Maus über einem Button fährt der Button farblich verändert wird.Jetzt wollte ich es aber noch gerne haben das wenn ich mit der Maus über einem Button fahre mein sfx_Button_change 1mal abgespielt wird.Ich könnte jetzt für jeden einzelnen Sound eine Variable erstellen und mit True and False arbeiten.Aber gibt es nicht noch eine andre Lösung?
Code: [AUSKLAPPEN]
Function Buttons_Function()
   Select Modus
      Case 1;Hauptmenü
         If ImagesCollide (gfx_Maus_Point,MausX,MausY,0,gfx_Button_Spielstart,240,150,0)
            DrawImage gfx_Button_Spielstart_on,240,150
         ;   PlaySound (sfx_Button_change)
         Else
            DrawImage gfx_Button_Spielstart,240,150
         End If
         
         If ImagesCollide (gfx_Maus_Point,MausX,MausY,0,gfx_Button_Optionen,240,250,0)
            DrawImage gfx_Button_Optionen_on,240,250
         ;   PlaySound (sfx_Button_change)
         Else
            DrawImage gfx_Button_Optionen,240,250
         End If
         
         If ImagesCollide (gfx_Maus_Point,MausX,MausY,0,gfx_Button_Beenden,240,350,0)
            DrawImage gfx_Button_Beenden_on,240,350
         ;   PlaySound (sfx_Button_change)
         Else
            DrawImage gfx_Button_Beenden,240,350
         End If
      Case 2;Spiel
         
      Case 3;Optionen
         
    End Select
End Function

Dice of Darkness

BeitragDo, Feb 03, 2011 23:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Also erstmal ist es ziemlich blöd, das "Bild" des Mauszeigers auf Kollision mit dem Button zu überprüfen. Das wäre allerhöchstens (aber noch nichtmal dann wirklich) gerechtfertigt, wenn der Button verschiedene Kurven und Ecken hat und du eine perfekte, pixelgenaue Kollisionsabfrage haben willst.
Ansonsten, wenn ein Button rechteckig ist, kannst du einfach kontrollieren, ob der Mauszeiger sich innerhalb des Bildbereichs vom Button befindet.

Beispiel: Der Button button_start wird an den Koordinaten 50,50 gezeichnet (= Eckpunkt links oben), und ist 150 mal 200 Pixel groß. Dann sieht die Kollisionsabfrage wie folgt aus:

Code: [AUSKLAPPEN]
If (MouseX() >= 50) And (MouseX() <= (50+150) And (MouseY() >= 50) And (MouseY() <= (50+200)) Then
    DrawImage button_start
EndIf


Erklärung zum obigen Beispiel: Erst wird überprüft, ob die X-Koordinate der Maus mindestens am linken oberen Rand ist. Dann, ob die X-Koordinate maximal den rechten Rand berührt. Und das gleiche noch einmal für die Y-Achse. Wenn beides erfüllt ist, wissen wir also, dass der Mauszeiger innerhalb des Buttonfeldes ist, und das "button_start" kann gezeichnet werden.

Nun zu dem Soundproblem: Um einen Sound abzuspielen, verwendet man in der Regel einen Soundkanal. Sonst hast du nämlich keine Kontrolle über das Abspielen, Anhalten etc. Ein Soundkanal ist einfach eine Integer-Variable:

Code: [AUSKLAPPEN]
Global soundchannel


Und jetzt rufst du an diesem Kanal den Befehl PlaySound auf:

Code: [AUSKLAPPEN]
soundchannel = PlaySound(click)


Noch besser ist es allerdings zu prüfen, ob der Kanal bereits etwas abspielt oder nicht. Denn wenn schon ein Sound abgespielt wird, kann es zu hässlichen Überlappungen führen, die nicht schön klingen Wink. Deswegen kann man mit ChannelPlaying() testen, ob ein Soundkanal schon etwas abspielt. Falls nein, kann man dann den Sound abspielen lassen:

Code: [AUSKLAPPEN]
If Not ChannelPlaying(soundchannel)
    soundchannel = click
EndIf


Beachte allerdings, dass, wenn du das ganze in einer Schleife ausführen lässt, der Sound jedes Mal, nachdem er fertig abgespielt wurde, erneut abgespielt wird, obwohl der User den Mauszeiger vielleicht gar nicht vom Button weg bewegt hat. Um so ein "Dauerklicken" zu vermeiden, kannst du ja noch eine Boolean-Variable einfügen und testen, ob der Sound zum ersten Mal gespielt wird, und erst wenn der Mauszeiger den Button wieder verlässt, soll der Sound neu abgespielt werden.


MfG, Dice
Gratis Spiele, Musik, Tools

Raiden93

BeitragFr, Feb 04, 2011 7:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Jetzt wird der Buttvon change sound nicht mehr alle 1000tel Sekunde Abgespielt doch jetzt besteht das Problem das er den Sound direkt nochmal abspielt sobald der Soundchannel wieder frei ist.

Sprich:
Ich fahre mit der Maus über dem Button, der Button Sound wird abgespielt und sobald der sound fertig abgespielt ist wird alles wieder von vorne abgespielt.

Was ich aber will das es nur 1 mal den Sound abspielt und dann erst wieder abgespielt werden kann sobald ich über einen anderen Button gefahren bin.

EDIT:
Habe es so gelöst.
Code: [AUSKLAPPEN]
Global Button1_Abspielen = True ;Button Sound Hauptmenü
Global Button2_Abspielen = True ;Button Sound Hauptmenü
Global Button3_Abspielen = True ;Button Sound Hauptmenü

Function Buttons_Function()
   
   
   Select Modus
      Case 1;Hauptmenü
         If ImagesCollide (gfx_Maus_Point,MausX,MausY,0,gfx_Button_Spielstart,240,150,0)
            DrawImage gfx_Button_Spielstart_on,240,150
            Button2_Abspielen = True
            Button3_Abspielen = True
            If Button1_Abspielen = True
               Button1_Abspielen = False
               PlaySound(sfx_Button_change)
            End If
         Else
            DrawImage gfx_Button_Spielstart,240,150
         End If
         
         If ImagesCollide (gfx_Maus_Point,MausX,MausY,0,gfx_Button_Optionen,240,250,0)
            DrawImage gfx_Button_Optionen_on,240,250
            Button1_Abspielen = True
            Button3_Abspielen = True
            If Button2_Abspielen = True
               Button2_Abspielen = False
               PlaySound(sfx_Button_change)
            End If
         Else
            DrawImage gfx_Button_Optionen,240,250
         End If
         
         If ImagesCollide (gfx_Maus_Point,MausX,MausY,0,gfx_Button_Beenden,240,350,0)
            DrawImage gfx_Button_Beenden_on,240,350
            Button1_Abspielen = True
            Button2_Abspielen = True
            If Button3_Abspielen = True
               Button3_Abspielen = False
               PlaySound(sfx_Button_change)
            End If
         Else
            DrawImage gfx_Button_Beenden,240,350
         End If
      Case 2;Spiel
         
      Case 3;Optionen
         
    End Select
End Function

Dice of Darkness

BeitragFr, Feb 04, 2011 13:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Du hast in dem zweiten Code ja überhaupt keine Änderung vorgenommen Shocked . Dann hätte ich mir das ja sparen können, dir die Lösungsvorschläge zu machen... Deine Version wird zwar funktionieren, aber:

Arrow Die Kollisionsabfrage zwischen Mauszeiger und Button verbraucht viel Speicher und der Befehl ImagesCollide() kann immer wieder aus diversen Gründen Fehler verursachen, bis hin zu MAV's.

Arrow Der Sound / die Sounds werden immer noch ohne Soundkanal abgespielt. Das kann blöde Folgen haben (es ist einfach schlechter Stil, nur den Befehl PlaySound() anzugeben, siehe meinen Beitrag oben).

Arrow Du brauchst jetzt für jeden neuen Button eine eigene Bool-Variable. Das ist super-unpraktisch, vor allem weil du in jedem Schritt (so wie es in deinem Code bisher aussieht) alle Bool-Variablen für jeden einzelnen Button auf True oder False setzt. Mach doch lieber eine Bool-Variable (z.B. "mouse_on_any_button") und setze sie auf True, sobald ein Button berührt wird. Und sobald der Mauszeiger sich nicht mehr auf einem Button befindet, wird die Variable sofort wieder auf False gesetzt. Ungefähr so:

Code: [AUSKLAPPEN]
Global mouse_on_any_button = False  ;noch wurde ja kein Button berührt

If (MouseX() >= button_eckpunkt_links) And (MouseX() <= button_eckpunkt_rechts) And (MouseY() >= button_eckpunkt_oben) And (MouseY() <= button_eckpunkt_unten)  ;Mauszeiger berührt den ersten Button
    If mouse_on_any_button = False Then soundchannel = PlaySound(sound)  ;jetzt darf der Sound genau einmal gespielt werden
    mouse_on_any_button = True  ;und bei der nächsten Abfrage wird der Sound nicht mehr gespielt, weil die Bedingung falsch ist

ElseIf (siehe oben, gleiche Abfrage für die anderen Buttons)
   ...
Else
    mouse_on_any_button = False  ;wenn der Mauszeiger gar keinen Button berührt
EndIf
Gratis Spiele, Musik, Tools

Raiden93

BeitragFr, Feb 04, 2011 16:03
Antworten mit Zitat
Benutzer-Profile anzeigen
ahh danke werde es sofort korrigieren und das mit dem"Code: [AUSKLAPPEN]
 If (MouseX() >= 50) And (MouseX() <= (50+150) And (MouseY() >= 50) And (MouseY() <= (50+200)) Then
    DrawImage button_start
EndIf"
"

ist bei mir gerade unpraktisch weil meine Buttons rund sind gibt es dafür auch eine :ösung?

Xeres

Moderator

BeitragFr, Feb 04, 2011 16:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Abgerundet: Rechteck Prüfen genügt. Rund: Kreis prüfen.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Raiden93

BeitragFr, Feb 04, 2011 16:32
Antworten mit Zitat
Benutzer-Profile anzeigen
aber es sieht Blöd aus wenn ich mit der Maus an meinem Rand gehe und dort der Button noch nicht aufblinkt .

Xeres

Moderator

BeitragFr, Feb 04, 2011 17:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Hast du mal das Bild als Beispiel? In den wenigsten Fällen wird ein Benutzer so exakt darauf achten. Solange a) er sieht, wenn er etwas klicken kann (optische Rückmeldung) und b) sich keine 2 Buttons überlagern, sollte es in Ordnung gehen.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group