An Wand entlanggleiten

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • An Wand entlanggleiten

    Hallo Leute,

    hat jemand zufällig eine elegante Lösung damit das Spielerobjekt an Wänden entlanggleiten kann und nicht einfach nur stoppt? Ich habe da bisher selbst eine Lösung programmiert, allerdings kommt mir das sehr umständlich vor und es funktioniert nur an geraden Wänden, an 45 Grad Schrägen klappt das z.b. nicht wirklich... Es handelt sich hierbei um meinen Topdown Shooter. Später kann ich meinen momentanen Code hochladen.

    Gruß ;)
  • Wenn du den winkel deiner Wand nicht kennst, dann würde ich dir die "Fächer" Methode empfehlen. In einer forschleife gehst du collision lines durch (wie ein Fächer der sich aufklappt), gleichzeitig nach links und nach rechts von der eigtl bewegungsrichtung aus und wartest, bis eine der collision_lines nciht mehr kollidiert, dann brichst du ab und das ist deine neue bewegungsrichtung. So wird jede bewegung die in die wand gehen würde abgelenkt.

    ancient-pixel.com
    youtube.com/user/SebastianMerkl <<< ich freu mich über einen Besuch ;)
  • Dabei kann man auch BinarySearch empfehlen.
    Andererseits könntest du auch einfach prüfen, wie viele Pixel du nach unten oder oben gehen musst, wenn du z.B. 5 Pixel nach rechts gehst. Entsprechend auch in einer Schleife.
    Ein Bug ist mehr als nur ein Bug, es ist ein... Käfer!
    Egal, wie gut du eine Mauer baust, sie fällt um.... der klügere gibt nach :D

    Willst du mit mir auf Discord Chatten/Quatschen?
    Meine Husi's Tutorial Reihe
  • Ich hatte vor einigen Jahren in einem Projekt auf die internen Variablen speed, hspeed, vspeed, verzichtet, weil ich das movement lieber selber steuern wollte, da es irgendwie immer mehr Probleme gemacht hat, als es sollte.
    Bin dabei zufälig auf eine recht einfache Lösung gestoßen, die daraus besteht, die x und y Verschiebung getrennt zu behandelt, ungefähr so:

    GML-Quellcode

    1. var maxspeed, speed_;
    2. speed_[0] = lengthdir_x(maxspeed, direction);
    3. speed_[1] = lengthdir_y(maxspeed, direction);
    4. if (!place_meeting(x + speed_[0], y, wall))
    5. x += speed_[0];
    6. if (!place_meeting(x, y + speed_[1], wall))
    7. y += speed_[1];

    Das läuft zwar wahrscheinlich nicht so gut, wie der Ansatz mit collision_line, ist aber dafür einfacher und schneller zu implementieren.
    Evtl. könnte auch tunneling entstehen, wenn sich das Objekt zu schnell bewegt. Für normale Geschwindigkeiten, funktioniert es aber ohne Probleme.

    Es kann auch passieren, dass man einen Abstand zur Wand von maxspeed Pixeln hat, da in so einem Fall place_meeting eine Kollision melden würde und deshalb keine Bewegung ausgeführt wird.
    Man könnte das fixen, indem man im Falle einer Kollision noch einen entsprechenden move_contact Aufruf einbaut, der dann die Lücke zwischen Spieler und Wand schließt.

    Da du ein Top-Down Spiel hast, sollte das hier ausreichend sein. Bei einem Platformer wäre es aber u.U. etwas kantig, weshalb ich da eher die Lösung von Husi empfehlen würde, bei der man eine Maximal Distanz zum hochlaufen und runterlaufen festlegt und dann bei einer Kollision nochmal entsprechend viele Pixel drüber/drunter prüft.

    Eine andere Idee wäre es das ganze mit Normalen zu machen, aber leider unterstützt es der GM nicht die Normale bei einer Kollision abzufragen.
    Falls du in deinem Spiel eine feste Anzahl an Schrägen hast, könntest du den entsprechenden Objekten per Hand eine dazu passende Normale zuweisen. Damit kannst du dann die Ablenkung ohne irgendwelche Tricks ausrechnen.
    Der Code würde dann ungefähr so aussehen:

    Quellcode

    1. speed -= normal * dot(speed, normal) * overbounce
    Dabei sind speed und normal der Geschwindigkeits Vektor und der Normalen Vektor der Oberfläche. overbounce ist optional und kann auf Werte >= 1 gesetzt werden, um einen bounce Effekt zu erzielen.

    Falls in deinem Spiel also nur bestimmte Schrägen vorkommen, kannst du die Normalen manuell in den Objekten hinterlegen und es dann damit probieren.
    Ob das natürlich mit deinem restlichen movement Code harmoniert ist eine ganz andere Sache ^^ .
  • @-$Marvin$-
    Vielen Dank für die ausführliche Antwort.
    Im Endeffekt habe ich das ganze auf eine eher simple aber dafür wohl wieder recht umständliche Art gelöst. Es funktioniert recht gut für meine Zwecke, kommen aber nicht nur 45 Grad Schrägen hinzu, wird es wohl zu umständlich, was bei mir zum Glück nicht der Fall ist
  • Benutzer online 1

    1 Besucher