Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Kollisionsabfrage (https://www.delphipraxis.net/149759-kollisionsabfrage.html)

Behemoph 29. Mär 2010 16:24


Kollisionsabfrage
 
Hallo leute, hoffe, dass mein Problem hier reinpasst.. :>

Und zwar bin ich dabei, ein Spielchen ala Space Invaders zu programmieren, meine fähigkeiten beschränken sich leider bisher jedoch auf den Schulunterricht.
Ich bin nun soweit, dass mein Schiffchen auf knopfdruck lenken und schießen kann. Bei einer Kollision von Geschoss und feindlichem Objekt soll dieses jedoch verschwinden.
und genau da hört es bei mir auf :x. Meine idee war folgende:
Delphi-Quellcode:
procedure p_schuss;
begin
 if (y<=form1.Image3.Top+form1.image1.top+form1.Image3.height) and (x>=form1.image3.left-17) and (x<=form1.Image3.left) and (form1.image3.visible=true) then
 begin
  form1.image3.visible:=false;
  ...
 end else
     begin
      y:=y-4;
      ...
     end;
end;
Die prozedur p_schuss wird in einem timer aufgerufen.
x und y sind die Koordinaten des Projektils, image3 ist das zu zerstörende Objekt, welches 17x17 pixel groß ist, image1 ist die Leinwand.
Doch es soll nicht bei diesem image3 bleiben, sondern es sollen noch einige andere zerstörbare objekte vorhanden sein.
Mit meinen Kentnissen würde ich jetzt für die 10000 weiteren images jeweils den text kopieren und die zahl bei 'imageX' ändern müssen.. aber das geht doch sicher einfacher, nur find ich einfach keine lösung :(
Es sollte also möglich sein, überprüfen zu lassen, ob sich das geschoss bei irgendeinem image befindet und dieses dann verschwinden zu lassen. Das wäre super :)
Hoffe, ihr könnt mir helfen und meine Informationen genügen dafür :)

mfg Behemoph

shmia 29. Mär 2010 17:12

Re: Kollisionsabfrage
 
Eine einfache Kollisionsabfrage im 2-dimensionalen Bereich könnte so aussehen:
Beide Objekte sind Rechtecke. (Dein Schuss ist ein Rechteck mit Breite=1 und Höhe = 6)

Die Rechtecke können sich überschneiden oder nicht.
Ein Spezialfall der Überschneidung ist, wenn ein Rechteck komplett im anderen enthalten ist.

Glücklicherweise bietet Windows schon eine Funktion um zu Prüfen, ob sich zwei Rechtecke überschneiden.
Diese Funktion wird jetzt noch schön verpackt, damit sie leicht zu benützen ist:
Delphi-Quellcode:
function HasKollision(const A,B:TRect):Boolean;
var
   union : TRect;
begin
   Result := IntersectRect(union, A,B);
end;
Um die Kollision mit einem Image zu prüfen, bauen wir eine weitere Hilfsfunktion:
Delphi-Quellcode:
function KollisionMitImage(img:TImage; r : TRect):Boolean;
var
   img_rect : TRect;
begin
   if img.Visible then
   begin
      img_rect := img.ClientRect;
      // Rechteck verschieben
      OffsetRect(img_rect, img.Top, img.Left);
      Result := HasKollision(img_rect, r);
   end
   else
      Result := False; // Image war unsichtbar
end;

Behemoph 29. Mär 2010 17:47

Re: Kollisionsabfrage
 
Danke für deine schnelle Antwort, nur bekomm ich es leider nicht auf die reihe :(. Wo müssen die Funktionen denn aufgerufen werden, was setze ich für "r" ein? achso, mein geschoss wird übrigends per canvas gezeichnet. sollte ich stattdessen auch für das Geschoss ein image verwenden? :>

mfg Behemoph

shmia 29. Mär 2010 18:01

Re: Kollisionsabfrage
 
Dein Geschoss erstellst du auch aus einem Rechteck.
Ich schlage vor, es ist 1 Pixel breit und 6 Pixel hoch (das kannst du je nach Geschmack verändern)
Du fängst jetzt erstmal an die Kollision mit einem einzigen Image ins Laufen zu bringen.
Delphi-Quellcode:
var
  geschoss : TRect;
begin
  // Rechteck für Geschoss
  // X & Y ist die Referenzposition
  geschoss := Rect(X,Y, X+1, Y+6);  // evtl auch Y-6

  if KollisionMitImage(image3, geschoss) then
  begin
    PlaySound('BummKrach.WAV',0,SND_FILENAME); // nur so als Idee, was man hier machen könnte
    image3.Visible := False; // nach Kollion verschwindet das Image
  end;
end;
Wenn du dann soweit bist, dann kannst du das nächste Problem angehen.
Du hast wohl so an die 20 bis 40 Images, die alle in einer Schleife auf eine Kollision geprüft werden wollen.
Aber immer eines nach dem anderen...

Behemoph 29. Mär 2010 18:31

Re: Kollisionsabfrage
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ok, entweder ich bin wirklich nur zu doof, oder das ganze ist in der form nicht kompatibel mit dem rest meines programmes. Wüsste nicht, in welche prozedur ich das ganze einfügen soll.. Blicke da noch nich so wirklich durch, fürchte ich :>. Wäre sehr nett, wenn du dir das mal kurz angucken könntest, ist ja noch nicht soooo viel :P. Komme jedenfalls nicht weiter :/ Sry für mein fehlendes Durchblicken :>

shmia 29. Mär 2010 18:50

Re: Kollisionsabfrage
 
Hi, dein Vorhaben ist auch noch etwas zu schwer für Dich.
Space Invaders sieht einfach aus, aber Spieleprogrammierung ist halt die Königsdiziplin beim Programmieren.
Delphi-Quellcode:
procedure p_schuss(var x,y:integer); // Parameterliste sollte genau so sein, wie oben deklariert
var geschoss:trect;
begin
  if schuss1 then
  begin
    y := y - 4; // Geschoss bewegen

    geschoss:=rect(x,y,x+1,y+6);
//  keine Ahnung woher diese Werte -38, -33 usw kommen, aber hier muss evtl etwas angepasst werden
//    geschoss:=rect(x-38,y-33,x-36,y-18);
    if KollisionMitImage(form1.image3, geschoss) then
    begin
      form1.image3.visible:=false;
      schuss1 := false;
    end
    else
    begin
      form1.Image1.canvas.rectangle(geschoss); // Geschoss zeichnen
    end;
  end;
end;

Behemoph 29. Mär 2010 19:06

Re: Kollisionsabfrage
 
Also ich bin ja erstmal sehr froh, dass du dich da bei mir zurechtgefunden hast :>. Die eigenartigen Zahlen habe ich mir ausprobiert.. damit die Geschosse mittig vom eigenartig aussehenden Schiff losfliegen. Nur eigenartiger Weise funktioniert die Sache immernoch nicht. Die geschosse verschwinden jetzt sogar manchmal und der stern verschwindet auch nicht :>. Dass die Sache noch ein wenig zu kompliziert für mich ist, möchte ich nicht bestreiten.. allerdings möchte ich ja weiterkommen und lernen, da möchte ich das nicht einfach so aufgeben, weil ich nicht weiterkomme. Gibt es denn nicht eine einfacher gehaltene Möglichkeit, zu gucken, welches image berührt wird?
Und nochmal danke für deine Mühen ;)

mfg Behemoph

Blup 30. Mär 2010 07:23

Re: Kollisionsabfrage
 
Du bist jetzt in der Lage einige Worte in einer fremden Sprache zu kennen und willst gleich einen Vortrag halten.
Sorry aber das wird so noch nichts, dir fehlen noch wichtige Grundkenntnisse und Übung.
Stell das Projekt erst mal zurück und beschäftige dich zu einem späteren Zeitpunkt damit.
Natürlich könnten die meisten hier für dich schnell dieses Spiel schreiben, aber das würde dich nicht weiter bringen.
Arbeite erst mal einige Tutorials durch oder besorg dir ein gutes Buch für Anfänger.

Hier habe ich etwas zum grundsätzlichen Aufbau so eines Spiels (eigentlich im Prinzip jede Anwendung) geschrieben: Memoryspiel


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz