Space Invaders

Für Fragen von Einsteigern und Programmieranfängern...

Space Invaders

Beitragvon LazarusPleb » 30. Nov 2017, 16:24 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

[url][/url]
LazarusPleb
 
Beiträge: 10
Registriert: 5. Okt 2017, 17:05

Beitragvon wp_xyz » 30. Nov 2017, 16:32 Re: Space Invaders

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.

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:

Code: Alles auswählen
 (Geschoss.x > Raumschiff.Left) and (Geschoss.x < Raumschiff.Right)

Und wenn Streifschüsse erlaubt sind, dann muss das "<" durch ein "<=" ersetzt werden, genauso beim ">".
wp_xyz
 
Beiträge: 2533
Registriert: 8. Apr 2011, 08:01

Beitragvon LazarusPleb » 30. Nov 2017, 18:25 Re: Space Invaders

wp_xyz hat geschrieben:
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.

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:

Code: Alles auswählen
 (Geschoss.x > Raumschiff.Left) and (Geschoss.x < Raumschiff.Right)

Und wenn Streifschüsse erlaubt sind, dann muss das "<" durch ein "<=" ersetzt werden, genauso beim ">".


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.
https://imgur.com/a/QuDan
So habe ich mir das vorgestellt. Wo ist der Denkfehler?
LazarusPleb
 
Beiträge: 10
Registriert: 5. Okt 2017, 17:05

Beitragvon Mathias » 30. Nov 2017, 18:27 Re: Space Invaders

Es betrifft nicht deine Frage, aber ich gebe dir einen Tip, das dein Code übersichtlicher wird. :wink:
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;

Sieht doch recht aufgeräumt aus ?
Somit findest du auch viel schneller einen Fehler. :wink:

Von Arrays würde ich auch Gebrauch machen, zB.
Code: Alles auswählen
var 
  schusstart: array[10..14] of Real

Somit kannst du deine Abfrage bei Timer2Timer sehr elegant lösen.
Code: Alles auswählen
  for i := 10 to 14 do begin
    if schussstart[i] = 15 then begin
      gegnerschussoben := gegnerschussoben - 0.01;
    end;
  end;


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.
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;


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.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3993
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

Beitragvon LazarusPleb » 30. Nov 2017, 18:52 Re: Space Invaders

LazarusPleb hat geschrieben:
wp_xyz hat geschrieben:
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.

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:

Code: Alles auswählen
 (Geschoss.x > Raumschiff.Left) and (Geschoss.x < Raumschiff.Right)

Und wenn Streifschüsse erlaubt sind, dann muss das "<" durch ein "<=" ersetzt werden, genauso beim ">".


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.
https://imgur.com/a/QuDan
So habe ich mir das vorgestellt. Wo ist der Denkfehler?


Ich habe das Programm, indem ich es so gemacht habe, wie du es sagst, hochgeladen:
https://www.file-upload.net/download-12842445/Versuch_SpaceInvaders.zip.html
LazarusPleb
 
Beiträge: 10
Registriert: 5. Okt 2017, 17:05

Beitragvon Soner » 30. Nov 2017, 21:34 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;
 
Soner
 
Beiträge: 411
Registriert: 26. Sep 2012, 23:07
Wohnort: Hamburg
OS, Lazarus, FPC: Win7Pro-32Bit, Immer letzte Lazarus Release mit SVN-Fixes | 
CPU-Target: 32Bit
Nach oben

Beitragvon LazarusPleb » 30. Nov 2017, 22:13 Re: Space Invaders

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;
 


So hab ich das auch gemacht. Nur das statt dem or ein and ist.(Es muss ja innerhalb der Grenzen sein.)
LazarusPleb
 
Beiträge: 10
Registriert: 5. Okt 2017, 17:05

Beitragvon Soner » 30. Nov 2017, 22:25 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.
Soner
 
Beiträge: 411
Registriert: 26. Sep 2012, 23:07
Wohnort: Hamburg
OS, Lazarus, FPC: Win7Pro-32Bit, Immer letzte Lazarus Release mit SVN-Fixes | 
CPU-Target: 32Bit
Nach oben

Beitragvon wp_xyz » 1. Dez 2017, 00:31 Re: Space Invaders

Ich würde das nicht mit NOT formulieren, da dreht sich einem ja der Kopf um, vor allem wenn man die boole'schen Gesetze nicht kennt: NOT (A AND B) = (NOT A) OR (NOT B).

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
wp_xyz
 
Beiträge: 2533
Registriert: 8. Apr 2011, 08:01

Beitragvon Mathias » 1. Dez 2017, 18:10 Re: Space Invaders

Das Schiff ist getroffen, wenn sich mindestens ein Eckpunkt des Geschosses im Schiff befindet:

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.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot
Mathias
 
Beiträge: 3993
Registriert: 2. Jan 2014, 17:21
Wohnort: Schweiz
OS, Lazarus, FPC: Linux (die neusten Trunc) | 
CPU-Target: 64Bit
Nach oben

• Themenende •

Zurück zu Einsteigerfragen



Wer ist online?

Mitglieder in diesem Forum: Google [Bot] und 1 Gast

porpoises-institution
accuracy-worried