Autor |
Beitrag |
somebody
      
Beiträge: 167
Erhaltene Danke: 2
|
Verfasst: So 10.01.10 01:01
Hallo Leute, für die Schule sollen wir einen kleines Spiel Programmieren. Das ganze soll recht einfach sein, man hat eine Kanone, die man nach links und rechts bewegen kann. Außerdem kann diese auch Kugeln abschießen. Oben befindet sich ein "Raumschiff", welches man treffen kann.
Soweit auch kein problem. Zwei Bedingungen waren noch gegeben, das ganze soll Objektorientiert und mit Canvas gemacht werden. Auch noch kein Problem.
Jetzt ist nur die Frage, wie kann ich mit Canvas eine Kollisionsabfrage machen, also abfragen, ob die Kugel das "Raumschiff" berührt hat? Ich hatte schon probiert es so zu machen, dass ich gucke ob die y koordinaten der kugel und des Raumschiffes nahezu gleich sind, UND ob die x Koordinaten der Kugel und des Raumschiffes nahezu gleich sind, allerdings ist dieser Fall komischerweise nie eingetreten.
Die Kugel ist ein Canvas.Ellipse und das Raumschiff ein Canvas.Rectangle
Habt ihr eine Idde?
Gruß
somebody
P.S: Falls die Infos zu wenig waren, kann ich ja auch noch ein Stück Code posten.
Zuletzt bearbeitet von somebody am So 10.01.10 01:18, insgesamt 1-mal bearbeitet
|
|
MaPsTaR
      
Beiträge: 90
Erhaltene Danke: 4
Win XP
Delphi 7 Enterprise
|
Verfasst: So 10.01.10 01:09
Ich würde mir um das Raumschiff ein Rechteck oder anderes "denken" und dann anhand der Koordinaten des Geschosses berechnen, ob es sich in dem Rechteck befindet.
Aber wenn das bei dir nie eingetreten ist...
Am besten wäre du postest mal deinen Code.
_________________ Liebe Kinder, es stimmt ... solnage auch nur der ertse und lezte Bchutsabe rihctig ist und alle andreen Bcuhsatben irgendwie vorahnden sind,
dann knan man es dennonch lesen, also macht nur weiter so, wir verstehen euch schon
|
|
somebody 
      
Beiträge: 167
Erhaltene Danke: 2
|
Verfasst: So 10.01.10 01:18
Oki, also hiermit bewege ich die Kugel
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| Canvas.Ellipse(Kugel.Bewegen_x(10,Kugel.x),Kugel.Bewegen_y(10,Kugel.y),20 + Kugel.Bewegen_x(10,Kugel.x),20 + Kugel.Bewegen_y(10,Kugel.y));
. . .
Function TKugel.Bewegen_Y(AVy: integer; AYalt: integer): Integer; begin FYneu := AYalt + AVy;
Result := FYNeu; end;
function TKugel.Bewegen_X(AVx: integer; AXalt: integer): Integer; begin FXneu := AXAlt + AVx;
Result := FXneu; end; |
Und das Raumschiff bewegt sich so
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| Canvas.Rectangle(Raumschiff.Bewegen_x(Lok_x),20,50 + Raumschiff.Bewegen_x(Lok_x), 40); . . .
function TRaumschiff.Bewegen_X(AVx: integer): Integer; begin FXneu := FXneu + AVx;
if FXneu >= 800 then begin FXneu := -20; end else begin Result := FXneu; end; end; |
Und dann hatte ich halt versucht, die Koordinaten zu vergleichen, das sah dann ungefähr so aus.
Delphi-Quelltext 1: 2: 3: 4:
| if (Kugel.y <= 8) and (Kugel.x = Raumschiff.Bewegen_x(Lok_speicher) then begin Raumschiff.Destroy; end; |
Ich hoffe es bringt etwas...
Moderiert von matze: Code- durch Delphi-Tags ersetzt
|
|
MaPsTaR
      
Beiträge: 90
Erhaltene Danke: 4
Win XP
Delphi 7 Enterprise
|
Verfasst: So 10.01.10 01:30
Zitat: | Delphi-Quelltext 1: 2: 3: 4:
| if (Kugel.y <= 8) and (Kugel.x = Raumschiff.Bewegen_x(Lok_speicher) then begin Raumschiff.Destroy; end; | |
Warum bewegst du das Raumschiff beim Testen nochmal?
Welche Felder hat Raumschiff denn?
X- und Y-Koordinate? Width? ...
Delphi-Quelltext 1: 2: 3: 4:
| if (Kugel.y <= 8) and (Kugel.x > Raumschiff.x) and (Kugel.x < (Raumschiff.x + Raumschiff.width)) then begin Raumschiff.Destroy; end; |
_________________ Liebe Kinder, es stimmt ... solnage auch nur der ertse und lezte Bchutsabe rihctig ist und alle andreen Bcuhsatben irgendwie vorahnden sind,
dann knan man es dennonch lesen, also macht nur weiter so, wir verstehen euch schon
|
|
ub60
      
Beiträge: 764
Erhaltene Danke: 127
|
Verfasst: So 10.01.10 01:39
Die grobe Kollision gibt es mit IntersectRect (Schnittpunkt zweier Rechtecke), das "Finetuning" dann mit Masken.
ub60
|
|
somebody 
      
Beiträge: 167
Erhaltene Danke: 2
|
Verfasst: So 10.01.10 01:40
Also ich bewege das Raumschiff nochmal, weil ich darüber die x Koordinate des Raumschiffes erhalte. Diese überprüfe ich dann... Man sieht die Bewegung aber nicht, da ich sie ja nicht zeichne.
Und das Raumschiff hat nur die Felder x und y.
|
|
MaPsTaR
      
Beiträge: 90
Erhaltene Danke: 4
Win XP
Delphi 7 Enterprise
|
Verfasst: So 10.01.10 01:53
Aber du müsstest die X-Koordinate doch auch in Lok_Speicher haben, oder?
Delphi-Quelltext 1: 2: 3: 4:
| if (Kugel.y <= 8) and (Kugel.x > Lok_speicher) and (Kugel.x < (Lok_speicher + 50)) then begin Raumschiff.Destroy; end; |
Wie kommst du eigentlich auf if (Kugel.y <= 8) ...
Müsste es nicht eher
Delphi-Quelltext 1:
| if (Kugel.y <= Raumschiff.y) ... |
heißen?
_________________ Liebe Kinder, es stimmt ... solnage auch nur der ertse und lezte Bchutsabe rihctig ist und alle andreen Bcuhsatben irgendwie vorahnden sind,
dann knan man es dennonch lesen, also macht nur weiter so, wir verstehen euch schon
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: So 10.01.10 03:04
Hey,
ich würd das so machen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| const TOLERANCE = 10;
if (Kugel.x + TOLERANCE > Raumschiff.x - TOLERANCE) and (Kugel.x - TOLERANCE < Raumschiff.x + TOLERANCE) and (Kugel.y + TOLERANCE > Raumschiff.y - TOLERANCE) and (Kugel.y - TOLERANCE < Raumschiff.y + TOLERANCE) then Raumschiff.Free; |
das Bild zeigt jetzt die 2. überprüfung. Der Punkt sind die Koordinaten un das Viereck die Toleranz.
MfG Bergmann
Moderiert von Narses: Bild als Anhang hochgeladen.
Einloggen, um Attachments anzusehen!
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
somebody 
      
Beiträge: 167
Erhaltene Danke: 2
|
Verfasst: So 10.01.10 11:29
Oki, Danke für die schnellen Antworten. Ich habe es jetzt mit Bergmans Variante versucht und es geht fast ohne Fehler. Das einzige Problem ist, dass wenn ich das Raumschiff getroffen habe, es nicht zerstört wird, sondern noch weiterlebt aber von Anfang an wieder startet. Wenn ich es dann ein Zweites mal treffen will, dann kommt eine Zugriffsverletzung, aber auch nur wenn ich das Raumschiff getroffen habe.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| procedure TForm1.Timer1Timer(Sender: TObject); const toleranz = 10; begin Timer2.Enabled := false; Paintbox1.refresh;
Canvas.Ellipse(Kugel.Bewegen_x(10,Kugel.x),Kugel.Bewegen_y(10,Kugel.y),20 + Kugel.Bewegen_x(10,Kugel.x),20 + Kugel.Bewegen_y(10,Kugel.y));
Canvas.Rectangle(Lok_speicher,20,50 + Lok_speicher, 40); Kugel.Y := Kugel.Y - 10;
if Kugel.y <= 8 then begin if (Kugel.x + toleranz > Raumschiff.x - toleranz) and (Kugel.x - toleranz < Raumschiff.x + toleranz) then begin Raumschiff.Free; Timer2.Enabled := false; end else begin Timer2.Enabled := true; PaintBox1.Refresh; Kugel.Y := 650; Timer1.Enabled := false; end; end; end; |
Ich finde den Fehler irgendwie nicht, könnt ihr mir da weiterhelfen?
EDIT: Ich erzeuge das Raumschiff einfach nochmal, nachdem es getroffen wurde, damit nach einmal schießen nicht gleich alles vorbei ist. Das alte wird natürlich auch zerstört um speicher zu sparen.
Danke für eure hilfe!
Moderiert von matze: Code- durch Delphi-Tags ersetzt
|
|
F34r0fTh3D4rk
      
Beiträge: 5284
Erhaltene Danke: 27
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: So 10.01.10 12:12
Bergmann89 hat folgendes geschrieben : | Hey,
ich würd das so machen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| const TOLERANCE = 10;
if (Kugel.x + TOLERANCE > Raumschiff.x - TOLERANCE) and (Kugel.x - TOLERANCE < Raumschiff.x + TOLERANCE) and (Kugel.y + TOLERANCE > Raumschiff.y - TOLERANCE) and (Kugel.y - TOLERANCE < Raumschiff.y + TOLERANCE) then Raumschiff.Free; |
das Bild zeigt jetzt die 2. überprüfung. Der Punkt sind die Koordinaten un das Viereck die Toleranz.
MfG Bergmann |
ich würde die Toleranz auf der linken Seite weglassen. Sonst könnte man auch gleich schreiben:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| const TOLERANCE = 10;
if (Kugel.x > Raumschiff.x - TOLERANCE*2) and (Kugel.x < Raumschiff.x + TOLERANCE*2) and (Kugel.y > Raumschiff.y - TOLERANCE*2) and (Kugel.y < Raumschiff.y + TOLERANCE*2) then |
und dann lässt man das *2 gleich weg und nimmt lieber ne größere Toleranz, falls es nicht reicht.
Das Projektil würde ich mir eher als Punkt vorstellen und das Raumschiff als Rechteck (in diesem Falle wäre es ein Quadrat).
Dann hast du halt nur noch die Punkt-In-Quadrat Prüfung zu machen.
Also eher wie das hier:
Delphi-Quelltext 1: 2: 3: 4: 5:
| if (Kugel.x > Raumschiff.x - Raumschiff.breite) and (Kugel.x < Raumschiff.x + Raumschiff.breite) and (Kugel.y > Raumschiff.y - Raumschiff.hoehe) and (Kugel.y < Raumschiff.y + Raumschiff.hoehe) then |
Und das mit der globalen Variable, in der du zusätzlich die Koordinate speicherst, ist nicht im Sinne der Objektorientierung.
In der Regel verzichtet man auf globale Variablen.
Ich würde das zu testende Projektil der Kollisions Funktion des Raumschiffs übergeben (oder umgekehrt):
Delphi-Quelltext 1:
| TRaumschiff.pruefeKollisionMit(projektil: TProjektil): boolean; |
oder:
Delphi-Quelltext 1:
| TProjektil.pruefeKollisionMit(raumschiff: TRaumschiff): boolean; |
Oder was hat es genau mit diesem Lok_Speicher auf sich?
mfg
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: So 10.01.10 15:29
Hey,
wie erzeugst du denn das Raumschiff, bzw wo? Weil das steht ja nich im Codeausschnitt.
MfG Bergmann.
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
somebody 
      
Beiträge: 167
Erhaltene Danke: 2
|
Verfasst: Mo 11.01.10 12:20
Das Raumschiff erzeuge ich in formcreate. Danke zwar für die weiteren Fragen, aber das Problem hat sich schon erledigt. geht mittlerweile alles...
aber trotzdem danke für die hilfe 
|
|
Florian H.
      
Beiträge: 29
|
Verfasst: Mo 11.01.10 18:35
|
|
|