Einzelnen Beitrag anzeigen

Plastewolf
(Gast)

n/a Beiträge
 
#1

kleines Spiel auf dem Form "rendern"

  Alt 6. Apr 2014, 12:49
Hallo miteinander,

Ich hatte gestern Abend spontan den Einfall mal ein kleines Jump 'n' Run-Spiel zu basteln.
Ich habe noch ein paar alte Sprites auf dem PC liegen gehabt welche alle im PNG Format vorliegen und zusammen geradeeinmal 50KB groß sind. Der Plan war diese später über das RC File direkt in die EXE zu binden.

Ich hatte das ganze zuerst auf einem leeren Form (mit Doublebuffer), einer TImage und dem OnKeyDown-Event vesucht. Mit einem Timer und einer Case-Of Schleife habe ich dann die Animationen nachgeschoben. Das ganze hat zwar funktioniert, aber so richtig Toll war das natürlich nicht. Ein alter Beitrag von dem User dominikkv hat mich dann auf die richtige Spur gebracht. Das Programm läuft zwar jetzt viel flüssiger aber die Optimallösung ist das natürlich auch nicht.

Bei der Bewegung fängt das Image natürlich trotz DoubleBuffer an ein wenig zu flackern. In der Theory wollte ich das Problem später über eine Paintbox mit Stream lösen. Das Problem hierbei ist jedoch das ich scheinbar meine PNG Datein nicht ohne weiteres auf diese Weise einlesen kann. Diese ganze Timer Geschichte ist allerdings auch nicht unbedingt das gelbe vom Ei da die Animationen nicht nur ein paar MS nachhängen wenn ich eine Taste drücke sondern sich auch teilweise Überlappen wenn ich z.b. W und D gleichzeitig drücke (Hab leider noch nicht so recht raus gefunden wie ich das am besten umgehe). Kann man eigentlich direkt die Grafiken im Speicher behalten? Dieses ständige LoadFromFile ist sicherlich auch nicht unbedingt sehr Ressourcenfreundlich.

(Achja, gehört zwar nicht unbedingt zu der eigentlichen Frage, aber hat jemand eine Idee wie man das Problem mit dem Springen lösen könnte? Ich dachte zuerst den Timer mit Case-Of durchlaufen zu lassen und dann immer das Top um 10 hochzuzählen bis die Maximalhöhe erreicht ist und dann danach wieder um 10 pro Durchlauf abzusenken bis man auf ein Hindernis trifft (Wand, Boden, Kiste etc.). Wollte das erst mit einer permanenten Gravity machen aber ich hab noch nicht so richtig raus gefunden wie das Funktioniert).

Ich hatte im Internet auch schonmal nach einigen Engines geschaut und dabei GLScene und Andorra2D gefunden. Bei beiden bin ich bereits an der Installation gescheitert


Ich poste hier mal einen Auszug aus dem Code wie ich ihn mir bisher zusammengesetzt habe:
Der Code selbst Funktioniert wenn auch ein wenig Suboptimal.

Delphi-Quellcode:
  const
  Speed = 3;
  AnimSpeed = 175;
  Pfad = '.\Debug\Win32\Graphic';

procedure TForm1.FormCreate(Sender: TObject);
begin
  TMoveR := TTimer.Create(self);
  TMoveR.Interval := AnimSpeed;
  TMoveR.OnTimer := TMoveREvent;
  TMoveR.Enabled := false;

  TMoveL := TTimer.Create(self);
  TMoveL.Interval := AnimSpeed;
  TMoveL.OnTimer := TMoveLEvent;
  TMoveL.Enabled := false;

  TMoveJ := TTimer.Create(self);
  TMoveJ.Interval := AnimSpeed;
  TMoveJ.OnTimer := TMoveJEvent;
  TMoveJ.Enabled := false;

  TMoveD := TTimer.Create(self);
  TMoveD.Interval := AnimSpeed;
  TMoveD.OnTimer := TMoveDEvent;
  TMoveD.Enabled := false;
end;

procedure TForm1.TMoveREvent(Sender: TObject);
begin
  Case MoveR of
    0: Player1.Picture.LoadFromFile(Pfad+'move1R.png');
    1: Player1.Picture.LoadFromFile(Pfad+'move2R.png');
    2: Player1.Picture.LoadFromFile(Pfad+'move3R.png');
    3: Player1.Picture.LoadFromFile(Pfad+'move2R.png');
  end;
  MoveR := MoveR+1;
  if MoveR > 3 then MoveR := 0;
  TMoveR.Enabled := False;
end;


procedure TForm1.TMoveLEvent(Sender: TObject);
begin
  Case MoveL of
    0: Player1.Picture.LoadFromFile(Pfad+'move1L.png');
    1: Player1.Picture.LoadFromFile(Pfad+'move2L.png');
    2: Player1.Picture.LoadFromFile(Pfad+'move3L.png');
    3: Player1.Picture.LoadFromFile(Pfad+'move2L.png');
  end;
  MoveL := MoveL+1;
  if MoveL > 3 then MoveL := 0;
  TMoveL.Enabled := False;
end;


procedure TForm1.TMoveJEvent(Sender: TObject);
begin
  Player1.Picture.LoadFromFile(Pfad+'jump.png');
  TMoveJ.Enabled := False;
end;


procedure TForm1.TMoveDEvent(Sender: TObject);
begin
  if Direction = 0 then Player1.Picture.LoadFromFile(Pfad+'duckR.png')
  Else Player1.Picture.LoadFromFile(Pfad+'duckL.png');
  TMoveD.Enabled := False;
end;






procedure TForm1.Timer1Timer(Sender: TObject);
var
  SpeedX, SpeedY: Integer;
begin
  Caption := TimeToStr(Time);
  SpeedX := 0;
  SpeedY := 0;

  if GetAsyncKeyState(VkKeyScan('d')) <> 0 then
    begin
      TMoveR.Enabled := True;
      Inc(SpeedX, Speed);
      Direction := 0;
    end;

  if GetAsyncKeyState(VkKeyScan('a')) <> 0 then
    begin
      TMoveL.Enabled := True;
      Dec(SpeedX, Speed);
      Direction := 1;
    end;


  if GetAsyncKeyState(VkKeyScan('s')) <> 0 then
    begin
      TMoveD.Enabled := true;
      //Inc(SpeedY, Speed);
    end;


  if GetAsyncKeyState(VkKeyScan('w')) <> 0 then
    begin
      TMoveJ.Enabled := true;
      Dec(SpeedY, Speed);
    end;

  Player1.Left := Player1.Left + SpeedX;
  Player1.Top := Player1.Top + SpeedY;

  If (GetAsyncKeyState(VkKeyScan('w')) = 0) AND (GetAsyncKeyState(VkKeyScan('a')) = 0) AND (GetAsyncKeyState(VkKeyScan('s')) = 0) AND (GetAsyncKeyState(VkKeyScan('d')) = 0) then
    begin
      If Direction = 0 then Player1.Picture.LoadFromFile(Pfad+'standR.png')
      Else Player1.Picture.LoadFromFile(Pfad+'standL.png');
    end;
end;

end.

MoveR = Rechts bewegen
MoveL = Links bewegen
MoveJ = Springen
MoveD = Ducken


Wie würdet Ihr das Problem lösen? Habt Ihr vielleicht eine Idee für mich?

Geändert von Plastewolf ( 6. Apr 2014 um 12:51 Uhr)
  Mit Zitat antworten Zitat