Laden...

XNA-Framework: Kollision von Rechtecken abfragen

Erstellt von Manniac vor 9 Jahren Letzter Beitrag vor 9 Jahren 4.995 Views
M
Manniac Themenstarter:in
9 Beiträge seit 2015
vor 9 Jahren
XNA-Framework: Kollision von Rechtecken abfragen

Hey,

( ich hoffe, ich bin hier im richtigen Bereich. )

Ich habe mich mal an C# gewagt und wollte zu Test-Zwecken ein kleines Spiel programmieren.
Allerdings stehe ich direkt vor einem Problem:
Meine Kollisionsabfrage funktioniert nicht.

Ich verwende zudem das XNA Framework.

Codes:
Intializierung:

Random random = new Random();
            foodX = random.Next(0, graphics.PreferredBackBufferWidth);
            foodY = random.Next(0, graphics.PreferredBackBufferHeight);

Kollisionsabfrage:

if (player_x == foodX && player_y == foodY)
            {
                Random random = new Random();
                foodX = random.Next(0, graphics.PreferredBackBufferWidth);
                foodY = random.Next(0, graphics.PreferredBackBufferHeight);

                player_food++;
            }

Zeichnung von "food"

spriteBatch.Draw(box, new Rectangle(foodX,foodY, box.Width, box.Height), Color.White);

Das Problem ist, dass die "Box" nicht verschwindet & an einem neuen Ort erstellt wird. Anscheinend stimmt etwas mit den Positionen nicht.

Grüße

2.207 Beiträge seit 2011
vor 9 Jahren

Hallo Manniac,

wilkommen im Forum.

Ich bitte dich, dir mal [Hinweis] Wie poste ich richtig? durchzulesen.

Auch findest du in [Artikel] Debugger: Wie verwende ich den von Visual Studio? raus, was wo mit den Positionen nicht stimmt, wenn es nur um Koordinaten geht.

Verlange bitte von deinen Helfern keine fertige Lösung für dein Problem.

Gruss

Coffeebean

M
Manniac Themenstarter:in
9 Beiträge seit 2015
vor 9 Jahren

Hey,

danke für die beiden Links. Das Erste habe ich mir bereits durchgelesen.
Zum 2:
Ich habe die Koordinaten bereits debuggt, allerdings habe - denke ich - den Fehler gefunden.

Die Box ist kleiner als die Figur, die der Spieler steuert.

Wie stelle ich es an, dass die Position ungefähr übereinstimmt? +/- 10 px.

( wie schon erwähnt; es reicht ein Tipp, keine Codes)

1.346 Beiträge seit 2008
vor 9 Jahren

Zwei Rechtecke sind kollidiert, genau dann wenn einer der Eckpunkte von Rechteck 1 in Rechteck 2 liegt oder einer der Eckpunkte von Rechteck 2 in Rechteck 1 liegt.

M
Manniac Themenstarter:in
9 Beiträge seit 2015
vor 9 Jahren

Okay,

ich habe nun die Koordinaten ausgeben lassen.
89 <--- FoodY
782 <- food X

89 <--- player_y
785 <---- player_x

Das müsste eigentlich ja passen. Zumal ich die Größe des Rechtecks erhöht habe.

5.658 Beiträge seit 2006
vor 9 Jahren

Hi Manniac,

du machst überhaupt keine Kollisionsabfrage auf Rechtecke sondern vergleichst nur die absoluten Positionen:

Kollisionsabfrage:

if (player_x == foodX && player_y == foodY)  
{}  

Du willst natürlich überprüfen, ob sich die Spielerposition innerhalb des Bereichs von x - (width * 0.5) ... x + (width * 0.5) befindet (und entsprechend für die Y-Koordnate).

Auch wenn die Frage eigentlich überhaupt nichts mit XNA zu tun hat: XNA eine veraltete Technologie, die von Microsoft nicht mehr unterstützt wird. Einige Alternativen findest du hier: [FAQ] Wie finde ich den Einstieg in die 3D-Programmierung mit C#?

Christian

Weeks of programming can save you hours of planning

M
Manniac Themenstarter:in
9 Beiträge seit 2015
vor 9 Jahren

Dann sollte das hier funktionieren, oder?

if((player_x >= (foodX + (box.Width *0.5)) && player_x <= (foodX - (box.Width * 0.5))) && (player_y >= (foodY + (box.Height *0.5)) && player_y <= (foodY - (box.Height
                 * 0.5))))
            {
                Console.WriteLine("YES");
            }

Auch wenn die Frage eigentlich überhaupt nichts mit XNA zu tun hat: XNA eine veraltete Technologie, die von Microsoft nicht mehr unterstützt wird. Einige Alternativen findest du hier: Wie finde ich den Einstieg in die 3D-Programmierung mit C#?

Danke, werde ich mir mal durchlesen. Vorerst brauche ich aber nur 2D. /edit:
Achso, 2D wird da auch unterstützt.

5.658 Beiträge seit 2006
vor 9 Jahren

Sieht schon besser aus. Hier noch ein paar Anmerkungen:

  • Die Vergleiche sind genau verkehrtherum, das sollte sich aber relativ einfach mit dem Debugger herausfinden lassen
  • Falls deine Koordinaten Intergers sind, mußt du an der richtigen Stelle auf int casten, oder / 2 verwenden anstatt \* 0.5
  • Dein Player benötigt sicherlich auch eine BoundingBox, momentan fragst du ja nur ab, ob sich die Position des Spielers innerhalb des Rechteckes befindet

Edit:

  • Die Mittelpunkte der Box werden gar nicht beachtet, d.h. die Box liegt immer bei [0,0]

Weeks of programming can save you hours of planning

M
Manniac Themenstarter:in
9 Beiträge seit 2015
vor 9 Jahren

Zu deinem letzten Punkt habe ich eine Frage.

Sind die X & Y Position ( so, wie sie momentan sind) exakt die Mitte des Rechtecks?

5.658 Beiträge seit 2006
vor 9 Jahren

Du hast zwei Positionen, eine für den Spieler und eine, für das Rechteck (Food?). Siehe dazu mein Edit in der letzten Antwort. Das Rechteck hat außerdem eine Breite und eine Höhe. Ob die Position die Mitte des Rechtecks ist oder der linke, untere Punkt oder irgendein anderer Punkt, ist völlig egal. Das kannst du frei definieren, je nachdem, wie es für dich am logischsten oder einfachsten erscheint.

Falls du Probleme hast, dir das Ganze visuell vorzustellen, dann zeichne dir ein Koordinatensystem auf ein Blatt Papier und versuche, das Problem erst einmal graphisch darzustellen.

Alternativ dazu kannst du dir ein Testprogramm schreiben, das erstmal nur Punkte und Rechtecke zeichnet. Das braucht dann auch nicht mit DirectX oder XNA gemacht, sondern kann eine einfache WinForm-Anwendung sein: [Tutorial] Zeichnen in Windows-Forms-Programmen (Paint/OnPaint, PictureBox).

Weeks of programming can save you hours of planning

M
Manniac Themenstarter:in
9 Beiträge seit 2015
vor 9 Jahren

Ich habe das nun folgendermaßen gelöst.

if (!IsPlayerInBox(player_x - smile.Width, player_y - smile.Height, player_x + smile.Width, player_y + smile.Height, foodX - box.Width, foodY - box.Height, foodX + box.Width, foodY + box.Height))
            {
                Random random = new Random();
                foodX = random.Next(0, graphics.PreferredBackBufferWidth);
                foodY = random.Next(0, graphics.PreferredBackBufferHeight);
                player_food++;
                
            }
 public bool IsPlayerInBox(float p_minx, float p_miny, float p_maxx, float p_maxy, float b_minx, float b_miny, float b_maxx, float b_maxy)
        {
            if(!(p_minx > b_maxx) && !(p_maxx < b_minx) && !(p_maxy < b_miny) && !(p_miny > b_maxy)) return false;
            return true;
        }

Danke für deine Tipps!

P
1.090 Beiträge seit 2011
vor 9 Jahren

Probiere das ganze doch mal Objekt Orientiert und gib die Objekte Player und Box in deine Methode.
So ist es einfach furchtbar zu Lesen und wird für dich wird es auch schwer sein deinen Fehler zu Debuggen.

Kleiner Tip zum Fehler Width müsste HalfWidth heißen oder du erkennst momentan eine Kollision ohne das die Objekte sich Berühren.

MFG
Björn

Sollte man mal gelesen haben:

Clean Code Developer
Entwurfsmuster
Anti-Pattern