KI für rollende Kugel / Hindernissen ausweichen

  • KI für rollende Kugel / Hindernissen ausweichen

    Hallo,
    ich habe ein Problem bei der Programmierung meines neuen Spiels.
    Erstmal das Grundlegende:
    Es geht unter anderem darum, eine Kugel zu steuern, und dabei Hindernissen auszuweichen, Punkte und Extras einzusammeln, andere Kugeln aus der Bahn zu rammen, usw.... Die Geschwindigkeit ist festgelegt, nur die Richtung ist beeinflussbar. Dabei soll es auch "Bots" geben, (z.B. für den Deathmatch-Modus).
    Diese sollen wie folgt reagieren:
    Die speed ist festgelegt, pro Step kann die direction um +4/-4 geändert werden.
    Bisher sieht meine Programmierung der KI so aus:
    Step-Event:
    1. Hindernis=0
    2. Der Bot kontrolliert ob etwas im Weg ist, in der Richtung, in die er sich gerade bewegt, und zwar mit 200 pts im vorraus:
    PunktX=x+cos(direction)*200
    PunktY=y+sin(direction)*200
    if(collision_line(x,y,PunktX,PunktY,Hindernis,true,true)>0){Hindernis=1}
    3. Richtungsänderung wenn was im Weg ist
    if(Hindernis=1){...}

    Also die Richtungsänderung klappt, bloss folgendes Problem:
    Der Bot erkennt das erste Hindernis, weicht auch aus, aber danach spinnt die Hinderniskontrolle (Schritt 2).
    Ich hab die Kollisionslinie mal zeichnen lassen, und nach dem ersten Hindernis zeigt die Linie nicht mehr in die Richtung der Bewegung sondern irgendwo sonst hin! ?(
    Ich versteh das nicht, eigentlich müsste mit meiner kleinen Formel oben doch alles glattgehen, also die Kollisionslinie immer in direction zeigen, oder nicht?

    Schonmal im vorraus danke für jede Hilfe :)
    Casi82
  • Ist ja auch logisch. Du setzt Hindernis auf 1 und nicht wieder auf 0.

    Also musst du auch weiterhin prüfen ob was 200 points voraus ist. Also ersetz einfach

    GML-Quellcode

    1. if(collision_line(x,y,PunktX,PunktY,Hindernis,true,true)>0){Hindernis=1}

    mit

    GML-Quellcode

    1. if(collision_line(x,y,PunktX,PunktY,Hindernis,true,true)>0){Hindernis=1;} else {Hindernis=0;}
  • Hm... als Sinus-Feind sage ich dir spontan: versuch's mit lengthdir :P. Ich glaube so müsste es aussehen (bin aber gerade nicht sicher):

    GML-Quellcode

    1. PunktX=x+lengthdir_x(200,direction)
    2. PunktY=y+lengthdir_y(200,direction)

    Wenn das funzt, dann sehe ich mein Misstrauen der Sinus-Kurve gegenüber als gerechtfertigt. ^^

    Ich denke aber eher, dass das Problem mit der Direction zusammen hängen muss (was zu einem vor kurzem bewältigten Problem in meinem aktuellen Projekt passt). Ich denke der Code deiner Richtungsänderung dürfte Aufschluss geben.
  • wenn die variable hindernis nur entweder 1 oder 0 sein kann, dann birngt die bei

    GML-Quellcode

    1. if(collision_line(x,y,PunktX,PunktY,Hindernis,true,true)>0)


    nichts, denn an der stelle, bei der du dieses reingeschrieben hast, gehört normalerweise das objekt rein

    edit: wenns das nicht is, probier mal das game im debug-mode laufen zu lassen und "watch" mal die variable direction


  • @ lolliger joj:
    Sorry, mein Fehler: in der Kollisionsabfrage steht bei mir natürlich nicht die Variable Hindernis, sondern diverse Objekte, die ich für diesen Beitrag nur als Hindernisse zusammenfassen wollte :wacko:

    @ F4ALLOUT:
    Danke, ich werde es mal ausprobieren.
    Meine Richtungsänderung funktioniert übrigens so:
    Links=1; Rechts=1;
    Dann werden in 10-Grad-Schritten Kollisionsabfragen nach links gestartet.
    Wenn eine Kollision stattfindet, Links+=1, wenn nicht, wird der Ablauf unterbrochen.
    Dann das gleiche für rechts.
    Dann:
    if(Links=Rechts){entweder nach links oder rechts richtung ändern}
    else
    {
    if(links<rechts){nach links richtung ändern, um Links*10 Grad}else{nach rechts richtung ändern, um Rechts*(-10) Grad}
    }

    Aber wie gesagt:
    Das Problem ist, das nach dem Hindernis=1 das erste mal stattgefunden hat, ausgewichen wird und Hindernis wieder =0 ist.
    Soweit so gut, aber komischerweise zeigt dann die "Kollisionslinie" nicht mehr in Bewegungsrichtung, sondern irgendwo anders hin, wo kein Hindernis ist.
    Und dadurch wird die Variable Hindernis nicht wieder auf 1 gesetzt, selbst wenn die Kugel auf ein Hindernis zusteuert :(

    Dabei wird der Code doch einfach nur jeden Step wiederholt, also wenns einmal klappt, muss es doch auch wieder klappen :headtouch:

    Casi82
  • Das Problem bei deinem Script ist ganz simpel, cos(x) und sin(x) arbeiten im normalen Koordinatensystem (y-Achse zeigt gegen oben), darum muss das so aussehen (y-Koordinate, also bei sin() umkehren):

    GML-Quellcode

    1. PunktX=x+cos(direction)*200
    2. PunktY=y-sin(direction)*200
    int (*x(*x(int))[5])(int*);
    Confused? Yes, it's C!
  • Also müsste meine lengthdir-Lösung das Problem doch beseitigt und mein Misstrauen sich bestätigt haben (wenn mir denn kein Fehler unterlaufen ist). ^^ Und wenn Du Recht hast, Dragoon, muss Casi diese erste funktionierende Prüfung immer in der Waagerechten ausgeführt haben, richtig? ;)

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von F4LL0UT ()