![]() |
Space Invaders in Delphi5
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo
wir haben die Aufgabe im Informatikunterricht ein Projekt unserer Wahl zu programmieren. Ein Freund und ich haben uns für einen kleinen Space Invaders - Klon entschieden. (Die Invader sollen einfach nur nach unten kommen und dabei abgeschossen werden, also nicht zurückschießen). Wir sind auch schon recht gut vorangekommen, hängen nun aber am Abschießen der Invader. Die Kollisionsabfrage passt soweit eigentlich, jedoch haben wir ein Problem mit dem "entfernen" des Schusses und der Invader. Um den Schuss löschen zu können, welcher sich bei uns in einem dynamischen Array befindet, dachten wir den gerade betrachteten Schuss zu löschen indem wir alle folgenden Schüsse "eins weiter nach vorn verschieben" (ich hoffe man weiß was gemeint ist ^^). Jedenfalls bringt Delphi uns eine Fehlermeldung. Ich hänge das Projekt einfach mal als Anhang in einer .txt Datei an. (es ist vom Aufbau noch nicht optimal und wird, wenn alles funktioniert noch optimiert) Danke schon einmal ~N4r0 |
Re: Space Invaders in Delphi5
Hallo N4r0,
Willkommen in der DP :dp: Euer Ansatz ist schon richtig. Du hast leider nicht verraten, welche Fehlermeldung angezeigt wird. Ich vermute allerdings mal, sie kommt daher, dass durch die vorwärtslaufende Schleife auf Elemente zugegriffen werden, die nicht mehr vorhanden sind. Versucht mal, die Schleife in Zeile 236 andersherum laufen zu lassen. Sprich:
Delphi-Quellcode:
Eine Sache allerdings noch: Ihr gebt die erzeugten Schuss-Images nirgens frei, was zu einem Memory-Leak führt! Ruft Schuss1[j].Free auf, bevor ihr es aus dem Array entfernt.
for j := High(Schuss1) downto 0 do
... |
Re: Space Invaders in Delphi5
Liste der Anhänge anzeigen (Anzahl: 1)
Hey,
danke für deine schnelle Antwort :) ich hab die Schleife mal abgeändert und vor der Schleife, die den Schuss aus dem Array löschen soll Schuss1[j].Free geschreiben. ich hab nochmal die Fehlermeldung in den Anhang gepackt. (also an sich ne Zugriffsverletzung) |
Re: Space Invaders in Delphi5
Die Richtung stimmte schon.
Delphi-Quellcode:
Außer daß du an der falschen Stelle angefangen hast.
Schuss1[j].Free;
for x:=j to high(Schuss1)-1 do Schuss1[x] := Schuss1[x+1]; SetLength(Schuss1,length(Schuss1)-1); j-1 ist ja der Schuß vor dem zu Löschenden ... du hattest also den Falschen entfernt und wenn j der 1. Schuß ist (j=0), dann hast du den Grund für die Berreichsüberschreitung. |
Re: Space Invaders in Delphi5
Zitat:
|
Re: Space Invaders in Delphi5
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
so siehts jetzt aus:
Delphi-Quellcode:
procedure TForm1.SchussTimerTimer(Sender: TObject);
var j,i,x : integer; collide : boolean; begin collide := false; for j := High(Schuss1) downto 0 do begin for i := 1 to 21 do begin if (kollision(Schuss1[j],i) = true) and (Invader[i].Visible = true) then begin collide := true; Invader[i].visible := false; Schuss1[j].Free; for x:=j to high(Schuss1)-1 do Schuss1[x] := Schuss1[x+1]; SetLength(Schuss1,length(Schuss1)-1); end end; if collide = false then Schuss1[j].top := Schuss1[j].top - 10; end; end; |
Re: Space Invaders in Delphi5
Habe das Projekt mal im Debugger durchgesteppt: Das Problem ist, dass die Schleife, in der die Kollision einer Kugel mit einem Invader geprüft wird, beim Auftreten einer Kollision nicht abgebrochen wird. D.h. wenn die Kugel schon entfernt wurde, wird sie trotzdem noch auf eine Kollision mit den übrigen Invadern geprüft, was zu einer Zugriffsverletzung führt.
Beheben kannst du das, indem du nach dem Entfernen der Kugel aus dem Array die innere Schleife mit dem Befehl break; abbrichst. Es wäre übrigens sinnvoller, wenn du die Variable collide in der äußersten Schleife auf False setzen würdest, statt nur am Anfang der Funktion. |
Re: Space Invaders in Delphi5
Super, danke dir für die schnelle und kompetente Hilfe :D
|
Re: Space Invaders in Delphi5
Hallo ihr,
Ich hätte da ein neues Problem. Undzwar bin ich gerade dabei meine programmierten functions in in neue Klassen, also in andere Units zu packen, um sie aus dem Hauptprogramm zubekommen. Nun versuche ich das die ganze Zeit mit meiner funktion kollision:
Delphi-Quellcode:
Ich scheine die neue Klasse auch richtig in die Unit1 implementiert zu haben, denn mein Programm startet ohne Probleme. function kollision(Schuss : TImage ; i : integer) : boolean; var xposition, yposition: integer; begin kollision := false; xposition := Schuss.left; yposition := Schuss.top; if (xposition >= Invader[i].left) and (xposition <= (Invader[i].left + Invader[i].width)) then begin if (yposition <= (Invader[i].top + Invader[i].height)) and (yposition >= Invader[i].Top) then kollision := true else kollision := false end else kollision := false; end; Jedoch wenn ich versuche einen Schuss auszusenden bekommen ich wieder eine Zugriffsverletzungs-Fehlermeldung und Delphi markiert mir diese Zeile:
Delphi-Quellcode:
Ich nehme also an, dass es damit zu tun hat, dass meine zweite Unit nicht auf die TImages zugreifen kann.
if (xposition >= Invader[i].left) and (xposition <= (Invader[i].left + Invader[i].width)) then
Wie ist es möglich dieses Problem zu beheben? |
Re: Space Invaders in Delphi5
Zitat:
diese Sachen prüfen: - Invader <> nil (bzw. bei einem Array z.B. Length > 0) - (i >= 0) and (i < Length(Invader)) - Invader[i] <> nil - ist Invader[i] wirklich ein gültiges Objekt und nicht bereits an anderer Stelle freigegeben |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:47 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz