Grafiken nebenher laufen zu lassen

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
irobot
Beiträge: 162
Registriert: 16.10.2005 09:22
Kontaktdaten:

Grafiken nebenher laufen zu lassen

Beitrag von irobot »

Guten Tag zusammen,

bin gerade dabei - endlich - mein eigenes Jump-n-Run spiel zu programmieren, einfach nur so zum Spass (nix dolles).

Frage dabei: wie kann ich es anstellen, das Dinge (Grafiken) einfach so nebenher laufen, wie z.B. die Flamme einer Fackel an der Wand
bestehend aus 10 einzelnen Sprites, ohne in der eigentlichen Programmschleife immer wieder einen solchen Prozess aufrufen zu müssen?

Mittels CreateThread(...) klappt es nicht, da ein Thread wohl keine Grafiken behandeln kann (?)

Vielen Dank im voraus für eure Kommentare!

Grüsse
Ralf
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Grafiken nebenher laufen zu lassen

Beitrag von STARGÅTE »

So ganz verstehe ich die Frage nicht ("nebenher laufen").
Geht es dir hier um die Position? Oder um Zeit? Oder um die Anzeige selbst?

Die Sprites werden doch eh alle gleichzeitig angezeigt, du brauchst doch nur DisplaySprite in deiner Hauptschleife aufrufen.
Und für ein Positionierungssystem musst du dir entsprechende Variablen oder Strukturen erstellen, die die jeweiligen Koordinaten updaten.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
irobot
Beiträge: 162
Registriert: 16.10.2005 09:22
Kontaktdaten:

Re: Grafiken nebenher laufen zu lassen

Beitrag von irobot »

Hallo STARGÅTE,

ich will einfach ein paar Fackeln oder Rundumlichter oder Ventilatoren oder ... einfach unabhängig vom Hauptprogramm in ihren "bewegungen" darstellen. Also einmal z.B. den Prozess "Ventilator dreht", also sagen wir mal 5 Sprites jeweils mit einem gewissen Delay() einfach starten und unabhängig vom Hauptgeschehen (Spielfigur klettert, oder macht sonstwas) laufen lassen.
BTW: der Hintergrund bewegt sich nicht, er wechselt, wenn die Spielfigur am Rande weiterläuft.

Ich hoffe, ich habe das diesmal verstehbar formuliert...
Benutzeravatar
Macros
Beiträge: 1361
Registriert: 23.12.2005 15:00
Wohnort: Olching(bei FFB)
Kontaktdaten:

Re: Grafiken nebenher laufen zu lassen

Beitrag von Macros »

Hallo irobot,

da hast du verschiedene Möglichkeiten:
  • Ich würde eine simple Lösung wählen:
    Eine Funktion die in der Hauptschleife aufgerufen wird und bewegliche Elemente aktualisiert. Also mal in Peudocode:

    Code: Alles auswählen

    Procedure HintergrundAnimation()
      ForEach Fackel()
        If Fackel_sichtbar
          ; % Modulo So erhöht es sich immer um eines und fällt nach dem höchsten wieder auf 0
          Fackel()\bild = (Fackel\bild=+1) % #Anzahl_Fackelbilder 
          DisplayTransparentSprite(#Fackel_basissprite+Fackel()\Bild,x,y)
        EndIf
      Next
      ; Man könnte auch alle Bewegten Elemente in einer Liste verwalten und nicht einzelne pro Typ anlegen
      ForEach Animiert()
        If Element_sichtbar
          ; Modulo So erhöht es sich immer um eines und fällt nach dem höchsten wieder auf 0
          Animiert()\bild = (Animiert()\bild=+1) % Animiert()\Bilderzahl
          DisplayTransparentSprite(Animiert()\Basisbild+Animiert()\Bild,x,y)
        EndIf
      Next
    EndProcedure
    (natürlich müssten x und y auch geupdated werden und liegen im Idealfall auch in der strukturierten Liste)
    So hast du den Vorteil, dass wenn dein Spiel allgemein ruckelt die Animation immer noch passt.
  • Wenn du wirklich komplett entkoppeln willst machst du einen Thread mit Mutex und einer Liste und in dem Thread aktualisierst du alles

    Code: Alles auswählen

    Global AnimationsMutex=CreateMutex(), global_quit
    Global NewList Animiert.MeineAnimationsStruktur()
    
    Procedure HintergrundAnimation(dummy)
      Repeat
        Delay(#Zeitschrittgenauigkeit)
        LockMutex(AnimationsMutex)
        ForEach Animiert()
          If Element_sichtbar
            Animiert()\sichtbar=1
            Animiert()\bild = (Animiert()\bild=+1) % Animiert()\Bilderzahl
            Animiert()\Sprite=Animiert()\Basisbild+Animiert()\Bild
            ; Weitere Aktualisierungen usw
          EndIf
        Next
        UnlockMutex((AnimationsMutex)
      Until global_quit=1
    EndProcedure
    
    
    AniThread=CreateThread(@HintergrundAnimation(),0)
    
    Repeat
      LockMutex(AnimationsMutex)
      ForEach Animiert()
        If Animiert()\sichtbar
          DisplayTransparentSprite( Animiert()\Sprite, Animiert()\x, Animiert()\y)
        EndIf
        UnlockMutex(AnimationsMutex)
        
        FlipBuffers()
      Until quitcondition
      
      global_quit=1
      
      WaitThread(AniThread)
    Oder sogar einen Schritt weitergehen und Thread(s) im Hintergrund eine Liste Anzuzeigende_Elemente() basteln lassen und die in der Hauptschleife dann rendern. Vorteil ist, dass du CPU last verteilst, doch die ist bei einem Jump and Run meist gering. Nachteil ist, dass das Rendering eventuell Einzelbilder auslässt, wenn es aus welchem Grund auch immer ruckelt. Das kann man natürlich auch nachträglich wieder synchronisieren.
Das mal nur als zwei Denkanstöße, man kann natürlich noch alles dazwischen wählen oder auch andere Lösungsansätze nutzen.
Was du wählst hängt auch davon ab ob du nur das Jump and Run bauen willst, oder vorhast, später ein großes Spiel zu bauen und dir nun Techniken aneignen willst.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Grafiken nebenher laufen zu lassen

Beitrag von STARGÅTE »

irobot hat geschrieben: 31.05.2025 10:12 Hallo STARGÅTE,

ich will einfach ein paar Fackeln oder Rundumlichter oder Ventilatoren oder ... einfach unabhängig vom Hauptprogramm in ihren "bewegungen" darstellen. Also einmal z.B. den Prozess "Ventilator dreht", also sagen wir mal 5 Sprites jeweils mit einem gewissen Delay() einfach starten und unabhängig vom Hauptgeschehen (Spielfigur klettert, oder macht sonstwas) laufen lassen.
BTW: der Hintergrund bewegt sich nicht, er wechselt, wenn die Spielfigur am Rande weiterläuft.

Ich hoffe, ich habe das diesmal verstehbar formuliert...
Sollen ihre "Bewegungen" denn Animationen sein, also mehrere verschiedene Sprites als Frames einer Animation?
Oder soll die "Bewegung" einfach durch eine Positionsänderung bzw. Sprite-Rotation dargestellt werden?

Ich glaube du hast ein falsches Konzept im Kopf, wie solche Szenen auf dem Bildschirm dargestellt werden.
Delays haben z.B. überhaupt nix darin verloren. Alle Sprite (egal ob Hintergrund, Spielfigur, Gegenstände, Effekte, was auch immer) werden immer alle in jedem Frame auf den Bildschirm gerendert. Wenn du Sprites (in ihrer Nummer) durchwechseln willst und das zeitbasiert sein soll (also z.B. alle 200 ms ein Wechsel), dann kannst du ElapsedMilliseconds() verwenden.
So erzeugst du z.B. eine Abfolge von 0,1,2,3,4 in 200 ms Schritten indem du (ElapsedMilliseconds()/200) % 5 schreibst.
Dieser Ausdruck erzeugt dir je nach vergangener Zeit immer Zahlen zwischen 0 und 4, ohne Delay und ohne Hilfsvariablen.

Mit anderen Worten, du schreibst deine "Bewegungen" nicht von Hand Zeilenweise als Programmcode: Display, Delay, Display, Delay ...
sondern per Berechnungsformeln, die je nach Zeit entweder das Spite ändern, die Position oder eben die Roation.
RotateSprite(#Sprite, ElapsedMilliseconds(), #PB_Absolute) würde z.B. ein Sprite rotieren lassen.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
irobot
Beiträge: 162
Registriert: 16.10.2005 09:22
Kontaktdaten:

Re: Grafiken nebenher laufen zu lassen

Beitrag von irobot »

Hallo zusammen,

vielen Dank für eure Hinweise!

Das mit diesem Mutex habe ich noch nicht richtig verstanden (lese gerade in der HTML-Hilfe...)

Ich will das mal mit diesen "ElapsedMilliseconds()" versuchen, bin ja nicht so der Profi

Grüsse
Ralf
Antworten