AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Collisionsabfrage

Ein Thema von Luckie · begonnen am 16. Jun 2002 · letzter Beitrag vom 16. Jun 2002
Antwort Antwort
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

Collisionsabfrage

  Alt 16. Jun 2002, 08:58
So Gegner habe ich auch schon - zu mindest einen .

Zum Schiessen verwende ich jbg's Code und um zu prüfen, ob ich ihn getroffen habe, verwende ich folgenden Code in einem Timer:

Code:
[b]procedure[/b] TForm1.tmrDefenderHittingTimer(Sender: TObject);
[b]var[/b]
  ii: DWORD;
  p: PPoint;
[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]);
    [b]if[/b] (p^.x > Image2.Left)
      [b]and[/b] (p^.x < Image2.Left + Image2.Width)
      [b]and[/b] (p^.y < Image2.Top)
      [b]then[/b]
    [b]begin[/b]
      Image2.Picture.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'expl1.bmp');
      bHit := TRUE;
      tmrDefenderHitting.Enabled := FALSE;
    [b]end[/b];
  [b]end[/b];
[b]end[/b];
In einem anderen Timer wird bHit geprüft und wenn das TRUE ist der Gegner wieder neu positioniert und der Collisions-Timer neu gestartet und alles geht von vorne los.

Nun mein Problem:
Wenn ich den Gegner einmal getroffen habe und schon mehr mals geschossen habe, explodiert er von alleine mehr mals. Ich habe so das dumpfe Gefühl, dass nach dem der Gegner neu gestartet wurde, noch Schüsse in der Liste sind, die dann auch noch die Bedingung erfüllen.

Löschen der Liste:

Code:
[b]procedure[/b] TForm1.DeleteDeadShoots(DeleteAll: Boolean);
[b]var[/b]
  p, penemy: 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]
     Fire; [color=#000080][i]// deswegen die Schleife rückwärts durchlaufen[/i][/color]
     Dispose(p);
    [b]end[/b];
  [b]end[/b];

  [b]for[/b] ii := AllShootsEnemy.Count - 1 [b]downto[/b] 0 [b]do[/b]
  [b]begin[/b]
    penemy := PPoint(AllShootsEnemy.Items[ii]);
    [b]if[/b] (penemy^.y > Width) [b]or[/b] (DeleteAll) [b]then[/b]
    [b]begin[/b]
     FireEnemy; [color=#000080][i]// deswegen die Schleife rückwärts durchlaufen[/i][/color]
     Dispose(penemy);
    [b]end[/b];
  [b]end[/b];
[b]end[/b];
Rufe ich das aber nach einem Treffer auf, bekomme ich eine Zugriffsverletzung.

by Daniel B; ich habe mir erlaubt aus den Variablen i ein ii zu machen, da sonst die Formatierung nicht funktioniert hätte.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#2
  Alt 16. Jun 2002, 10:57
Dein Code:

Code:
    [b]if[/b] (p^.x > Image2.Left)
      [b]and[/b] (p^.x < Image2.Left + Image2.Width)
      [b]and[/b] (p^.y < Image2.Top)
Das ist wohl die eigentliche Kollisionsabfrage. Nun, wenn du abfragst, ob x zwischen Left und Left + Width liegt, musst du auch abfragen, ob y zwischen Top und Top + Height liegt. Weil so wird auch ein Schuss ein Treffer sein, der unterhalb des Zielobjekts liegt.

Setzt du bHit nach der Abfrage auch wieder auf false?

Und musst du beim Löschen der Schüsse nicht zum einen den Schuss selbst löschen (machst du ja mit Dispose()), als auch den Eintrag in der TList (TList.Delete())? Steht auch in dem anderen Thread drin, aber im hier geposteten Code nicht...

Mir ist außerdem folgende Zeile unklar:

Code:
[b]if[/b] (penemy^.y > Width) [b]or[/b] (DeleteAll) [b]then[/b]
Warum soll y größer als Width sein?
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3
  Alt 16. Jun 2002, 17:15
Danke werde ich mir mal ankucken.

bHit setze ich wieder uaf TRUE und zur Information, falls es wichtig ist: Der Schuß von mir geht von unten nach oben und der des Gegner von oben nach unten, deswegen muß er gelöscht werden, wenn er größer der Höhe des Formulars wird.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.478 Beiträge
 
Delphi 10.1 Berlin Professional
 
#4

Re: Collisionsabfrage

  Alt 16. Jun 2002, 17:33
Zitat von Luckie:
Code:
    [b]if[/b] (p^.y < 0) [b]or[/b] (DeleteAll) [b]then[/b]
    [b]begin[/b]
       Fire; [color=#000080][i]// deswegen die Schleife rückwärts durchlaufen[/i][/color]
       Dispose(p);
    [b]end[/b];
  [b]end[/b];
Das sah doch bei mir anders aus. Anstatt Fire gehört da doch FAllShoots.Delete(i) hin. Mit Fire erzeugst du einen neuen Schuss, aber an dieser Stelle soll der Schuss aus FAllShoots entfernt werden. Das Kommentar kannst du entfernen und die Schleife wieder vorwärts laufen lassen, da du FAllShoots.Delete nicht aufrufts. Übrigens führt der Code zu einer Schutzverletzung, da der Speicherbereich für die Koordinaten zwar freigegen wird, aber eben nicht der Eintrag entfernt wird.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#5
  Alt 16. Jun 2002, 17:38
Sah das echt anders aus? Ehrlich gesagt habe ich mich die ganze Zeit gewundert warum da Fire steht .
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
OregonGhost

Registriert seit: 8. Jun 2002
Ort: Lübeck
1.216 Beiträge
 
Delphi 3 Professional
 
#6
  Alt 16. Jun 2002, 17:42
Wenn du y mit der Breite vergleichst, wird er aber nicht gelöscht, wenn y größer als die Höhe des Formulars ist, sondern erst, wenn es größer als die Breite ist ;c)
Oregon Ghost
---
Wenn NULL besonders groß ist, ist es fast schon wie ein bisschen eins.
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.478 Beiträge
 
Delphi 10.1 Berlin Professional
 
#7
  Alt 16. Jun 2002, 17:48
Zitat:
Code:
Image2.Picture.LoadFromFile(ExtractFilePath(ParamStr(0)) + 'expl1.bmp');
Ich würde das expl1.bmp einmalig in ein TBitmap einlesen und dann nur noch Image2.Picture.Assign(BitmapExpl1);
schreiben. Diese Vorgehensweise ist um einiges schneller, da das Bild nicht jedesmal von der im Verhältinis zum Arbeitsspeicher langsamen Festplatte geladen werden muss.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie
(Moderator)

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#8
  Alt 16. Jun 2002, 17:52
Danke Jungs so klatt es.

@jbg: Kommt noch alles. Die Bitmaps und das ganze Zeugs wird in die Ressource gepackt nur so lnage ich noch am basteln bin ist es so etwas einfacher. Die Grafiken sind bis her noch nicht so toll. Ich werde mal sehen ob ich für die Spezial Effekts George Lucas gewinnen kann . Von der Optimierung habe ich schon geträumt und von Collosionsabfragen, Schleifen, Feuern, explodierenden Raumschiffen usw. .
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:57 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf