Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Schießen meine ich (https://www.delphipraxis.net/160-schiessen-meine-ich.html)

Luckie 15. Jun 2002 08:06


Schießen meine ich
 
Bitte nicht lachen. Ich will mal so mein erstes Spiel programmieren. Und da dachte ich mir, ich schieße einfach mal so ein paar Objekte ab, die auf der Form rumschwirren. Aber so weit bin ich noch lange nicht. Alles was ich bisher geschafft habe, ist einen Schuß abzufeuern. Und das auch nur schlecht als recht.
Es ist gerade mal ein Schuß und dann ist Schluß. Zu allen Übel folgt der Schuß, wenn er abgefeuert wurde noch der Waffe (ein einfaches Label am unterem Fensterrand, welches man hin und her bewegen kann). Ich könnte aus der Kugel eine Rakete machen die man ins Ziel steuern muß, dann paßt es wieder, aber das will ich nicht.

Hier erstmal etwas Code:

Delphi-Quellcode:
procedure TForm1.Shoot(x, y: DWORD);
var
  Shot: TShot;
begin
  Shot.x := x;
  Shot.y := y;
  Form1.Refresh;
  Form1.Canvas.Draw(Shot.x ,Shot.y ,bullet);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
   Shoot(lblGun.Left+(lblGun.Width div 2), ypos);
   Dec(ypos, 5);
end;
Der Schuß wird mit der Leertaste ausgelöst, da wird einfach der Timer gestartet. Das es das nicht ist weiß ich auch. Aber ich komme nicht dahinter wie es gehen könnte. Irgendwie muß ich die Schüsse in einem Array halten und in einer Schleife bewegen und mit dem Timer nur den Takt vorgeben. Aber wie?

Ach so, ich glaube, das Spiel hieß "Asterioids" oder so. So soll dass dann mal aussehen.

Ohne DirectX oder so bitte.

jbg 15. Jun 2002 09:05

Du musst, beim Abfeuern dir die X und Y Koordinaten merken. Danach sind diese dein Ausgangspunkt. Ein Array würde ich dir da vorerst einmal nicht empfehlen, da man nicht weiß, wieviel Schuss abgefeuert werden, und wenn ein Schuss "ausgelebt" hat, dann musst du bei einem Array alle nachfolgenden Schüsse um ein Element nach vorne schieben. Mit einer dynamischen Liste wie TList, ist das kein Problem.

Code:
[color=#000080][i]// AllShoots: TList;[/i][/color]

[b]procedure[/b] TForm1.Fire; [color=#000080][i]// Schuss abgeben[/i][/color]
[b]var[/b]
  p: PPoint;
[b]begin[/b]
  New(p);
  p^.x := lblGun.Left + (lblGun.Width [b]div[/b] 2);
  p^.y := lblGun.Top;
  AllShoots.Add(p); [color=#000080][i]// neuen Schuss zu Liste hinzufügen[/i][/color]
[b]end[/b];

[b]procedure[/b] TForm1.DeleteDeadShoots(DeleteAll: Boolean);
[b]var[/b]
  p: PPoint;
  ii: Integer;
[b]begin[/b]
  [b]for[/b] ii := AllShoots.Count -1 [b]downto[/b] 0 [b]do[/b]
  [b]begin[/b]
    p := PPoint(AllShoots.Items[ii]);
    [b]if[/b] (p^.y < 0) [b]or[/b] (DeleteAll) [b]then[/b]
    [b]begin[/b]
       AllShoots.Delete(i); [color=#000080][i]// deswegen die Schleife rückwärts durchlaufen[/i][/color]
       Dispose(p);
    [b]end[/b];
  [b]end[/b];
[b]end[/b];

[b]procedure[/b] TForm1.Timer1Timer(Sender: TObject);
[b]var[/b]
  p: PPoint;
  ii: Integer;
[b]begin[/b]
  [b]for[/b] ii := 0 [b]to[/b] AllShoots.Count -1 [b]do[/b]
  [b]begin[/b]
    p := PPoint(AllShoots.Items[ii]);
    Shoot(p^.x, p^.y);
    Dec(p^.y, 5);
  [b]end[/b];
  DeleteDeadShoots(False);
[b]end[/b];

[b]procedure[/b] TForm1.FormDestroy...
[b]begin[/b]
  DeleteDeadShoots(True); [color=#000080][i]// speicher freigeben[/i][/color]
[b]end[/b];
by Daniel B; ich habe aus den Variablen i, ein ii gemacht, da sonst die Formatierung nicht funktioniert hätte.

Luckie 15. Jun 2002 09:42

Danke schon. das sieht ja so kompliziert aus, das müßte gehen. Aaaaber...

So will ich jetzt einen Schuß mit deinem Code abfeuern, aber das klappt noch nicht:

Code:
[b]procedure[/b] TForm1.FormKeyDown(Sender: TObject; [b]var[/b] Key: Word;
  Shift: TShiftState);
[b]var[/b]
  p: PPoint;
[b]begin[/b]
  [b]case[/b] Key [b]of[/b]
    VK_LEFT: lblGun.Left := lblGun.Left - 5;
    VK_RIGHT: lblGun.Left := lblGun.Left + 5;
    VK_SPACE:
    [b]begin[/b]
      Fire;
      Timer1.Enabled := TRUE;
    [b]end[/b];
  [b]end[/b];
[b]end[/b];
In der letzten Zeile bekomme ich eine AccessViolation bveim Debuggen.
Zitat:

Code:
[b]procedure[/b] TForm1.Fire; [color=#000080][i]// Schuss abgeben[/i][/color]
[b]var[/b] p: PPoint;
[b]begin[/b]
  New(p);
  p^.x := lblGun.Left + (lblGun.Width [b]div[/b] 2);
  p^.y := lblGun.Top;
  AllShoots.Add(p); [color=#000080][i]// neuen Schuss zu Liste hinzufügen <-- HIER[/i][/color]
[b]end[/b];

Aber wie ist das, wenn ich so:
Zitat:

Code:
[b]procedure[/b] TForm1.Shoot(x, y: DWORD);
[b]var[/b]
  Shot: TShot;
[b]begin[/b]
  Shot.x := x;
  Shot.y := y;
  Form1.Refresh;
  Form1.Canvas.Draw(Shot.x, Shot.y, bullet);
[b]end[/b];

schiesse, dann werden ja jedes mal alle Schüsse gelöscht.

jbg 15. Jun 2002 10:02

Du musst die TList AllShoots erst im OnCreate Ereignis erzeugen (AllShoots := TList.Create) und im OnDestroy Ereignis über AllShoots.Free (nach dem Aufruf von DeleteDeadShoots) wieder freigeben.

Damit nicht bei jedem Zeichnen eines Schusses, alle anderen gelöscht werden, musst du den Aufruf von Form1.Refresh aus der Funktion Shoot in das OnTimer-Ereignis (vor die Schliefe) verschieben.

Luckie 15. Jun 2002 10:08

*PATSCH* :oops:

guggly 17. Feb 2015 04:13

AW: Schießen meine ich
 
ich schreibe gerade an einem Funktionszeichner (hat man vileicht aus meinen früheren Fragen sehen können). Der hat bis jetzt nur einen SChönheitsfehler: Ich zeichne die ganzen Parablen in ein TPaintBox. Nur sieht man da die Pixel sehr schnell. Ich habe so das Gefühl, das die nicht so Detailreich ist.

himitsu 17. Feb 2015 07:44

AW: Schießen meine ich
 
Hi Spambot

Quelle: http://www.delphipraxis.net/297-genaue-tpaintbox.html



Die "bunten" Delphi-Codes kann man doch bestimmt nicht mehr reparieren?


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz