Space Invaders
-
- Beiträge: 10
- Registriert: Do 5. Okt 2017, 18:05
Space Invaders
Hallo,
ich habe ein Problem bei meinem Space Invaders Clon.
Alles funktioniert, bis darauf, dass die Schüsse der Gegner nicht richtig erkennen, ob das eigene Raumschiff getroffen wird.
Der dafür wichtige Code ist Zeile 167-231.
Bitte um Hilfe, was ich falsch gemacht hab.
Prinzip. linker Punkt des Schusses muss kleiner vom x wert sein als linker Punkt des Raumschiffes. Dementsprechend rechter Punkt des Schusses muss größer sein, als rechter Punkt des Raumschiffes und es muss auf der passenden Höhe liegen. Andersrum bei dem abschießen der Aliens hat es nach dem Prinzip geklappt.
(alles an Quelltext in unit 1.)
https://www.file-upload.net/download-12 ... s.rar.html
ich habe ein Problem bei meinem Space Invaders Clon.
Alles funktioniert, bis darauf, dass die Schüsse der Gegner nicht richtig erkennen, ob das eigene Raumschiff getroffen wird.
Der dafür wichtige Code ist Zeile 167-231.
Bitte um Hilfe, was ich falsch gemacht hab.
Prinzip. linker Punkt des Schusses muss kleiner vom x wert sein als linker Punkt des Raumschiffes. Dementsprechend rechter Punkt des Schusses muss größer sein, als rechter Punkt des Raumschiffes und es muss auf der passenden Höhe liegen. Andersrum bei dem abschießen der Aliens hat es nach dem Prinzip geklappt.
(alles an Quelltext in unit 1.)
https://www.file-upload.net/download-12 ... s.rar.html
Re: Space Invaders
Wirklich? Ich weiß zwar nicht, was hier genau passieren soll, aber wenn der Schuss das Raumschiff treffen soll, dann muss die linke Koordinate des Geschosses größer sein als der linke Punkt des Raumschiffes und die rechte kleiner, also in Pseudocode:LazarusPleb hat geschrieben:Hallo,
linker Punkt des Schusses muss kleiner vom x wert sein als linker Punkt des Raumschiffes. Dementsprechend rechter Punkt des Schusses muss größer sein, als rechter Punkt des Raumschiffes und es muss auf der passenden Höhe liegen.
Code: Alles auswählen
(Geschoss.x > Raumschiff.Left) and (Geschoss.x < Raumschiff.Right)
-
- Beiträge: 10
- Registriert: Do 5. Okt 2017, 18:05
Re: Space Invaders
Ersteinam vielen Dank für die schnelle Antwort, auch wenn ich den Sinn bei dir nicht wirkliche erkenne, habe ich es mal ausprobiert Funktioniert hat es nicht.wp_xyz hat geschrieben:Wirklich? Ich weiß zwar nicht, was hier genau passieren soll, aber wenn der Schuss das Raumschiff treffen soll, dann muss die linke Koordinate des Geschosses größer sein als der linke Punkt des Raumschiffes und die rechte kleiner, also in Pseudocode:LazarusPleb hat geschrieben:Hallo,
linker Punkt des Schusses muss kleiner vom x wert sein als linker Punkt des Raumschiffes. Dementsprechend rechter Punkt des Schusses muss größer sein, als rechter Punkt des Raumschiffes und es muss auf der passenden Höhe liegen.
Und wenn Streifschüsse erlaubt sind, dann muss das "<" durch ein "<=" ersetzt werden, genauso beim ">".Code: Alles auswählen
(Geschoss.x > Raumschiff.Left) and (Geschoss.x < Raumschiff.Right)
https://imgur.com/a/QuDan
So habe ich mir das vorgestellt. Wo ist der Denkfehler?
-
- Beiträge: 6900
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Space Invaders
Es betrifft nicht deine Frage, aber ich gebe dir einen Tip, das dein Code übersichtlicher wird.
Wieso verwendest du in OpenGL nicht glTranslatef ?
Sieht doch recht aufgeräumt aus ?
Somit findest du auch viel schneller einen Fehler.
Von Arrays würde ich auch Gebrauch machen, zB.
Somit kannst du deine Abfrage bei Timer2Timer sehr elegant lösen.
Somit könntest so etwas auch in eine for-to-Schleife packen und sparst somit etliche Zeilen Code.
Die gegner?farbe müsste dann auch in eine Array.
Auch in den Zeilen wo sich dein Fehler befindet, wäre eine Schleife angebracht, dann müsstest du nur einmal korrigieren, anstelle von 5mal.
Ich hoffe das ich dir mit diesen Tips helfen kann.
PS:Wen du willst kann ich die noch sagen, wie du die Steuerung deines Raumschiffes elegant lösen kannst, ohne das sich die Tastaturwiederholung bemerkbar macht.

Wieso verwendest du in OpenGL nicht glTranslatef ?
Code: Alles auswählen
glPushMatrix; //Gegner1
glTranslatef(-0.8 + gegnerrechts1, 0.9 - gegnerunten, 0.0);
glbegin(gl_QUADS);
glcolor3f(1 + gegner1farbe, 0.0, 0.0);
glvertex3f(-0.0, -0.05, 0.0);
glvertex3f(-0.1, -0.05, 0.0);
glvertex3f(-0.1, 0.0, 0.0);
glvertex3f(-0.0, 0.0, 0.0);
glend;
glPopMatrix;
Somit findest du auch viel schneller einen Fehler.

Von Arrays würde ich auch Gebrauch machen, zB.
Code: Alles auswählen
var
schusstart: array[10..14] of Real
Code: Alles auswählen
for i := 10 to 14 do begin
if schussstart[i] = 15 then begin
gegnerschussoben := gegnerschussoben - 0.01;
end;
end;
Die gegner?farbe müsste dann auch in eine Array.
Code: Alles auswählen
if (schussoben - 0.85 > 0.9 - gegnerunten) and (gegnerrechts1 - 0.9 < schusslinks + 0.01) and (gegnerrechts1 - 0.8 > schusslinks - 0.01) then
//Wird überprüft, ob Raumschiff 1 getroffen wird
begin
gegner1farbe := -1;
//Raumschiff wird gelöscht, indem es schwarz wird
Schussoben := 0;
//Variablen des Schuss werden für den nächsten Schuss zurückgesetzt
Schussstart := 0;
end;
Ich hoffe das ich dir mit diesen Tips helfen kann.
PS:Wen du willst kann ich die noch sagen, wie du die Steuerung deines Raumschiffes elegant lösen kannst, ohne das sich die Tastaturwiederholung bemerkbar macht.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- Beiträge: 10
- Registriert: Do 5. Okt 2017, 18:05
Re: Space Invaders
Ich habe das Programm, indem ich es so gemacht habe, wie du es sagst, hochgeladen:LazarusPleb hat geschrieben:Ersteinam vielen Dank für die schnelle Antwort, auch wenn ich den Sinn bei dir nicht wirkliche erkenne, habe ich es mal ausprobiert Funktioniert hat es nicht.wp_xyz hat geschrieben:Wirklich? Ich weiß zwar nicht, was hier genau passieren soll, aber wenn der Schuss das Raumschiff treffen soll, dann muss die linke Koordinate des Geschosses größer sein als der linke Punkt des Raumschiffes und die rechte kleiner, also in Pseudocode:LazarusPleb hat geschrieben:Hallo,
linker Punkt des Schusses muss kleiner vom x wert sein als linker Punkt des Raumschiffes. Dementsprechend rechter Punkt des Schusses muss größer sein, als rechter Punkt des Raumschiffes und es muss auf der passenden Höhe liegen.
Und wenn Streifschüsse erlaubt sind, dann muss das "<" durch ein "<=" ersetzt werden, genauso beim ">".Code: Alles auswählen
(Geschoss.x > Raumschiff.Left) and (Geschoss.x < Raumschiff.Right)
https://imgur.com/a/QuDan
So habe ich mir das vorgestellt. Wo ist der Denkfehler?
https://www.file-upload.net/download-12 ... s.zip.html
-
- Beiträge: 724
- Registriert: Do 27. Sep 2012, 00:07
- OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
- CPU-Target: x86_64-win64
- Wohnort: Hamburg
Re: Space Invaders
Wenn ich deine Zeichnung von https://imgur.com/a/QuDan anschaue, dann ist die Kollisionsabfrage einfach. Bei Schuss.X2<Schiff.X1 oder Schuss.X1>Schiff.X2 findet nie ein Kollision statt, dann musste man das etwa so umsetzen (y1 ist oben und y2 ist unten)
Code: Alles auswählen
if not ((Schuss.X2<Schiff.X1) or (Schuss.X1>Schiff.X2)) then begin // treffer bei x
if not ((Schuss.Y2<Schiff.Y1) or (Schuss.Y1>Schiff.Y2)) then begin // treffer bei Y
//getroffen
end;
end;
-
- Beiträge: 10
- Registriert: Do 5. Okt 2017, 18:05
Re: Space Invaders
So hab ich das auch gemacht. Nur das statt dem or ein and ist.(Es muss ja innerhalb der Grenzen sein.)Soner hat geschrieben:Wenn ich deine Zeichnung von https://imgur.com/a/QuDan anschaue, dann ist die Kollisionsabfrage einfach. Bei Schuss.X2<Schiff.X1 oder Schuss.X1>Schiff.X2 findet nie ein Kollision statt, dann musste man das etwa so umsetzen (y1 ist oben und y2 ist unten)Code: Alles auswählen
if not ((Schuss.X2<Schiff.X1) or (Schuss.X1>Schiff.X2)) then begin // treffer bei x if not ((Schuss.Y2<Schiff.Y1) or (Schuss.Y1>Schiff.Y2)) then begin // treffer bei Y //getroffen end; end;
-
- Beiträge: 724
- Registriert: Do 27. Sep 2012, 00:07
- OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
- CPU-Target: x86_64-win64
- Wohnort: Hamburg
Re: Space Invaders
Mit dem AND-Verknüpfung muss ganze Schuß im Schiff sein, sonst wird es nicht als Treffer gezahlt. Bei mein Abfrage reicht eine Berührung von irgeneine Seite. Ich prüfe ob es Nichttreffer und verneine das ganze.
Mein Vorgehensweise kannst du für viele Kollisionsabfragen verwenden. Es ist meistens einfacher Nichttreffer zu prüfen. z.B wenn (Schuss.X2<Schiff.X1) ist, dann ist es nicht Treffer und man braucht nicht mehr zu prüfen.
Mein Vorgehensweise kannst du für viele Kollisionsabfragen verwenden. Es ist meistens einfacher Nichttreffer zu prüfen. z.B wenn (Schuss.X2<Schiff.X1) ist, dann ist es nicht Treffer und man braucht nicht mehr zu prüfen.
Re: Space Invaders
Blödsinn - so wie es Soner macht, ist es genau richtig. (Leider kann ich meinen Beitrag hier nicht mehr löschen...)
[EDIT]
Um diesem Beitrag doch noch einen Sinn zu geben, man kann auch sagen: Das Schiff ist getroffen, wenn sich mindestens ein Eckpunkt des Geschosses im Schiff befindet:
Code: Alles auswählen
type
TFigur = record
x1, y1, x2, y2: Integer;
end;
function PktinFigur(x,y: Integer; AFigur: TFigur): Boolean;
begin
Result := (x >= AFigur.x1) and (x <= AFigur.x2) and (y >= AFigur.y1) and (y <= AFigur.y2);
end;
function Treffer(Schuss, Schiff: TFigur): Boolean;
begin
Result := PktInFigur(Schuss.x1, Schuss.y1, Schiff) or
PktInFigur(Schuss.x2, Schuss.y1, Schiff) or
PktInFigur(Schuss.x1, Schuss.y2, Schiff) or
PktInFigur(Schuss.x2, Schuss.y2, Schiff);
end;
-
- Beiträge: 6900
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Space Invaders
Etwas muss da noch berücksichtigt werden. Wen das Geschoss zu schnell ist und die FPS zu klein, dann kann es passieren, das das Geschoss durchfliegt, ohne das es zur Kollision kommt. Das war bei ersten NFS der Fall, wen man da mit dem Auto eine sehr hohe Geschwindigkeit hatte, fuhr man ab und zu durch den Gegenverkehr, ohne das es eine Kollision gab.Das Schiff ist getroffen, wenn sich mindestens ein Eckpunkt des Geschosses im Schiff befindet:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot