Seite 1 von 2

MouseButtonReleased()

Verfasst: 15.12.2006 17:58
von a14xerus
Gibt es so einen Befhel oder ein Workaround?
Ich möchte erreichen ,das es die Selbe Funktion wie KeyboardReleased() hat, da ich ansonsten vorallem in der Menünavigation meines Spiels oft Probleme bekomme
Möglichkeit wäre ja GetAsyncKeyState_(#VK_LBUTTON) = -32767, aber auf den SchulPC's funktioniert Api irgendwie nicht (jedenfalls dieser Befehl), und es wäre ja doof, wenn das auf manchen PC's nicht geht

Verfasst: 15.12.2006 18:42
von mk-soft
Hi,

Code: Alles auswählen

;-TOP
; Kommentar       : 
; Author          : mk-soft
; Second Author   : 
; Datei           : .pb
; Version         : 1.01
; Erstellt        : 
; Geändert        :
; 
; Compilerversion : PB4.01 
; Compilermode    :
;
; ***************************************************************************************

;- Konstanten
Enumeration ; Window ID
  #Window
EndEnumeration

Enumeration ; Menu ID
  #Menu
EndEnumeration

Enumeration ; MenuItem ID
  #Menu_Exit
EndEnumeration

Enumeration ; Statusbar ID
  #Statusbar
EndEnumeration

Enumeration ; Gadget ID
  
EndEnumeration

; ***************************************************************************************

;- Globale Variablen
Global exit = 0

;- Fenster
style = #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 400, 300, "Fenster", style)
  ; Menu
  If CreateMenu(#Menu, WindowID(#Window))
    MenuTitle("&Datei")
      MenuItem(#Menu_Exit, "Be&enden")
  EndIf
  ; Statusbar
  CreateStatusBar(#Statusbar, WindowID(#Window))
  ; Gadgets
  If CreateGadgetList(WindowID(#Window))
  
  EndIf
  
  ;-- Hauptschleife
  Repeat
    event   = WaitWindowEvent()
    window  = EventWindow()
    menu    = EventMenu()
    type    = EventType()
    Select event
      Case #PB_Event_Menu                       ; ein Menü wurde ausgewählt
        Select menu
          Case #Menu_Exit
            Exit = 1
        EndSelect
      Case #PB_Event_Gadget                     ; ein Gadget wurde gedrückt
      Case #PB_Event_CloseWindow                ; das Schließgadget vom Fenster wurde gedrückt
        Exit = 1
      Case #PB_Event_Repaint                    ; der Fensterinhalt wurde zerstört und muss neu gezeichnet werden (nützlich für 2D Grafik-Operationen) 
      Case #PB_Event_SizeWindow                 ; das Fenster wurde in der Größe verändert
      Case #PB_Event_MoveWindow                 ; das Fenster wurde verschoben
      Case #PB_Event_ActivateWindow             ; das Fenster wurde aktiviert (hat den Fokus erhalten)
      Case #PB_Event_SysTray                    ; das SysTray wurde aktiviert
    
      Case #WM_LBUTTONUP
        Debug "Left Button Up"
      Case #WM_RBUTTONUP
        Debug "Right Button Up"
        
    EndSelect
    
  Until Exit
EndIf


Verfasst: 15.12.2006 18:43
von #NULL
da du von KeyboardReleased() sprichst, nehme man an im screen, richtig?

Code: Alles auswählen

mb1=MouseButton(1)
;..
If mb1_was And Not mb1
  ; mouse-button 1 released
EndIf
;...
;...
mb1_was=mb1

Verfasst: 15.12.2006 19:52
von a14xerus
#NULL hat geschrieben:da du von KeyboardReleased() sprichst, nehme man an im screen, richtig?
Ja
#NULL hat geschrieben:

Code: Alles auswählen

mb1=MouseButton(1)
;..
If mb1_was And Not mb1
  ; mouse-button 1 released
EndIf
;...
;...
mb1_was=mb1
Das is schon ne gute lösung, aber gibt es niht vielleicht doch ne funktion für sowas?

Aber ersteinmal reicht das vollkommen aus. Danke

Verfasst: 15.12.2006 20:05
von RaVeN99
:?
Kann ja sein dass ich das jetz falsch verstehe, aber pack doch den code von #NULL einfach in ne Procedure.
Du lässt einfach jedesmal wenn einer der MBs gedrückt wurde ne variable auf 1 setzen, sobald die Maus wieder ne aktion ausführen kann (sprich sich über nem Button befindet or so) frägste einfach erneut den MB status ab. Ist der 0 wurde der MB losgelassen.
Das ganze kannste ja auch ständig machen lassen, in der Mainloop, einfach einmal pro durchgang guggen was der MB so macht und ggf. eben die variable verändern. Also so würds ich machen... Theoretisch brauchste ja nichmal wirklich ne Proc *grübel*

Aber wie gesagt, kanns auch völlig missverstanden haben - damit wär das gerede also hinfällig ;)



Mfg
RaVeN

Verfasst: 15.12.2006 20:10
von a14xerus
ne du hast es schon verstanden
Im moment wird einfach einmal pro Mainloop der Status geholt, vorher der alte in *_was verschoben und dann anstatt mousebutton(#pb_musebutton_*) immer die mb* and not *_was geschichte.
Also es klappt schon.
Ich dachte nur, wenn es sowas für die Tastatur gibt...
Aber wiegesagt. so geht es auch

Verfasst: 15.12.2006 20:13
von edel
Der DX Screen laeuft auf einem normalem Fenster. Dieses kannst du
per subclass abfangen und auf #WM_LBUTTONUP reagieren.


Beispiel :

Code: Alles auswählen

Prototype PrevCallback(hwnd,msg,wParam,lParam)

Procedure Callback(hwnd,msg,wParam,lParam)
  Shared PrevCallback.PrevCallback
  
  If msg = #WM_LBUTTONUP
    CloseScreen()
    MessageRequester("","Linke Taste wurde losgelassen")
    End
  EndIf
  
  ProcedureReturn PrevCallback(hwnd,msg,wParam,lParam)
EndProcedure

InitSprite()

OpenScreen(800,600,32,"")

PrevCallback.PrevCallback = SetWindowLong_(ScreenID(),#GWL_WNDPROC,@Callback())

Repeat 
  ClearScreen(0)
  
  
  
  
  FlipBuffers() 
ForEver

Verfasst: 16.12.2006 01:44
von Kaeru Gaman
ich schätze mal, dein kernproblem wird sein, dass du nicht möchtest,
dass das programm mehrere loops lang auf den tastendruck reagiert.

das problem besteht ja auch beim keyboard im screen.
allerdings empfinde ich die lösung über KeyboardReleased() als Notlösung,
da ich persönlich es vorziehe, wenn das programm auf
den tastendruck reagiert und nicht auf dessen beendigung.
(kann bei games lästig sein, wenn die steuertasten erst bei loslassen funktionieren)

so ein "react only once" verhalten kann man ganz einfach mit einem flag programmieren,
ganz ähnlich wie das beispiel von NULL und die Ausführungen von Raven...

Code: Alles auswählen

If MouseButton(1)
  If MbutActive = 0
    ; Hier die Reaktion
    MbutActive = 1
  EndIf
Else
  MbutActive = 0
EndIf
btw: in die Windows-Oberfläche ist so etwas schon eingebaut.
der rückgabewert von GetAsyncKeyState_(#VK_LBUTTON) (war es glaubich)
ist beim ersten drücken anders als bei gedrückt halten. beide sind <>0, aber sie unterscheiden sich.

Verfasst: 16.12.2006 09:43
von #NULL
<edit: der rückgabewert von GetAsyncKeyState kann manchmal deshalb bei aufeinanderfolgenden aufrufen variieren, weil ein potenielles "was pressed since previous call" beim zweiten aufruf nicht mehr vorhanden ist>

Code: Alles auswählen

OpenWindow(0,500,100,100,100,"")
Repeat
  event=WaitWindowEvent()
  
  lb.w=GetAsyncKeyState_(#VK_LBUTTON)
  If lb & 1
    Debug "lb was pressed (not just down) since last GAKS-call"
  EndIf
  
  If lb & (1<<15)
    Debug "lb is currently down"
  EndIf
  
Until event=#PB_Event_CloseWindow
für eine untersucheung auf ein mouse-released müßte man auch mit GetAsyncKeyState() ein flag bzw ein last/old-variable einführen.


..so ist es eigenltich recht simpel, egal ob mit GAKS() oder mit MouseButton():

Code: Alles auswählen

InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(800,600,32,"")
Repeat
  ExamineKeyboard()
  ExamineMouse()

  ;lb2=lb1 :: lb1=GetAsyncKeyState_(#VK_LBUTTON)
  lb2=lb1 :: lb1=MouseButton(1)

  If lb2 And Not lb1
    ;mouse released
    n!1
  EndIf

  ClearScreen(n*$88)
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)

Verfasst: 16.12.2006 13:42
von a14xerus
Danke für die ganze hilfe, aber es klappt super bei mir jetzt
Keyboardreleased() war nur ein beispiel, ich benutz es nur zum beenden des spiels, damit es nicht dann innerhalb von 3 frames durch 3 menüs springt
Und das mit der maus klappt auch super