Animation Bewegen?

Anfängerfragen zum Programmieren mit PureBasic.
D4uS1
Beiträge: 268
Registriert: 02.09.2006 12:16

Animation Bewegen?

Beitrag von D4uS1 »

Folgendes Problem,

Ich habe eine Flieger Animation, ein Jet dessen Turbinen am laufen sind. Diese möchte ich über den Bildschrim bewegen können, per Tastatur. Aber wenn ich die jeweilige Taste drücke, ruckelt das Spiel, weil der Computer erst die Animation an der Stelle zu Ende bringt an der sie angefangen hat, bis er zur nächsten stelle übergeht. Kann mir jemand sagen wo der Fehler liegt? Hier der Code:

Code: Alles auswählen

Procedure Spiel()

For x = 1 To #Max_Flieger
FliegerX = 100
FliegerY = 100
Next

For x = 1 To #Max_Flieger
LoadSprite(x+5, "Bilder/Spiel/Jet/Jet" +Str(x) +".bmp")
TransparentSpriteColor(x+5, RGB(255, 0, 255))
Next

Repeat
ClearScreen(RGB(0, 0, 0))
ExamineKeyboard()

For x = 1 To #Max_Flieger
If KeyboardPushed(#PB_Key_Up)
BewegFliegerY = -4
EndIf
If KeyboardPushed(#PB_Key_Down)
BewegFliegerY = 4
EndIf
Next

FliegerY + BewegFliegerY

For x = 1 To #Max_Flieger
DisplayTransparentSprite(x+5, FliegerX, FliegerY)
FlipBuffers()
Next

Until KeyboardPushed(1)
EndProcedure
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beitrag von STARGÅTE »

Code: Alles auswählen

Procedure Spiel() 

For x = 1 To #Max_Flieger 
FliegerX = 100 
FliegerY = 100 
Next 

For x = 1 To #Max_Flieger 
LoadSprite(x+5, "Bilder/Spiel/Jet/Jet" +Str(x) +".bmp") 
TransparentSpriteColor(x+5, RGB(255, 0, 255)) 
Next 

Repeat 
ClearScreen(RGB(0, 0, 0)) 
ExamineKeyboard() 

For x = 1 To #Max_Flieger 

If KeyboardPushed(#PB_Key_Up) 
BewegFliegerY = -4 
EndIf 
If KeyboardPushed(#PB_Key_Down) 
BewegFliegerY = 4 
EndIf 

FliegerY + BewegFliegerY 

DisplayTransparentSprite(x+5, FliegerX, FliegerY) 
FlipBuffers() 

Next 

Until KeyboardPushed(1) 
EndProcedure
Einfach nur eine For Next Schleife machen, in der Abfrage und Anzeige drin sind

So würde es gehen, obwohl das auch nicht gerade das erfeckte ist ^^
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
tobe
Beiträge: 146
Registriert: 14.09.2006 17:33
Wohnort: Oktoberfest

Beitrag von tobe »

hi,

also auf den ersten blick, springt mich sofort das FlipBuffers() an.
da in der for next schleife kann das nicht gutgehen,
obwohl...wenn man einfach alles in die schleife packt geht es ja auch ;)
hier mal mein vorschlag:

Code: Alles auswählen

Procedure Spiel()
  FliegerX = 100
  FliegerY = 100
  For x = 1 To #Max_Flieger
    LoadSprite(x+5, "Bilder/Spiel/Jet/Jet" +Str(x) +".bmp")
    TransparentSpriteColor(x+5, RGB(255, 0, 255))
  Next
  Repeat
    For x = 1 To #Max_Flieger
      ClearScreen(0)
      ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Up)
        BewegFliegerY = -4
      EndIf
      If KeyboardPushed(#PB_Key_Down)
        BewegFliegerY = 4
      EndIf
      FliegerY + BewegFliegerY
      DisplayTransparentSprite(x+5, FliegerX, FliegerY)
      FlipBuffers()
    Next
  Until KeyboardPushed(1)
EndProcedure
PureBasic 4.40 (Windows - x86)
D4uS1
Beiträge: 268
Registriert: 02.09.2006 12:16

Beitrag von D4uS1 »

Danke für die Antworten, habs schon eingebaut und es funktioniert perfekt!
D4uS1
Beiträge: 268
Registriert: 02.09.2006 12:16

Beitrag von D4uS1 »

Hab doch noch ein Problem, der Jet soll natürlich auch noch schießen können. Da das Bild 200 Pixel breit ist und der Schuss eine Box(blabla) mit der größe 2 und 2 sein soll hab ich SchussX = FliegerX + 99 und SchussY = FliegerY +2 gesetzt. Wenn ich aber schiesse klappt es einfach nicht! Die Schüsse sollen ausserdem in einem bestimmtem Abstand auftauchen und danach nicht verschwinden. Praktisch ein MG, aber wie soll ich das machen?
Benutzeravatar
tobe
Beiträge: 146
Registriert: 14.09.2006 17:33
Wohnort: Oktoberfest

Beitrag von tobe »

da kommen sicher noch mehr probleme auf dich zu ;)
ich hab das alte beispiel nochmal überarbeitet, dabei hab ich die for next schleife für den spritewechsel rausgeschmissen und durch einen zähler ersetzt, den hab ich dann noch in einen 30ms timer reingepackt, dann kann man die geschwindigkeit des spritewechsels schöner anpassen.
jetzt zu den schüssen, da musst du ja irgendwo die koordinaten jedes schusses speichern, dafür hab ich einfach mal ne linked list genommen.
wenn ein schuss aus dem bildschirmbereich rausfliegt sollte man ihn löschen weil sonst hast irgendwann 100000 schüsse in der liste.
ich hoffe der rest erkärt sich von selbst ;)

Code: Alles auswählen

Procedure Spiel()
  FliegerX = 100
  FliegerY = 100
  bildschirmbreite = 800
  NewList schuss.POINT()
  If CreateSprite(#schuss,2,2)
    StartDrawing(SpriteOutput(#schuss))
    Box(0, 0, 2, 2, $909090)
    StopDrawing()
  EndIf
  
  For x = 1 To #Max_Flieger
    LoadSprite(x+5, "Bilder/Spiel/Jet/Jet" +Str(x) +".bmp")
    TransparentSpriteColor(x+5, RGB(255, 0, 255))
  Next
  
  Repeat
    zeit = ElapsedMilliseconds()
    ClearScreen(0)
    ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Up)
      BewegFliegerY = -4
    EndIf
    If KeyboardPushed(#PB_Key_Down)
      BewegFliegerY = 4
    EndIf
    
    FliegerY + BewegFliegerY
    
    If spritewechseltimer < zeit
      spritewechseltimer = zeit + 30
      x + 1
      If x > #Max_Flieger
        x = 1
      EndIf
    EndIf
    DisplayTransparentSprite(x+5, FliegerX, FliegerY)
    
    If KeyboardPushed(#PB_Key_Space)
      AddElement(schuss())
      schuss()\x = FliegerX + 99
      schuss()\y = FliegerY + 2
    EndIf
    ForEach schuss()
      schuss()\x + 5
      If schuss()\x > bildschirmbreite
        DeleteElement(schuss())
      Else
        DisplayTransparentSprite(#schuss, schuss()\x, schuss()\y)
      EndIf
    Next
    
    FlipBuffers()
  Until KeyboardPushed(1)
EndProcedure
ps: mit einem lauffähigen stück code wäre es wesentlich einfacher zu testen ob das auch funktioniert.
PureBasic 4.40 (Windows - x86)
D4uS1
Beiträge: 268
Registriert: 02.09.2006 12:16

Beitrag von D4uS1 »

bei mir verfielfältigt sich dann das flugzeug und wandert nach rechts oder nach links :lol: !
Ghost
Beiträge: 141
Registriert: 10.04.2006 09:10

Beitrag von Ghost »

Vileicht solltest du noch einen timer für die schüsse reinpacken damit du die Feuerate optimieren kannst, ansonsten erzeugt er jeden Frame ein schuss. Also:

Code: Alles auswählen

Global TimerSchuss.f
...
repeat

TimerSchuss +1

If KeyboardPushed(#PB_Key_Space) AND TIMERSCHUSS = (dann einen Wert je höher sesto länger dauert es eh der nächste schuss fällt)
      AddElement(schuss()) 
      schuss()\x = FliegerX + 99 
      schuss()\y = FliegerY + 2 
      TIMER = 0
    EndIf 
    ForEach schuss() 

...
und am besten noch vor repeat "SetFrameRate(X)" reinseten, damitmüsste es auf allen rechnern gleichschnell laufen.
(X durch einen beliebigen wert austauschen ... mit dem Befehl regelst du wievieleFrames Pro Sekunde ablaufen)

Edit
Irgendwo gibt es auch ein tutorial zu diesem Spiel ... musst mal schauen weiß leider net mehr wo ich das her habe ... da stand es sei für fortgescrittene aber so schwer wars nicht

Edit2:
habs gefunden ist auf folgendem link
http://www.purearea.net/pb/german/

Es heist Spieleprogrammieren für Fortgeschrittene.
(nutze v. 3.3)
Benutzeravatar
tobe
Beiträge: 146
Registriert: 14.09.2006 17:33
Wohnort: Oktoberfest

Beitrag von tobe »

@Ghost
das hab ich doch extra weggelassen damit St@ndFurz nicht langweilig wird ;)

jetzt hab ich mal lauffähigen code draus gemacht und auch den 2ten timer mit eingebaut:

Code: Alles auswählen

EnableExplicit
#bildschirmbreite = 800
#bildschirmhoehe = 600
#schuss = 0
#Max_Flieger = 5

Procedure Spiel()
  Define FliegerX, FliegerY, x, zeit, BewegFliegerY, spritewechseltimer, wEvent, SchussTimer
  FliegerX = 100
  FliegerY = 100
  NewList schuss.POINT()
  If CreateSprite(#schuss,2,2)
    StartDrawing(SpriteOutput(#schuss))
    Box(0, 0, 2, 2, $909090)
    StopDrawing()
  EndIf
  
  For x = 1 To #Max_Flieger
    CreateSprite(x, 200, 50)
    StartDrawing(SpriteOutput(x))
    ;Box(0, 0, 199, 199, $909090)
    LineXY(0,0,199,25,$909090)
    LineXY(0,49,199,25,$909090)
    LineXY(0,0,0,49,$909090)
    DrawText(70,18,Str(x))
    StopDrawing()
  Next
  
  Repeat
    zeit = ElapsedMilliseconds()
    ClearScreen(0)
    ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Up)
      BewegFliegerY = -4
    ElseIf KeyboardPushed(#PB_Key_Down)
      BewegFliegerY = 4
    Else
      BewegFliegerY = 0
    EndIf
    
    FliegerY + BewegFliegerY
    
    If spritewechseltimer < zeit
      spritewechseltimer = zeit + 300
      x + 1
      If x > #Max_Flieger
        x = 1
      EndIf
    EndIf
    DisplayTransparentSprite(x, FliegerX, FliegerY)
    
    If KeyboardPushed(#PB_Key_Space)
      If SchussTimer < zeit
        SchussTimer = zeit + 100
        AddElement(schuss())
        schuss()\x = FliegerX + 200
        schuss()\y = FliegerY + 25
      EndIf
    EndIf
    ForEach schuss()
      schuss()\x + 5
      If schuss()\x > #bildschirmbreite
        DeleteElement(schuss())
      Else
        DisplayTransparentSprite(#schuss, schuss()\x, schuss()\y)
      EndIf
    Next
    
    FlipBuffers()
    wEvent = WindowEvent()
    While wEvent
      Select wEvent
        Case #PB_Event_CloseWindow
          End
      EndSelect
      wEvent = WindowEvent()
    Wend
    
  Until KeyboardPushed(#PB_Key_Escape)
EndProcedure

InitSprite()
InitKeyboard()
If OpenWindow(0, 0, 0, #bildschirmbreite, #bildschirmhoehe, "test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered) = 0
  End
EndIf
OpenWindowedScreen(WindowID(0), 0, 0, #bildschirmbreite, #bildschirmhoehe, 1, 0, 0)
SetFrameRate(75)
Spiel()
PureBasic 4.40 (Windows - x86)
Antworten