Problem mit 2d Kollisionsabfrage



  • Hallo!

    Also, ich programmiere im moment an einem outbreak clone.(kennt bestimmt jeder... da wo man so steine mit nem ball kaputtmachen muss und mann den immer mit so nem teil unten abfangen muss 😃 ) auf jeden fall weiß ich nicht so ganz wie ich die kollisions abfrage zwischen stein unnd ball realisieren soll. bzw. ich kann eine kollision feststellen aber wie bestimmt ich dann WIE der ball abprallen soll. denn wenn er von oben auf den stein prallt sollte er natürlioch nach unten gehen und von links dann halt nach rechts. 🙄 aber ich weiß nicht wie ich die seiten bestimmen kann an die der ball prallt.
    ich dachte dadran das ganze dann irgenndwie mit rects zu lösen; geht ja auch gut bei si nem spiel. aber dann gibt es auch noch die möglichkeit das beispielsweise nur EIN eck vom ball um steinRECT drin is.
    Also kurz gesagt, ich weiß nicht so ganz wie ich das umsetzen soll. 😃
    wär für jeden tip dankbar!

    ➡ Thx im Voraus!



  • Ich verstehe nicht genau wo dein Problem liegt. Wenn du die Kollision feststellen kannst, kannst du ab dann die Bewegungsrichtung umkehren bzw. den Winkel zwischen Bewegungsrichtung des Balls und dem Stein bestimmen und dann den Ball in die entgegengesetzte Richtung unter berücksichtigung des Winkels bewegen lassen.



  • die kollision kann ich mit rects feststellen.

    Bsp:

    +---+
    ||----------+
    +---+
    ****|
    **+------------+
    das große iste ein stein und das kleine der ball. uund genau da hast das problem. prallt der ball jetzt nach oben oder nach links ob? das mit den winkeln und so is easy aber ich weiß net wie ich feststellen soll WO der ball dran prallt.

    [die * sind nur so da sonst gings net gehscheit mit leerzeichen]



  • hm.. du willst also wissen ob der ball an den linken/rechten (daher senkrechten) seite ankommt oder an der waagerechten? Mach doch einfach eine solche abfrage: x,y sind die koordinaten des kollisionspunktes. Nun frag ab ob x-1/y oder x+1/y immernoch kollision (dann ist es wohl eine waagerechte seite) und frag ab ob x/y-1 oder x/y+1 immernoch kollision (dann ist es wohl eine senkrechte seite) 🙂 Wenns nun genau auf die ecke trifft, lässt sich das entsprechend rausfinden. Funktioniert aber nur wenn es keine schrägen Steine gibt 😉



  • 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 senkrechte

    Hab 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.x

    Das 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.x

    Das 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... :p 😡

    Aber 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!! 😉

    😃 👍 👍


Anmelden zum Antworten