Einzelnen Beitrag anzeigen

.chicken

Registriert seit: 5. Dez 2006
459 Beiträge
 
#1

Vernünftige Animationskontrolle

  Alt 25. Mai 2008, 15:29
Hi, ich wollte mal fragen wie man Animationen sinnvoll steuert. Also für meine 2D-Engine habe ich eine T2DXAnimatedSpriteEx-Klasse gebastelt.
Man kann ihr eine Textur zuordnen, gibt dann Framezahl, Reihen und Spalten an und kann dann über die Frame-Property die verschiedenen Frames animieren.
Außerdem kann man verschiedene FrameSets erstellen, sodass beim Animieren nur Frames von zB 5-10 benutzt werden. Das ganze geht auch rückwärts von 10-5. Außerdem kann man angeben ob das FrameSet wiederholt oder nur einmal abgespielt werden soll.

Wenn ich jetzt damit aber ein Raumschiff animieren will, dann wird die Kontrolle schon relativ kompliziert, denn ich möchte dass die Animationen erst zuende ablaufen bevor neue begonnen werden.
Hier mal ein Code-Ausschnitt:
Delphi-Quellcode:
procedure TForm1.ControlShip(_TimeKey: Single);
begin
  if (GetAsyncKeyState(VK_LEFT) < 0) then
  begin
    Ship.Position := Get2DXVector2(Ship.Position.X - _TimeKey / 3, Ship.Position.Y);
    if Ship.FrameSet.ID = 'Flyingthen //'Flying' ist das Standard-Framset, dass das Schiff unanimiert zeigt
      Ship.ActivateFrameSet('MoveL', True) //naja 'MoveL' = Linksbewegung
    else
    if Ship.FrameSet.ID = 'MoveRthen
      Ship.ActivateFrameSet('MoveRB', True) //'MoveRB' = Rechtsbewegung rückwärts, um das Schiff in Ausgangslage zurueckzubringen
    else
    if Ship.FrameSet.ID = 'MoveLBthen
      Ship.ActivateFrameSet('MoveL', False)
    else
    if (Ship.FrameSet.ID = 'MoveRB') AND (Ship.Frame = Ship.FrameSet.AnimationStop) then
      Ship.ActivateFrameSet('MoveL', True);
  end
  else
  if (GetAsyncKeyState(VK_RIGHT) < 0) then
  begin
    Ship.Position := Get2DXVector2(Ship.Position.X + _TimeKey / 3, Ship.Position.Y);
    if Ship.FrameSet.ID = 'Flyingthen
      Ship.ActivateFrameSet('MoveR', True)
    else
    if Ship.FrameSet.ID = 'MoveLthen
      Ship.ActivateFrameSet('MoveLB', True)
    else
    if Ship.FrameSet.ID = 'MoveRBthen
      Ship.ActivateFrameSet('MoveR', False)
    else
    if (Ship.FrameSet.ID = 'MoveLB') AND (Ship.Frame = Ship.FrameSet.AnimationStop) then
      Ship.ActivateFrameSet('MoveR', True);
  end
  else
  begin
    if Ship.FrameSet.ID = 'MoveLthen
      Ship.ActivateFrameSet('MoveLB')
    else
    if Ship.FrameSet.ID = 'MoveRthen
      Ship.ActivateFrameSet('MoveRB')
    else
    if Ship.Frame = Ship.FrameSet.AnimationStop then
      Ship.ActivateFrameSet('Flying', True);
  end;
  Ship.Animate(_TimeKey);
end;
Der Code bewirkt lediglich, dass das Raumschiff, wenn es nach links bewegt wird, leicht in die Schräglage animiert wird, nach rechts genauso. Wenn man die Tasten dann los lässt, wird erst wieder in die Ausgangs-Position zurückbewegt, bevor eine neue Animation angefangen werden kann.

Die Boolschen Parameter in der ActivateFrameSet-Prozedur legen fest, ob das Frame auf AnimationStart gesetzt wird.

Ich hoffe ihr versteht ungefähr wie der Code funktioniert. Mein Problem ist: Das ist doch viel zu kompliziert oder?
Wenn ich jetzt noch eine einfache Komplettrotation hinzufügen möchte, dann wird das ganze nochmal viel komplizierter, um zu verhindern dass falsche Animationsketten entstehen.

Wie regelt man sowas? Liegt der Fehler in meiner Sprite-Klasse? Sollte man sowas anders organisieren?
Wenn ihr mehr Code braucht, sagt Bescheid, aber mir reicht es schon, wenn ihr mir erklärt wie man so Animationen gut verwalten kann.

Grüße, .ch!cken
  Mit Zitat antworten Zitat