Objekt in Richtung Maus bewegen



  • Hi, ich weiß wirklich nicht, wieso ich das nicht mehr hinbekomme, aber ich möchte, dass ein Objekt auf der Koordinate [x1,y1] sich zur Koordinate [UnbekanntX,UnbekanntY] um X Pixel bewegen soll

    Ziel ist es, wenn ich z.B. ein Objekt habe und ich die Entertaste drücke, ein weiteres Objekt entsteht und sich von seiner Startposition zur Maus hinbewegt.

    Nun ist das Problem, dass ich es einfach nicht realisiert bekomme (mit den ganzen Winkeln und den Trigonometrischen Funktionen). Habe noch nicht viele Stunden dieses Thema gehabt und wollte nun fragen, ob mir hier einer helfen möchte, dies zu Realisieren (es geht nur um die Berechnung).

    Ich habe mir folgendes überlegt:

    -Objekt 1 wird auf (150, 200) erstellt
    -Mausposition ist (400, 100)
    ->Winkel von der Objekt1-Position zur Mausposition berechnen: dir
    ->Objekt.x+= cos(dir)*Geschwindigkeit
    ->Objekt.y+= sin(dir)*Geschwindigkeit

    Die letzten beiden Zeilen stimmen so nicht, das habe ich ausprobiert und ich weiß nicht, wie ich die machen soll. Der Ansatz zu den ersten Schritten fehlt mir völlig.

    mfg


  • Mod

    Für eine gradlinige, gleichförmige Bewegung musst du gar keinen Winkel ausrechnen und brauchst auch keine trigonometrischen Funktionen.

    Wenn du

    -Objekt 1 wird auf (150, 200) erstellt
    -Mausposition ist (400, 100)

    hast, dann sind die Differenzen (400-150, 100-200), das heißt (250, -100).

    Du bewegst das Objekt also um 250 Pixel in Richtung x und um -100 Pixel in Richtung y, dann wird es an der Mausposition landen. Wenn du das langsamer haben möchtest, kannst du diese Werte einfach skalieren, zum Beispiel durch 100 teilen, um immer in 100 Zeitschritten ans Ziel zu kommen. Dann bewegst du in jedem Zeitschritt das Objektum 25 Pixel in Richtung x und um -10 Pixel in Richtung y.

    Du kannst (250, -100) auch normieren, das heißt jede der beiden Zahlen durch $$\sqrt{250^2 + (-100)^2}$$ teilen. Dann bekommst du neue Zahlen (dx, dy) heraus, die du auch als Geschwindigkeit benutzen kannst, und wenn du möchtest, auch wieder mit einer Konstanten multiplizieren, um die Bewegung schneller oder langsamer zu machen.



  • Danke schon mal für den Ansatz. Das mit der Geschwindigkeit habe ich jedoch noch nicht verstanden.

    Das Problem aktualisiert auf 60 Frames die Sekunde. Wenn ich nun diese Abstände durch 100 teile (z.B), weiß ich nicht, mit welchem Wert ich dann die Position des Objektes addieren soll.

    Ziel ist es, das Objekt mit 5 Pixeln Geschwindigkeit von A nach B zu bringen.

    - Differenz ausgerechnet
    - Differenz durch 5 geteilt (?)
    - x+= ?
    - y+= ?

    Danke schonmal, mfg


  • Mod

    Gast_oirmb schrieb:

    Ziel ist es, das Objekt mit 5 Pixeln Geschwindigkeit von A nach B zu bringen.

    Für eine konstante Geschwindigkeit brauchst du das zweite Verfahren, das ich beschrieben habe: Jeden Wert durch die Norm teilen. Wenn die Differenz also (dx, dy) ist, teilst du dx und dy jeweils einmal durch $$\sqrt{dx^2 + dy^2}$$. Dann nimmst das, was rauskommt (multiplizierst das noch mit 5, um eine Geschwindigkeit von 5 Pixeln pro Frame zu bekommen), und addierst das in jedem Frame zu deinen x/y-Werten.

    Ich würde das wenn möglich in double rechnen und nicht in int-Werten, sonst könnte es eventuell passieren, dass am Ende eine Geschwindigkeit von 0 herausbekommst.



  • Die Bewegung ist auf jeden Fall schon mal vorhanden, danke. Nun besteht das Problem, dass immer wenn sich die Kugel nach rechts oder oben bewegen soll, sie sich nur Diagonal an den Ort hinbegibt. Ich weiß nicht, ob im u.s. Code ein Fehler ist, nach links und unten funktioniert es jedoch fließend.

    //vx: Verschiebung x
    //vy: Verschiebung y
    //m_X: (momentane Position x)
    //m_Y: (momentane Position y)
    
    double vx = (MouseX-m_X); //Abstand x ausrechnen
    double vy = (MouseY-m_Y); //Abstand y ausrechnen
    
    vx/=sqrt(pow(vx, 2.0)+pow(vy, 2.0));
    vy/=sqrt(pow(vx, 2.0)+pow(vy, 2.0));
    
    m_X+=vx*3; // Mit 3 Pixeln bewegen
    m_Y+=vy*3;
    

  • Mod

    Gast_oirmb schrieb:

    vx/=sqrt(pow(vx, 2.0)+pow(vy, 2.0));
    vy/=sqrt(pow(vx, 2.0)+pow(vy, 2.0));
    

    Die erste Zeile verändert vx und in der zweiten Zeile benutzt du den neuen Wert von vx.

    Außerdem könnte vx*vx möglicherweise schneller sein als pow(vx, 2.0).



  • Kopf -> Tisch. Natürlich. Die Bewegungen gehen jetzt richtig. Jedoch gibts da ein letztes Problem, das auf mich überhaupt keinen Sinn macht:

    double vx1 = (MouseX-m_X); //Abstand x ausrechnen
    double vy1 = (MouseY-m_Y); //Abstand y ausrechnen
    
    double vx2 = vx1;
    double vy2 = vy2;
    
    vx2/=sqrt(pow(vx1, 2.0)+pow(vy1, 2.0));
    vy2/=sqrt(pow(vx1, 2.0)+pow(vy1, 2.0));
    
    m_X+=vx2*5;
    m_Y+=vy2*5;
    
    std::cout<<vx1<<","<<vy1<<"; "<<vx2<<", "<<vy2<<std::endl;
    

    Wenn die letzte Zeile drin ist, funktioniert alles Perfekt. In dem Moment, wo ich sie auskommentiere, geht das ganze System mehr. Wo ist da der Fehler? Das versteh ich nun wirklich nicht. 😮



  • Dort oben ist ein Tippfehler. Das Problem ist beseitigt. Danke für die Geduld.



  • Hi. Ich habe mir das insgesamt angesehen, aber im Nachhinein festgestellt, dass es auf diese Weise nicht meinen Erwartungen entspricht. Ich kann zwar einen Punkt von A nach B bewegen, ich habe jedoch vergessen, dass dieser Punkt diese Richtung weiter einschlagen soll. Somit muss ich wohl doch mit Winkeln arbeiten. Das Objekt soll ja nicht an der X2 stehen bleiben sondern in die gleiche Richtung weiterfliegen. Außerdem schien das Objekt trotz deiner Formal statt diagonalem den langen Weg (> ^ statt /) einzuschlagen, wenn man die Geschwindigkeit runtersetzte.

    Somit bräuchte ich doch den Winkel von Punkt A nach Punkt B.

    Ich habe bereits folgenden Ansatz:

    //Die Katheten berechnen
    double a = Game.MouseX-m_X;
    double b = Game.MouseY-m_Y;
    //Pythagoras: Die Hypotenuse berechnen
    double c = sqrt(a*a+b*b);
    
    if(c==0) c=1; //Division durch 0 verhindern
    
    //Beta berechnen
    double Beta ( 180*asin(a/c)/PI ); //SFML arbeitet mit Bogenmaß, deswegen in Gradmaß umrechnen.
    

    Das alles funktioniert soweit. Der Winkel von Beta ist bestimmt. Der Ball soll sich zum Beispiel in die Richtung 60° Bewegen. Jedoch weiß ich nicht, mit was ich die X und Y Werte des Objektes addieren soll, damit er sich richtig bewegt.

    m_X+=(180.0*cos(60.0))/PI;
    m_Y+=(180.0*sin(60.0))/PI;
    

    So funktioniert das leider nicht. Ich hoffe ihr könnt mir da helfen.


  • Mod

    Gast_oirmb schrieb:

    Hi. Ich habe mir das insgesamt angesehen, aber im Nachhinein festgestellt, dass es auf diese Weise nicht meinen Erwartungen entspricht. Ich kann zwar einen Punkt von A nach B bewegen, ich habe jedoch vergessen, dass dieser Punkt diese Richtung weiter einschlagen soll. Somit muss ich wohl doch mit Winkeln arbeiten. Das Objekt soll ja nicht an der X2 stehen bleiben sondern in die gleiche Richtung weiterfliegen. Außerdem schien das Objekt trotz deiner Formal statt diagonalem den langen Weg (> ^ statt /) einzuschlagen, wenn man die Geschwindigkeit runtersetzte.

    Somit bräuchte ich doch den Winkel von Punkt A nach Punkt B.

    Ich verstehe nicht ganz, was bei dir nicht funktioniert. Deiner Beschreibung nach klingt es eher nach einem Implementierungsproblem. Wenn das Objekt weiterfliegen soll, kannst du ja einfach die Stopp-Bedingung weglassen.

    Jedenfalls brauchst du definitiv keine Winkel-Berechnungen, wenn du nur gleichförmige Bewegungen mit kartesischen Koordinaten (x/y-Werte) hast. Du würdest am Ende den Winkel ja doch wieder in deltaX/deltaY-Werte umrechnen, und dieses Hin-und-her-gerechne könntest du dir auch sparen.



  • Ich weiß auch nicht, wie ich das erklären soll. Grundsätzlich verfolgt er das Ziel richtig. Nur wenn man die Geschwindigkeit so auf 2 Pixel / Frame setzt, so sieht man, wie er nicht genau die Linie verfolgt, die am schnellsten ist, sondern manchmal dazu neigt, lieber x oder y statt beides zu verfolgen. Das merkt man jedoch nur, wenn das Ziel ihre Position nicht verändert.

    Wie auch immer würde ich trotzdem gerne mit Winkeln arbeiten, da ich später auch ein Partikelsystem implementieren möchte und dort mit Winkeln arbeiten möchte.
    Z.B. Flamme -> Richtung 90° oder Explosion -> 0 - 360°

    Soweit ich weiß, rechne ich die Polarkoordinaten in die Karthesichen folgendermaßen um:

    xziel = r*cos(a)*entfernung
    yziel = r*sin(a)*entfernung

    Die Entfernung wird dann auf objekt.x+1 und objekt.y+1 gesetzt, damit er sich immer weiter bewegt.

    Ist der Ansatz so richtig oder denke ich in die falsche Richtung?



  • Ich möchte noch hinzufügen, dass bei deiner Version, die ich folgendermaßen eingebaut habe:

    //Die Katheten berechnen
    double a = Game.MouseX-m_X;
    double b = Game.MouseY-m_Y;
    
    //Pythagoras: Die Hypotenuse berechnen
    double c = sqrt(a*a+b*b);
    
    if(c==0) c=1; //Division durch 0 verhindern
    
    a/=c;
    b/=c;
    
    m_X+=a*3;
    m_Y+=b*3;
    

    Er sich komischerweise unterschiedlich schnell bewegt (je nachdem, ob er sich nur Waagerecht / Senkrecht oder Diagonal bewegt).


Anmelden zum Antworten