Buttons für Spiele/Fullscreen-Anwendungen
Verfasst: 22.10.2009 16:09
Hallo,
nachdem ich ein paar Informationen gesammelt habe und nun an
einem Brettspiel arbeite, habe ich mal ein Button-Include
zusammengebastelt:
Die Benutzung ist anschaulich im Code vorgeführt. Trotzdem ein paar Hinweise:
- Das Include verwendet das Eventhandling von normalen Fenstern
- Anstatt OpenScreen verwende ich ein Borderless WindowedScreen
- Die Sprites für Buttons bestehen aus drei seitlich aneinandergereihten Teilen: "Unaktiv", "Fokus" und "Eingedürckt"
- Die Größe eines Button-Sprites ist egal, solange die Breite durch 3 Teilbar ist
Ansonsten denke ich mal, dass alles Weitere klar ist.
Wenn es Fragen, Kommentare und irgendwelche Anregungen gibt, dann bitte posten.
Viel Spaß damit!
Gruß Josef
nachdem ich ein paar Informationen gesammelt habe und nun an
einem Brettspiel arbeite, habe ich mal ein Button-Include
zusammengebastelt:
Code: Alles auswählen
;******************************************
; Constants
;******************************************
Enumeration
#Button_Normal
#Button_MouseOver
#Button_Push
EndEnumeration
;******************************************
; Structures
;******************************************
Structure Button
Sprite.i
State.i
X.i
Y.i
Width.i
Height.i
EndStructure
;******************************************
; Variables
;******************************************
Global *Button_Array
Global Button_MaxIndex.i
Global *Button_Current.Button
Global Button_Pushed.i
ExamineDesktops()
Global PreviousWidth = DesktopWidth(0)
Global PreviousHeight = DesktopHeight(0)
Global PreviousDepth = DesktopDepth(0)
Global PreviousFrequency = DesktopFrequency(0)
;******************************************
; Functions
;******************************************
Procedure.i UseButtons(Array Button.Button(1))
*Button_Array = @Button(0)
Button_MaxIndex = ArraySize(Button())
*Button_Current = 0
EndProcedure
Procedure.i SetButton(Index.i, Sprite.i, X.i, Y.i)
Protected *Button.Button = *Button_Array + Index * SizeOf(Button)
*Button\Sprite = Sprite
If Sprite
*Button\State = #Button_Normal
*Button\X = X
*Button\Y = Y
*Button\Width = SpriteWidth(Sprite) / 3
*Button\Height = SpriteHeight(Sprite)
EndIf
EndProcedure
Procedure.i ExamineButtons(Event.i, MouseX.i, MouseY.i)
Protected *Button.Button, Index.i
If *Button_Current
*Button = *Button_Current
Select *Button\State
Case #Button_MouseOver
If Not (MouseX => *Button\X And MouseX < *Button\X + *Button\Width And MouseY => *Button\Y And MouseY < *Button\Y + *Button\Height)
*Button_Current = #Null
*Button\State = #Button_Normal
ElseIf Event = #WM_LBUTTONDOWN Or Event = #WM_LBUTTONDBLCLK
*Button\State = #Button_Push
EndIf
Case #Button_Push
If Event = #WM_LBUTTONUP
If MouseX => *Button\X And MouseX < *Button\X + *Button\Width And MouseY => *Button\Y And MouseY < *Button\Y + *Button\Height
*Button\State = #Button_MouseOver
Button_Pushed = (*Button - *Button_Array) / SizeOf(Button)
ProcedureReturn #True
Else
*Button_Current = #Null
*Button\State = #Button_Normal
EndIf
EndIf
EndSelect
Else
*Button = *Button_Array
For Index = 0 To Button_MaxIndex
If *Button\Sprite
If MouseX => *Button\X And MouseX < *Button\X + *Button\Width And MouseY => *Button\Y And MouseY < *Button\Y + *Button\Height
*Button\State = #Button_MouseOver
*Button_Current = *Button
Break
EndIf
*Button + SizeOf(Button)
EndIf
Next
EndIf
ProcedureReturn #False
EndProcedure
Procedure.i DisplayButtons()
Protected *Button.Button = *Button_Array, Index.i
For Index = 0 To Button_MaxIndex
If *Button\Sprite
ClipSprite(*Button\Sprite, *Button\State * *Button\Width, 0, *Button\Width, *Button\Height)
DisplaySprite(*Button\Sprite, *Button\X, *Button\Y)
EndIf
*Button + SizeOf(Button)
Next
EndProcedure
Procedure.i DisplayTransparentButtons()
Protected *Button.Button = *Button_Array, Index.i
For Index = 0 To Button_MaxIndex
If *Button\Sprite
ClipSprite(*Button\Sprite, *Button\State * *Button\Width, 0, *Button\Width, *Button\Height)
DisplayTransparentSprite(*Button\Sprite, *Button\X, *Button\Y)
EndIf
*Button + SizeOf(Button)
Next
EndProcedure
Procedure.i PushedButton()
ProcedureReturn Button_Pushed
EndProcedure
;******************************************
; Example
;******************************************
Procedure.i SetScreenSettings(Width.i ,Height.i, BitsPerPel.i ,Frequency.i ,TestMode.i = 0)
; Danke an "fluid byte"!
Protected DevMode.DEVMODE
DevMode\dmSize = SizeOf(DEVMODE)
DevMode\dmFields = #DM_BITSPERPEL | #DM_PELSWIDTH | #DM_PELSHEIGHT | #DM_DISPLAYFREQUENCY
DevMode\dmBitsPerPel = BitsPerPel
DevMode\dmPelsWidth = Width
DevMode\dmPelsHeight = Height
DevMode\dmDisplayFrequency = Frequency
ProcedureReturn ChangeDisplaySettings_(@DevMode, TestMode)
EndProcedure
Global Sprite.i
Global Dim Button.Button(5)
InitSprite()
SetScreenSettings(1024, 768, 32, 60) ;Wenn nötig anpassen!
OpenWindow(0, 0, 0, 0, 0, "Test", #PB_Window_Maximize|#PB_Window_BorderLess)
OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768, 0, 0, 0) ;Hier ebenso anpassen, wenn nötig!
Sprite = CreateSprite(#PB_Any, 80 * 3, 30)
StartDrawing(SpriteOutput(Sprite))
Box(0 , 0, 80, 30, $C0C0C0) ;Normal
Box(80 , 0, 80, 30, $FF0000) ;Mouse over
Box(160, 0, 80, 30, $800000) ;Push
StopDrawing()
UseButtons(Button())
For I = 0 To 5
SetButton(I, Sprite, 200, 200 + I*40)
Next
Repeat
Event = WindowEvent()
ClearScreen(#Black)
; Buttons anzeigen:
DisplayButtons()
FlipBuffers()
; Events für Buttons abfragen:
If ExamineButtons(Event, WindowMouseX(0), WindowMouseY(0))
; Button wurde gedrückt:
Debug "Button nr. " + Str(PushedButton() + 1) + " pushed"
Else
; Sonstige Abfragen:
Select Event
Case #WM_KEYDOWN
If EventwParam() = #VK_ESCAPE
Break
EndIf
EndSelect
EndIf
Delay(1)
ForEver
CloseWindow(0)
SetScreenSettings(PreviousWidth, PreviousHeight, PreviousDepth, PreviousFrequency)
End
- Das Include verwendet das Eventhandling von normalen Fenstern
- Anstatt OpenScreen verwende ich ein Borderless WindowedScreen
- Die Sprites für Buttons bestehen aus drei seitlich aneinandergereihten Teilen: "Unaktiv", "Fokus" und "Eingedürckt"
- Die Größe eines Button-Sprites ist egal, solange die Breite durch 3 Teilbar ist
Ansonsten denke ich mal, dass alles Weitere klar ist.
Wenn es Fragen, Kommentare und irgendwelche Anregungen gibt, dann bitte posten.
Viel Spaß damit!
Gruß Josef