Wie kann ich ein Sprite in die Richtung bewegen, in die es zeigt?

11

Ich benutze Java / Slick 2D. Ich versuche, das Sprite mit der Maus zu drehen und mit den Pfeiltasten das Sprite zu bewegen. Ich kann das Sprite problemlos zum Drehen bringen, aber ich kann es nicht dazu bringen, sich in die Richtung zu bewegen, in die es soll. Wenn ich "vorwärts" drücke, bewegt sich das Sprite nicht unbedingt in Richtung Maus. Eigentlich bewegt es sich wirklich nur nach links auf dem Bildschirm. Ich bin mir sicher, dass es dafür einen Standardcode geben muss, da viele Spiele diesen Bewegungsstil verwenden. Kann mir jemand helfen, was der Trigger sein soll? Vielen Dank

BEARBEITEN: Hier ist der Rotationscode (der etwas anderes Seltsames bewirkt: /programming/12610320/why-is-my-image-rotating-off-center )

int mX = Mouse.getX();
        int mY = HEIGHT - Mouse.getY();
        int pX = sprite.x;
        int pY = sprite.y;
        int tempY, tempX;
        double mAng, pAng = sprite.angle;
        double angRotate=0;

        if(mX!=pX){
            mAng = Math.toDegrees(Math.atan2(mY - pY, mX - pX));
            if(mAng==0 && mX<=pX)
                mAng=180;
        }
        else{
            if(mY>pY)
                mAng=90;
            else
                mAng=270;
        }

        sprite.angle = mAng;
        sprite.image.setRotation((float) mAng); 

Und der Bewegungscode. Ich kann mich nur nach links bewegen ...

double ang = sprite.angle;
            Input input = gc.getInput();

            if(input.isKeyDown(sprite.up)){
                sprite.x += Math.cos(ang)*sprite.moveSpeed;
                sprite.y += Math.sin(ang)*sprite.moveSpeed;
            }if (input.isKeyDown(sprite.down)){
                sprite.x += -1*Math.cos(ang*Math.PI/180)*sprite.moveSpeed;
                sprite.y += -1*Math.sin(ang*Math.PI/180)*sprite.moveSpeed;
            }if (input.isKeyDown(sprite.left)){
                sprite.x -= Math.cos(ang*Math.PI/180)*sprite.moveSpeed;
                sprite.y += Math.sin(ang*Math.PI/180)*sprite.moveSpeed;
            }if (input.isKeyDown(sprite.right)){
                sprite.x += Math.cos(ang*Math.PI/180)*sprite.moveSpeed;
                sprite.y -= Math.sin(ang*Math.PI/180)*sprite.moveSpeed;
            }
rphello101
quelle
Was ist der Sinn des Codes, den Sie hinzugefügt haben? Ist das ein neues Problem? Wenn es sich um ein neues Problem handelt, öffnen Sie bitte eine neue Frage. Bitte aktualisieren Sie diese Frage nur mit Informationen zum Bewegen des Sprites in die Richtung, in die es zeigt.
MichaelHouse
Nein, es ist der Code, den ich verwendet habe, der das Problem verursacht hat. Siehe die Kommentare unten. Jemand hat danach gefragt.
rphello101
Ich sehe nicht, wo Sie sprite.movespeed berechnen?
AturSams
movespeed ist eine Konstante, in diesem Fall eingestellt auf .3
rphello101

Antworten:

14

Sie möchten einen Vektor erhalten, der auf Ihrer aktuellen Geschwindigkeit und Richtung basiert. Verwenden Sie dann diesen Vektor, um Ihre Position zu erhöhen.

//first get the direction the entity is pointed
direction.x = (float) Math.cos(Math.toRadians(rotation));
direction.y = (float) Math.sin(Math.toRadians(rotation));
if (direction.length() > 0) {
    direction = direction.normalise();
}
//Then scale it by the current speed to get the velocity
velocity.x = direction.x * speed;
velocity.y = direction.y * speed;

Jetzt kennen Sie Ihre Geschwindigkeit anhand Ihrer Rotation. Sie können Ihre Position mit diesen Informationen aktualisieren.

//Update the position based on our current speed
//This is basic s = vt physics
position.x += velocity.x * timeElapsed;
position.y += velocity.y * timeElapsed;
MichaelHouse
quelle
Für eine (schlampige) Klasse, die all dies enthält, können Sie einen Ludum Dare 21-Eintrag sehen, den ich hier zusammengestellt habe: bitbucket.org/byte56/ld21/src/af3dfc2c4c48/src/Byte56_LD21/…
MichaelHouse
Vielen Dank. Nach einigen Änderungen hat dies funktioniert. Ich habe jedoch eine andere Frage an Sie, wenn Sie dies lesen: Das Sprite dazu zu bringen, sich rückwärts zu bewegen, ist nur - = von dem, was Sie hier haben. Wie bewege ich es nach links oder rechts?
rphello101
@ rphello101 Gute Frage, du solltest eine neue Frage stellen. Mehr Menschen werden davon profitieren und Sie erhalten möglicherweise eine bessere Antwort als die, die ich habe.
MichaelHouse
3

Sie erhalten die Mausposition

mouseX = ... 
mouseY = ...

Sie erhalten die Sprite-Position

spriteX = ...
spriteY = ...

Sie finden den Winkel

angle = Math.atan2(mouseY - spriteY, mouseX - spriteX);

Ihre Bewegung wird sein:

moveX = Math.cos(angle) * speed * time;
moveY = Math.sin(angle) * speed * time;
AturSams
quelle
Als Tipp: Erstellen Sie eine Tabelle (Array) für cos und sin mit vorberechneten Werten. Sie können also einfach cosTable [(int) angle] * speed * time und sinTable [(int) angle] * speed * time ausführen. Es ist nicht so genau. Aber Sie erhalten Ihre Werte viel schneller.
Sidar
Dadurch wird das Sprite in Richtung Maus bewegt, dies entspricht jedoch nicht der Richtung, in die das Sprite zeigt. Das Sprite könnte sich immer noch zur Maus drehen, wenn die Rotationsgeschwindigkeit begrenzt ist oder aus einem anderen Grund. Grundsätzlich beantworten Sie die falsche Frage.
MichaelHouse
@ Byte56 sagte er "Wenn ich" vorwärts "drücke, bewegt sich das Sprite nicht unbedingt in Richtung Maus" Ich denke, das ist es, wonach er gefragt hat. Du könntest aber recht haben.
AturSams
Es ist sicher mehrdeutig. Ich habe in diesem Fall nur den Titel der Frage verwendet. Versteh mich nicht falsch, deine Antwort ist gut. Ich denke, wir werden herausfinden, was das OP wollte, wenn sie zurückkommen.
MichaelHouse
2
@Sidar Das wäre eine vorzeitige Optimierung. Das Erstellen von Sin / Cos-Tabellen, ohne die Sin / Cos-Operationen als Engpass zu identifizieren, ist Zeitverschwendung.
Bummzack