Problem mit 2d Kollisionsabfrage
-
Dein Problem hängt ganz von deiner Kollisionsabfrage ab. Vielleicht kannst du zeigen (schematisch) was der konkret macht bzw. was er prüft.
Spontan fällt mir nix ein außer dass du anhand der globalen Position des Balls bestimmen könntest, welche Kante des Steins dem Ball gerade zugewandt ist. Dies ist dann sie Seite, bei der eine Kollision stattgefunden hat.
Die entsprechende Seite könntest du feststellen, indem du einen Vektor vom Mittelpunkt des Balls zum Mittelpunkt des Steins (bzw. dessen Rechteck) berechnest. Dann checkst du, mit welcher Kante der Vektor sich schneidet. Diese Kante ist die dem Ball zugewandte.
-
@life
das kann nicht immer fuktionieren denn der ball bewegt sich ja mehrere pixel pro frame und dann passierts meistens dass er mehr als 1 pixel "im" stein drin ist. somit bekommt man dann immer kollision raus.@randa
also bis jetzt hab ich einfach nur sowas in der art:struct rect{ int x,y; int w,h; } ball,stone; if(ball.x>=stone.x && ball.y#x<=stone.x+stone.w && ball.y>=stone.y && ball.y<=stone.y+stone.h){ KOLLISION!}
unnd genauso hab ihcs halt noch mit den anderen drei ecken gemacht. also einfach die rects "verglichen".
-
wie gesagt, probier mal aus was ich oben beschrieben hab.
Noch ein (spartanisches) beispiel zur Veranschaulichung:
____ ______ / / \ \ / + ---------------+ \ /___/ \ \ \_____\
+ = Mittelpunkte.
--- Vektor.
Die kleine Figur ist der Ball. Die zugewandte seite ist die linke von der großen Figur (dem Stein). Wäre der Ball oben, würde der Vektor die obere Seite schneiden, usw...Edit: code
-
dann brauchst du eh ne bessere kollisionsabfrage. Sonst kanns dir ja passieren, dass deine kugel einfach durch das rechteck durchfliegt (wenns schnell genug ist). Also musste schon die "spur" der kugel abfragen... Die Abfrage, ob es eine Kollision gibt oder nicht, kann dabei natürlich so bleiben
edit: wenn du das so machst, brauchste auch keinen Vektor von einem Mittelpunkt zum Anderen zu machen (denn der Bewegungsvektor geht genauso gut), weil du halt gleich einen Randpunkt als Kollisionspunkt erhälst. Dann musst du nur noch überprüfen, welchen Randvektor dieser Punkt "schneidet". Nachteil hierbei ist, dass du halt erst die Randvektoren festlegen musst und an diesen immer entlang gehen musst (was auch zeitaufwendig ist). Vorteil ist, dass es flexibler ist und auch mit schrägen Steinen funktionieren sollte.
-
@randa
mal ne ganz doofe frage: wie mach ich sowas? wie setll ich fest "durch" welche seite der vektor geht?
@life
sry aber deds hab ich net so gnaz geblickt ^^oh mann, irgendwei si des sau schwer ahb auch schon auf englscihen seiten geguckst und so aber irgendwie hat da niemadn so richtig ne ahnung. aber es haben dioch schon so viele leute sowas programmiert
da fällt mir grad nich ein: ich hab ne lösung nur is das dann irgendwie komisch:
Also so... ich check die kollision wie oben ab. also jededn eckpunkt. is er "im" rect vom stein drin, dann guck ich noch ob ein banachtbarter eckpunkt uach drin is, dann is die richtung in die der ball abprallt ja schon logisch! und wenn echt NUR ein eck im steinrect is dann prüf ich um wie viel pixel es auf der x und auf der y acshe in den steion reingeht(is bissel doof zuu erklären). wenn der ball den stein so trifft wie ich oben gezeigt hab und er biespielsweise mehr nach rechts "in den stein reingeht" dann müsste er nach oben abprallen.
aber irgendwie wirkt dass dann komisch wenns viele steine nebeneinander gibt. der ball prallt da net ab sondern geht irgendwie trotzdem und macht viel zu viel stieen kaputt. ihr könnts euch ja mal angucken irh merkts wenn ihr ne ziet lang spielt... -> http://wallyshp.funpic.de/hb.zip
-
wenn ich dich richtig verstanden habe (was nicht leicht ist wegen der ganzen tippfehler
) gehts dir nur noch um die ecken. Du willst jetzt also wissen, ob er an die senkrechte seite geprallt ist oder an die waagerechte. Dazu guckst du wie weit er in x richtung und y richtung vom rand entfernt ist. Wenn er weiter in x richtung "drin" ist -> war wohl die waagerechte
Wenn er weiter in y richtung drin ist -> war wohl die senkrechteHab ich das richtig verstanden? Nun aufjedenfall kann dies falsch sein. An deinem bsp kann man z.b. nicht erkennen, wie der Ball nun weiter fliegen müsste, weil man halt nur den Endzustand sieht (der Ball ist im rect (was eigentlich meiner Meinung nach auch nicht sein sollte >_<)). Anhand des Endzustandes, lässt sich nicht bestimmen mit welcher Seite des Steinrechteckes er nun kollidiert ist. Er könnte ja auch mit der Senkrechten kollidieren, aber eine starke x bewegung (und kleine y bewegung) haben. Dann würde dein Programm aber so tun als ob der ball mit der waagerechten kollidiert wäre ... Also machs lieber wie ichs gesagt habe xD (oder wie randa es vorschlägt)
-
W@lly schrieb:
@randa
mal ne ganz doofe frage: wie mach ich sowas? wie setll ich fest "durch" welche seite der vektor geht?
Bitte lesen. Danke.
Bye, TGGC (Reden wie die Großen)
-
Ich würde es spontan so machen, Voraussetzung ist, dass die Steine in deiner Dateinstruktur von unten (niedrigerer y-Wert) nach oben (höherer y-Wert) sortiert sind.
[code]
-Loop durch alle Steine
//ball ist sowieso unter dem Steinen, also teste nicht weiter:
--if yPos des Balls + Radius < yPos des Steins - halbe Höhe d. Steins then break
//wenn ball nicht über dem stein ist, gabs vielleicht ne kollision
--else if yPos des Balls - Radius <= yPos des Steins + halbe Höhe
---if xPos Ball + radius >= xPos Stein - Steinbreite/2 oder
---xPos Ball - radius <= xPos Stein + Steinbreite/2
----finde mit beschriebender Methode heraus, ob x oder y - Kollision
----if y
-----ball_richtungsvector.y = -ball_richtungsvektor.y
----else
-----ball_richtungsvector.x = -ball_richtungsvektor.xDas wars glaub ich schon. Jetzt kannste einfach die Richtung normalisieren und auf die Position addieren. Fertig.
-
spl@t schrieb:
Ich würde es spontan so machen, Voraussetzung ist, dass die Steine in deiner Dateinstruktur von unten (niedrigerer y-Wert) nach oben (höherer y-Wert) sortiert sind.
[code]
-Loop durch alle Steine
//ball ist sowieso unter dem Steinen, also teste nicht weiter:
--if yPos des Balls + Radius < yPos des Steins - halbe Höhe d. Steins then break
//wenn ball nicht über dem stein ist, gabs vielleicht ne kollision
--else if yPos des Balls - Radius <= yPos des Steins + halbe Höhe
---if xPos Ball + radius >= xPos Stein - Steinbreite/2 oder
---xPos Ball - radius <= xPos Stein + Steinbreite/2
----finde mit beschriebender Methode heraus, ob x oder y - Kollision
----if y
-----ball_richtungsvector.y = -ball_richtungsvektor.y
----else
-----ball_richtungsvector.x = -ball_richtungsvektor.xDas wars glaub ich schon. Jetzt kannste einfach die Richtung normalisieren und auf die Position addieren. Fertig.
du hast dir den thread nicht durchgelesen oder?
-
Naja, hab ihn überflogen, weiß auch nicht wie ich gerade darauf gekommen bin dass die Richtungsänderung ein ungelöstes, und die Kollision ein gelöstes Problem ist... Sorry
Aber wenn man das Spiel spielt, merkt man nicht viel von Problemen bei der Kollision.
Trotzdem Nachtrag:
Wie würde es eigentlich aussehen, wenn du einfach immer annimmst, dass es sich um eine Kollision mit der Unter - bzw. Oberseite des Steines handelt, und immer den y-Vektor umkehrst? Bei den kleinen Steinen würde das wohl kaum auffallen, außerdem ensteht der Effekt, dass der Ball an der nächsten Schicht Steine abgeprallt ist, das Problem, dass der Ball zu viele Steine hintereinander abräumt sollte auch gelöst sein, und du kannst auf das Rechteck um den Ball verzichten und erreichst somit auch bei nem großen Ball pixelgenaue Kollision.Besser?
-
"Naja, hab ihn überflogen, weiß auch nicht wie ich gerade darauf gekommen bin dass die Richtungsänderung ein ungelöstes, und die Kollision ein gelöstes Problem ist... Sorry"
warum gehste dann nur auf die Kollision ein und nicht wie man rausfindet obs eine "x-Kollision" oder "y-Kollision" ist?
"Aber wenn man das Spiel spielt, merkt man nicht viel von Problemen bei der Kollision."
Mit der Kollision nicht, aber mit der RIchtungsänderung...
"Wie würde es eigentlich aussehen, wenn du einfach immer annimmst, dass es sich um eine Kollision mit der Unter - bzw. Oberseite des Steines handelt, und immer den y-Vektor umkehrst? "
Warum löst er nicht einfach das Problem anstatt es zu ignorieren?
"das Problem, dass der Ball zu viele Steine hintereinander abräumt sollte auch gelöst sein"
nein?
"und du kannst auf das Rechteck um den Ball verzichten und erreichst somit auch bei nem großen Ball pixelgenaue Kollision. "
Nein. Du legst auch ein Rechteck um den Ball..
-
Sag mal du Troll, irgendwie ergibt nicht ein einzelner Kommentar zu meinem Post auch nur den Hauch von Sinn, ich werde jetzt nicht darauf eingehen, ist ja wohl lächerlich.
Lies du lieber mal richtig.
-
@mods
Könnte man hier ent so ne art ignore-funktion einbinden? dann wär tggc bestimmt bei fast allen forum usern auf der ignore list... :pAber nichts destotrotz (oder wie auch immer man das schreibt) hab ich mir tggc's tip zu herzen genommen und meinen gehirnschmalz benutzt :p :
Hab mal im mathebuch von der 9. klasse geguckt und hab gedacht das konnte man ja mit linearen funktionen lösen. also wenn nur ein eck im steinrect drin is, dann stellt der ne funktion linearefuntion auf. und checkt dann ob der "funktionsgraph" durch die linke/rechte oder obere/untere seite geht.
aber dann muss ich halt nur vom mittelpunt des balles ausgehen!? kann das so ähnlich funktionieren?
-
guck lieber im mathebuch der klasse 12-13 unter vektorrechnung nach
übrigens war TGGC nicht immer so arrogant und selbstgefällig
Unter FAQ hat er nämlich nen paar tutorials zu total banalen Problemen geschrieben.. wirklich erstaunlich
-
eine genaue kollision zwischen stein/kreis kriegst du nur, wenn du die strahlgleichung in die kreisgleichung einsetzt nach s auflöst,und dann für jede seite testest.
hier mal en bissl arbeit abgenommen:
(xO+sxD)-xM)2+(yO+syD)-yM)2=r2
.
O ist der startpunkt eines strahls des rechtecks
D ist die steigung des Strahls
M ist der mittelpunkt des Kreises
s ist die stelle der Strecke, an der Der Kreis den Strahl trifft(es gibt 0,1,oder 2 lösungen).
um den echten treffpunkt rauszubekommen,brauchst du nurnoch s*D+O rechnen.nu viel spaß beim umformen^^
-
life schrieb:
übrigens war TGGC nicht immer so arrogant und selbstgefällig
Unter FAQ hat er nämlich nen paar tutorials zu total banalen Problemen geschrieben.. wirklich erstaunlich
Um ihm jetzt zuvor zu kommen...:
Er _IST_ es halt!!
-
otze schrieb:
eine genaue kollision zwischen stein/kreis kriegst du nur, wenn du die strahlgleichung in die kreisgleichung einsetzt nach s auflöst,und dann für jede seite testest.
hier mal en bissl arbeit abgenommen:
(xO+sxD)-xM)2+(yO+syD)-yM)2=r2
.
O ist der startpunkt eines strahls des rechtecks
D ist die steigung des Strahls
M ist der mittelpunkt des Kreises
s ist die stelle der Strecke, an der Der Kreis den Strahl trifft(es gibt 0,1,oder 2 lösungen).
um den echten treffpunkt rauszubekommen,brauchst du nurnoch s*D+O rechnen.nu viel spaß beim umformen^^
dann musste aber noch abfragen, dass s nicht größer als die länge der Strecke wird und nicht kleiner als 0..
einfacher, aber langsamer ist es, wenn du es so machst:
(Rect.x + n1 - Ball.x)² + (Rect.y + n2 - Ball.y)² <= r²
Und n1 und n2 dürfen nur Werte von 0-Rect.breite bzw 0-Recht.höhe annehmen. Müsste eigentlich auch funktionierenDas funktioniert dann übrigens auch wenn bei ihm der Ball mal wieder mit einem Zug mitten ins Rect fliegt
btw. musste dann bei meiner Variante das ganze mit ner doppelten for-schleife oder so durchgehen..edit: mit der performancesparenden Variante von otze bekomm ich übrigens mit derive folgendes für s heraus :D:
s = - (sqrt(r2·(xd2 + yd^2) - xd2·(ym2 - 2·ym·yo + yo^2) + yd·(xm - xo)·(2·xd·(ym - yo) - yd·(xm - xo))) + xd·(xo - xm) + yd·(yo - ym))/(xd^2 + yd^2) s = (sqrt(r2·(xd2 + yd^2) - xd2·(ym2 - 2·ym·yo + yo^2) + yd·(xm - xo)·(2·xd·(ym - yo) - yd·(xm - xo))) + xd·(xm - xo) + yd·(ym - yo))/(xd^2 + yd^2)
-
So...gtu ich glaub das projekt hat sich dann schon für mich erledigt...
bin jetzt grad mal in der zehnten klasse und hab von euren gleichungen net wirklich ne ahung.
so'n dreck...
naja ich schau mal ob ich's irgendwie gebacken krieg. wenn noch irgendwer n tip hat, wär ich trotzdem dankbar.
-
ich bin auch in der 10. who cares?
ist das ein grund, eine einfache quadratische gleichung nicht auflösen zu können? oder mal im internet nach kreisgleichung oder strahlengleichung zu googlen?@life jo und nu stell dir das mal im 3d raum vor,dann weiste, was ich da für ne arbeit hatte^^
-
ich versteh nicht ganz, wieso alle meinen Post ignorieren. Weil life irgendwelchen unpassenden Kommentare dazu gegeben hat?
Ich glaub ich mach doch folgendes:life schrieb:
"Naja, hab ihn überflogen, weiß auch nicht wie ich gerade darauf gekommen bin dass die Richtungsänderung ein ungelöstes, und die Kollision ein gelöstes Problem ist... Sorry"
warum gehste dann nur auf die Kollision ein und nicht wie man rausfindet obs eine "x-Kollision" oder "y-Kollision" ist?
Ich bin auf die Richtungsänderung (Umkehrung des Vektors) eingegangen, nicht auf den entsprechenden Kollisionsalgorithmus zum bestimmen ob x-oder y-Kollision. Ich weiß wie geschrieben, dass das falsch war.
life schrieb:
"Aber wenn man das Spiel spielt, merkt man nicht viel von Problemen bei der Kollision."
Mit der Kollision nicht, aber mit der RIchtungsänderung...
Nein, die Richtungsänderungen stimmen, der Ball prallt ordentlich von den Wänden ab, die Kollision ist das Problem.
life schrieb:
"Wie würde es eigentlich aussehen, wenn du einfach immer annimmst, dass es sich um eine Kollision mit der Unter - bzw. Oberseite des Steines handelt, und immer den y-Vektor umkehrst? "
Warum löst er nicht einfach das Problem anstatt es zu ignorieren?
Das Problem wird nicht ignoriert sondern auf sehr einfache Art gelöst.
life schrieb:
"das Problem, dass der Ball zu viele Steine hintereinander abräumt sollte auch gelöst sein"
nein?
Wenn er von der Seite kommt, würde er seine Richtung frühzeitiger ändern und eine Kollision mit der nächsten Schicht wäre nicht möglich.
life schrieb:
"und du kannst auf das Rechteck um den Ball verzichten und erreichst somit auch bei nem großen Ball pixelgenaue Kollision. "
Nein. Du legst auch ein Rechteck um den Ball..
Quatsch, wo denn
? Es wird der Radius des Balls mit benutzt (bezieht sich ja alles auf den Pseudocode von oben).
Übrigens hab ich selbst erst die Kollision bei einem Pingpongsspiel so realisiert, und wenn ich mit mehreren Bällen spiele, ist die Kollision der Bälle untereinander eindeutig pixelgenau (naja, fast), selbst wenn diese den viertel Bildschirm ausfüllen.
Wo verdammt nochmal liegt das Problem? Ich sage ja nicht, dass es auf beschriebene Weise 100% gut aussehen muss, aber nen Versuch wärs wert.