Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 11, 2025 04:12

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 4 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Kollision Schläger Ball in Pong
BeitragVerfasst: Do Jun 01, 2006 20:49 
Offline
DGL Member

Registriert: So Mai 28, 2006 03:15
Beiträge: 18
Aloha,
tut mir Leid das ich euch schon wieder frage, ich hoffe es ist nicht wieder so eine dumme wie letztes mal, doch an diesem Problem sitze ich schon länger und verstehe einfach nicht, warum es bei mir nicht funktioniert.

Ich hoffe auch das ihr das Thema Kollisionen nicht schon zu leid seid, aber nun zum eigentlichen Punkt.
Ich wollte eigentlich zuerst einmal ein ganz einfaches Grundprogramm Pong schreiben und dieses später eventuell ein wenig aufpeppen.
Schläger lassen sich bewegen, Ball bewegt sich und prallt an den Rändern ab, nur will er nicht vom Schläger abprallen.

Ich habe es mir so gedacht:
Ich reduziere den Ball auf vier Punkte, ungefähr so:
Code:
  1.  
  2. ___1___
  3. _/___\_
  4. 2_____3
  5. _\___/_
  6. ___4___
  7.  

Die Zahlen markieren dabei die Punkte des Balls.
Jetzt kommt das rechnintensive, wo ich dachte, dass es zwar nicht elegant, aber so gelöst ist, dass es auf jednfall klappt (was ja leider ein Irrtum ist).
Ich lasse eine Schleife durchlaufen, in der ich jeden Punkt des Quadrats mit meinetwegen zuerst den Punkt 1 vergleiche.
Ist dies der Fall, so bekommt die Variable BallBewegung ein neues Vorzeichen (BallBewegung wird jedesmal zu der aktuellen BallPosition addiert, so kommt die Bewegung zustande).
Nun scheitert mein Code leider schon sehr früh, denn laut Debugger kommt es nie vor, dass die Punkte identisch sind.
Die Kollsionsfunktion sieht bei mir so aus:
Code:
  1.  
  2. function KollisionSchlaegerBall
  3.   (SX, SY, SHoehe, SBreite, BallX, BallY, BallRadius : Integer) : integer;  
  4. //SX, SY sind die Koordinaten für den unteren linken Punkt des Viereckes
  5. var Hoehe, Breite : integer;
  6. begin
  7.   result := 0;
  8.   Hoehe := 0;
  9.   repeat
  10.     Breite := 0;
  11.     repeat
  12. {Hier wird überprüft ob die Koordinaten gleich sind
  13. Wenn die rechte oder linkte Kordinaten des Balls mit der des Viereckes übereinstimmt gebe 1 zurück
  14. Wenn die obere oder untere, dann gib 2 zurück
  15. Breite und Hoehe werden immer erhoeht und zu der Position des unteren
  16. linken Punktes des viereckes dazuaddiert
  17. somit sollen (wenn nötig) alle Punkte des Viereckes abgearbeitet werden}
  18.       if ((SX + Breite = BallX) and (SY + Hoehe = BallY + BallRadius)) then  
  19.         result := 1;                                                                                    
  20.       if ((SX + Breite = BallX + BallRadius) and (SY + Hoehe = BallY)) then  
  21.         result := 2;                                                                                    
  22.       if ((SX + Breite = BallX - BallRadius) and (SY + Hoehe = BallY)) then  
  23.         result := 2;                                                                                  
  24.       if ((SX + Breite = BallX) and (SY + Hoehe = BallY - BallRadius)) then
  25.         result := 1;
  26.       inc(Breite);
  27.     until (result = 1) or (result = 2) or (Breite = SBreite);
  28.     inc(Hoehe);
  29.   until (result = 1) or (result = 2) or (Hoehe = SHoehe);
  30. end;
  31.  

Wie gesagt kommt es aber nie dazu, dass eine Zele in der result := 1 oder result := 2 steht bearbeitet wird (weil seltsamer weise die Bedingung also nie erfüllt wird).
Den Schlaeger Zeichne ich ganz normal so:
Code:
  1. procedure ZeichneSchlaeger(x, y, hoehe, breite : integer);
  2. begin
  3.   glBegin(GL_Quads);
  4.     glVertex3f(x, y, 0);
  5.     glVertex3f(x + breite, y, 0);
  6.     glVertex3f(x + breite, y + hoehe, 0);
  7.     glVertex3f(x, y + hoehe, 0);
  8.   glEnd;
  9. end;

Und die "Zeichnung" wird so aufgerufen:
Code:
  1.  Zeichneschlaeger
  2.     (round(Mouse.CursorPos.x * Aufloesungsfaktorx),
  3.      round(600 - (Mouse.CursorPos.y * Aufloesungsfaktory)),
  4.     Schlaegerhoehe1, Schlaegerbreite);

Der Schlaeger nimmt also die Position des Mauszeigers ein.
Da ich im ortho Modus bin und die Aufloesung 800*600 nutze, erhalte ich mit CursorPos nicht die Position die ich will, also Teile ich "Meine" Aufloesung durch die von Windows und erhalte so den Aufloesungsfaktor (getestet, klappt auch wunderbar).

So, ich hoffe ich habe mein Problem nicht zu ausführlich erläutert und hoffe auch, dass ihr mr evtl. weiterhelfen könnt.

Mfg Raxor


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 01, 2006 21:19 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Ich würde es so probieren:

Der ball ist ein Punkt (Mittelpunkt) und ein Radius.
Der Balken ist ein Rechteck, definiert durch sagen wir mal 2Punkte

Du berechnest immer den Abstand Mittelpunkt Balken, und wenn der Kleiner/Gleich dem Radius ist, gehts in die Gegenrichtung.

Der Abstand ist leicht zu bestimmen:

Ist der Ball direkt vor dem Balken, musst du nur die Y Koordinaten vergleichen (Ich sag jetzt einfach mal, dass das Spiel in die Verticale geht)
Is der Ball (Mittelpunkt) nicht direkt vor dem Balken musst du den Abstand der Nächsten Ecke zum Mittelpunkt berechnen.

Korrekte Physik ist das natürlich noch nicht, aber die Kollision müsste hinreichend sein.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 01, 2006 21:22 
Offline
DGL Member
Benutzeravatar

Registriert: Di Nov 26, 2002 22:12
Beiträge: 259
Wohnort: Dresden
Direkte Vergleiche für die Kollisionserkennung sind generell keine gute Idee.

Wenn deine Kollision mit der Wand funktioniert kannst du sie doch genauso für die Schläger umsetzen. Du musst nur zusätzlich prüfen ob
(BallPosition + Radius >= SchlägerMitte – HalbeSchlägerBreite) and
(BallPosition - Radius <= SchlägerMitte + HalbeSchlägerBreite)

Zweifelsfrei keine sehr elegante Methode, weil Ball und Schläger als Rechtecke gehandhabt werden. Aber sie funktioniert.

Da deine Kollisionsebene bekannt ist kannst du auch einfach prüfen ob deine Kugel mit der Ebene kollidiert. Das lässt sich auf eine Geraden-Ebenen-Schnittpunktbestimmung zurückführen. Dafür musst du nur den invertierten Normalenvektor an den Kugelmittelpunkt multipliziert mit dem Kugelradius anlegen um einen Punkt auf der Geraden zu erhalten. Der Richtungsvektor der Geraden ist der Bewegungsvektor deiner Kugel).

_________________
Nichts auf der Welt ist so gerecht verteilt wie der Verstand. Denn jederman ist überzeugt, dass er genug davon habe.
Rene Descartes, frz. Mathematiker u. Philosoph, 1596-1650


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Do Jun 01, 2006 23:04 
Offline
DGL Member

Registriert: So Mai 28, 2006 03:15
Beiträge: 18
So, jetzt wird es für mich wieder peinlich.

Wie letztes mal lag das Problem nämlich wo anders...

Wie ich geschrieben habe, habe ich das Rechteck zeichnen so aufgerufen:
Code:
  1.  Zeichneschlaeger
  2.     (round(Mouse.CursorPos.x * Aufloesungsfaktorx),
  3.      round(600 - (Mouse.CursorPos.y * Aufloesungsfaktory)),
  4.     Schlaegerhoehe1, Schlaegerbreite);

Man sieht, ich führe dort Berechnungen aus... die nicht in Variablen gespeichert werden.
Wenn ich dann die Kollision errechnet habe, habe ich die nicht aktualisierten Variablen übergeben... naja, wenn ich die aktualisiere funktioniert das auch.

Aber eure Hinweise/Tipps sind trotzdem sehr gut, so kann ich das ein wenig verbessern/optimieren.

Edit: Kann es sein, das die Forumszeit nicht GMT + 1h, sondern nur GMT ist?

So Noch ein Edit...
Für meine derzeitigen Zwecke ist glaube ich die von Flash beschriebene Methode die beste (auch bereits umgesetzt).
Allerdings finde ich die Methode von Magellan auch interessant (auch bereits probeweiser umgesetzt), wenn ich richtig verstanden habe, wird da nicht geprüft ob der Ball den Schläger treffen wird, sondern ob er bereits drin ist. Solche (zumindest für mich) ungewöhnlichen Denkansätze finde ich immer sehr interessant.
Den Rest von Magellans Beitrag müsste ich mir nochmal in einer ruhigen Stunde zu Gemüte führen... ich habe nicht ohne Grund vor ein paar Wochen Mathe Abi Grundkurs geschrieben (müsste erstmal nachschauen was invertiert heißt ^^).


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 4 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 12 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.008s | 16 Queries | GZIP : On ]