Seite 1 von 1

Unterbrechbarer Ablauf

Verfasst: 20.11.2025 18:18
von Delle
Hallo,

was ich noch nie so richtig verstanden habe: wie kann ich z.B. ein Intro abbrechen mit Taste oder Maus, wenn aber irgendwas noch durchläuft?

Guckt euch mal den Code an: es werden nacheinander 3 verschiedene Hintergründe angezeigt mit 1 Sekunde Abstand.

Wie kann man aber - egal an welcher Stelle - das Intro beenden?

Muss ich da mit Threads arbeiten?

Code: Alles auswählen

If InitSprite() = 0
    MessageRequester("Error", "Can't open screen & sprite environment!", 0)
    End
  EndIf
  
  If OpenWindow(0, 0, 0, 420, 200, "A screen in a window...", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
    CreateStatusBar(0, WindowID(0))
      AddStatusBarField(420)
      
    StatusBarText(0, 0, "Automatically zoomed screen area when changing window size...")
    
    If OpenWindowedScreen(WindowID(0), 0, 0, 420, 200, #True, 0, 20)
  
      CreateSprite(0, 50, 50) ; Erstellt ein leeres Sprites, dies wird komplett schwarz sein
        
      Repeat
        ; Es ist sehr wichtig, alle im Queue befindlichen Ereignisse während jedes Frames abzuarbeiten
        ;
        Repeat
          Event = WaitWindowEvent(10)
          
          If Event = #PB_Event_CloseWindow Or Event = #PB_Event_LeftClick
            End
          EndIf
        Until Event = 0
        
        FlipBuffers()
        ClearScreen(RGB(0, 0, 0)) ; Ein blauer Hintergrund
        Delay(1000)
        
        
        FlipBuffers()
        ClearScreen(RGB(64, 64, 64)) ; Ein blauer Hintergrund
        Delay(1000)
        
        
        FlipBuffers()
        ClearScreen(RGB(64,0,0)) ; Ein blauer Hintergrund
        Delay(1000)
        
      ForEver
      
    Else
      MessageRequester("Error", "Can't open windowed screen!", 0)
    EndIf
  EndIf

Re: Unterbrechbarer Ablauf

Verfasst: 20.11.2025 18:38
von NicTheQuick
Du solltest da besser kein Delay() einbauen, sondern vorher z.B. in einem Array festlegen welche Farbe nach welcher anderen kommt und dann mit ElapsedMilliseconds() arbeiten um bei jedem Schleifendurchlauf zu prüfen, wann die nächste Farbe dran kommt. Du speicherst also in einer Variable den aktuellen Wert von ElapsedMilliseconds() plus 1000 und wenn dann in der Schleife der Wert von ElapsedMilliseconds() über dem in der Variable ist, zeigst du die nächste Farbe an und erhöhst gleichzeitig den Wert der Variable wieder um 1000, damit der nächste Farbwechsel wieder nach einer Sekunde passiert.
Dann läuft deine Schleife ununterbrochen und du kannst jederzeit die Tastatureingaben prüfen.

Threads sind für dieses Beispiel etwas überrissen.

Re: Unterbrechbarer Ablauf

Verfasst: 20.11.2025 18:54
von Axolotl
ich habe es mal mit Timer und Statemachine versucht....
Soll das so?

Code: Alles auswählen

If InitSprite() = 0
    MessageRequester("Error", "Can't open screen & sprite environment!", 0)
    End
  EndIf
  
  If OpenWindow(0, 0, 0, 420, 200, "A screen in a window...", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
    CreateStatusBar(0, WindowID(0))
      AddStatusBarField(420)
      
    StatusBarText(0, 0, "Automatically zoomed screen area when changing window size...")
    
    If OpenWindowedScreen(WindowID(0), 0, 0, 420, 200, #True, 0, 20)
  
      CreateSprite(0, 50, 50) ; Erstellt ein leeres Sprites, dies wird komplett schwarz sein

      AddWindowTimer(0, 1, 1000) 
      statemachine = 0 

      Repeat
        ; Es ist sehr wichtig, alle im Queue befindlichen Ereignisse während jedes Frames abzuarbeiten
        ;
        Repeat
          Event = WaitWindowEvent(10)
          
          If Event = #PB_Event_CloseWindow Or Event = #PB_Event_LeftClick
;           End
            Break 2 

          ElseIf Event = #PB_Event_Timer 
            statemachine + 1 

          EndIf
        Until Event = 0
        
        Select statemachine 
          Case 0 
            ; nothing to do until ..... 

          Case 1 
            FlipBuffers()
            ClearScreen(RGB(0, 0, 0)) ; Ein blauer Hintergrund
;           Delay(1000)

          Case 2 
            FlipBuffers()
            ClearScreen(RGB(64, 64, 64)) ; Ein blauer Hintergrund
;           Delay(1000)
        
          Case 3 
            FlipBuffers()
            ClearScreen(RGB(64,0,0)) ; Ein blauer Hintergrund
;           Delay(1000)

          Default 
            Break ; done. 
        EndSelect 

      ForEver
      
    Else
      MessageRequester("Error", "Can't open windowed screen!", 0)
    EndIf
  EndIf

Re: Unterbrechbarer Ablauf

Verfasst: 20.11.2025 19:14
von Delle
Yup, genau so.... halt nur noch in Schleife :)

Mousebewegungen müsste man dann mit MouseX/Y abfragen, oder?
Bei einem reinen Window (2D) dann mittels GetCursorPos_(MousePos(0)) oder?

Weil Event für Mausbewegungen gibt's ja anscheinend nicht...

Re: Unterbrechbarer Ablauf

Verfasst: 20.11.2025 22:38
von Delle
Frage: lässt sich der Ablauf auch durch Bewegung der Maus unterbrechen?

Ich habe InitMouse() sowie ExamineMouse() bereits drin, aber Debug MouseX() bzw. MousY() liefern immer 0.

Ansonsten hätte ich intial die Position von MouseX() + MouseY() abgefragt und während der Schleife die Werte verglichen, ob sich was geändert hat...

Re: Unterbrechbarer Ablauf

Verfasst: 21.11.2025 00:18
von Delle
Gefunden:

If DesktopMouseX()<>mousex Or DesktopMouseY()<>mousey
End
EndIf

Also ich komm hier echt mit Windows/Screens durcheinander..

Re: Unterbrechbarer Ablauf

Verfasst: 21.11.2025 00:29
von Delle
Wie kriegt man noch einen Abbruch damit rein?

If KeyboardReleased(#PB_Key_All)

End
EndIf


Mit der Maus funktioniert es, auf Tastaturanschläge aber keinerlei Reaktion...

Re: Unterbrechbarer Ablauf

Verfasst: 21.11.2025 01:05
von Axolotl
Ich mache nur windows und nicht screen....
Deshalb würde ich ein case #WM_KEYDOWN mit break einbauen.

Re: Unterbrechbarer Ablauf

Verfasst: 21.11.2025 11:50
von Axolotl
So, ich arbeite eher selten bis garnicht mit den 2D-Games Funktionen.
Aber: Die Hilfe ist dein Freund. Hier würdest du alle Hinweise finden, die dein Program zum funktionieren bringen.
Oder einfach gesagt: Du hast die jeweiligen InitMouse() bzw. InitKeyboard() Funktionen vergessen.
Ich habe noch ein zweites Beispiel gebastelt, mit dem Vorschlag von NicTheQuick.
Mir persönlich gefällt das zweite Beispiel hier weiter unten besser, weil es "Windows-konformer" ist und die Mouse sichtbar bleibt.

Code: Alles auswählen

Define Index, Count = 3 
Define Dim Colors(Count) 

; init .... 
  Colors(0) = RGB(0, 0, 0)    ; Ein blauer Hintergrund 
  Colors(1) = RGB(64, 64, 64) ; Ein blauer Hintergrund
  Colors(2) = RGB(64,0,0)     ; Ein blauer Hintergrund
  Colors(3) = RGB(64,0,0)     ; Ein blauer Hintergrund 

;If InitSprite() = 0
If InitMouse() = 0 Or InitSprite() = 0 Or InitKeyboard() = 0
     MessageRequester("Error", "Can't open screen & sprite environment!", 0)
    End
  EndIf
  
  If OpenWindow(0, 0, 0, 420, 200, "A screen in a window...", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
    CreateStatusBar(0, WindowID(0))
      AddStatusBarField(420)
      
    StatusBarText(0, 0, "Automatically zoomed screen area when changing window size...")
    
    If OpenWindowedScreen(WindowID(0), 0, 0, 420, 200, #True, 0, 20)
  
      CreateSprite(0, 50, 50) ; Erstellt ein leeres Sprites, dies wird komplett schwarz sein

      AddWindowTimer(0, 1, 1000) 
      Index = 0 

      Repeat
        ; Es ist sehr wichtig, alle im Queue befindlichen Ereignisse während jedes Frames abzuarbeiten
        ;
        Repeat
          Event = WaitWindowEvent(10)
          
          If Event = #PB_Event_CloseWindow Or Event = #PB_Event_LeftClick
;           End
            Break 2 

          ElseIf Event = #PB_Event_Timer 
            Index + 1 
            If Index < 0 Or Index > Count 
              Break 2  ; Leave the Loop 
            EndIf 

          EndIf
        Until Event = 0

        ExamineKeyboard()
        ExamineMouse()
          
        FlipBuffers()
        ClearScreen(Colors(Index)) 

    ; ForEver 
      If KeyboardPushed(#PB_Key_All)  ; All keys are tested. Very useful for any key checks.
        Break 
      EndIf
      Until MouseButton(#PB_MouseButton_Left) Or MouseButton(#PB_MouseButton_Right)

    Else
      MessageRequester("Error", "Can't open windowed screen!", 0)
    EndIf
  EndIf
Zweites Beispiel:

Code: Alles auswählen

#Threshold  = 1000 + (2000*#PB_Compiler_Debugger)         ; every 1 or X seconds 

Define StartTime.q 
Define Index, Count = 3 
Define Dim Colors(Count) 

; init .... 
  Colors(0) = RGB(0, 0, 0)    ; Ein blauer Hintergrund 
  Colors(1) = RGB(64, 64, 64) ; Ein blauer Hintergrund
  Colors(2) = RGB(64,0,0)     ; Ein blauer Hintergrund
  Colors(3) = RGB(64,0,0)     ; Ein blauer Hintergrund 


  If InitSprite() = 0
     MessageRequester("Error", "Can't open screen & sprite environment!", 0)
    End
  EndIf
  
  If OpenWindow(0, 0, 0, 420, 200, "A screen in a window...", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
    CreateStatusBar(0, WindowID(0))
      AddStatusBarField(420)
      
    StatusBarText(0, 0, "Automatically zoomed screen area when changing window size...")
    
    If OpenWindowedScreen(WindowID(0), 0, 0, 420, 200, #True, 0, 20)
  
      CreateSprite(0, 50, 50) ; Erstellt ein leeres Sprites, dies wird komplett schwarz sein

      Index = 0 
      StartTime = ElapsedMilliseconds() 

      Repeat
        ; Es ist sehr wichtig, alle im Queue befindlichen Ereignisse während jedes Frames abzuarbeiten
        ;
        Repeat
          Select WaitWindowEvent(10) 
            Case #PB_Event_None 
              Break ; leave this window event loop 

            Case #PB_Event_CloseWindow 
              Debug "#PB_Event_CloseWindow  -> bye. " 
              Break 2   ; leave both loops at once 
          
            Case #WM_KEYDOWN 
              Debug "#WM_KEYDOWN  "  ; any key is pressed ? 
              Break 2   ; leave both loops at once 

            Case #PB_Event_LeftClick, #PB_Event_RightClick   ; Mouse Clicks 
              Debug "#PB_Event_MouseClick " 
              Break 2   ; leave both loops at once 

          EndSelect 
        ForEver 

        If ElapsedMilliseconds() - StartTime >= #Threshold 
          Index + 1 
          Debug "Debug Index " + Index 
          If Index < 0 Or Index > Count 
CompilerIf #PB_Compiler_Debugger And 1 ; <== quick check by changing 1 to 0 
            Index = 0  ; Debug start again 
CompilerElse  
            Break  ; Leave the Loop 
CompilerEndIf 
          EndIf 
          StartTime = ElapsedMilliseconds()  ; new start time 
        EndIf 
          
        FlipBuffers()
        ClearScreen(Colors(Index)) 

      ForEver 
      Debug "Done" 

    Else
      MessageRequester("Error", "Can't open windowed screen!", 0)
    EndIf
  EndIf