¿Cómo puedo mover un sprite en la dirección que está mirando?

11

Estoy usando Java / Slick 2D. Estoy tratando de usar el mouse para rotar el sprite y las teclas de flecha para mover el sprite. Puedo hacer que el sprite gire sin problemas, pero no puedo moverlo en la dirección que se supone que debe hacer. Cuando presiono "hacia adelante", el sprite no necesariamente se mueve hacia el mouse. En realidad, solo se moverá hacia la izquierda de la pantalla realmente. Estoy seguro de que tiene que haber algún código estándar para esto, ya que muchos juegos usan este estilo de movimiento. ¿Alguien puede ayudarme con lo que se supone que es el trigonometría? Gracias

EDITAR: Aquí está el código de rotación (que hace algo extraño: /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); 

Y el código de movimiento. Solo puedo moverme hacia la izquierda de la pantalla ...

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
fuente
¿Cuál es el punto del código que ha agregado? ¿Es este un nuevo problema? Si es un problema nuevo, abra una nueva pregunta. Solo actualice esta pregunta con información relacionada con el movimiento del sprite en la dirección en la que está orientado.
MichaelHouse
No, es el código que usé lo que causó el problema. Ver los comentarios a continuación. Alguien lo pidió.
rphello101
No veo dónde calculas sprite.movespeed?
AturSams
la velocidad de movimiento es una constante, en este caso establecida en .3
rphello101

Respuestas:

14

Querrás obtener un vector basado en tu velocidad y rumbo actuales. Luego usa ese vector para incrementar tu posición.

//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;

Así que ahora sabes tu velocidad en función de tu rotación. Puede actualizar su posición con esa información.

//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
fuente
Para una clase (descuidada) que contiene todo esto, puede ver una entrada de Ludum Dare 21 que reuní
MichaelHouse
Gracias. Después de algunas modificaciones, esto funcionó. Sin embargo, tengo otra pregunta para ti si lees esto: hacer que el sprite se mueva hacia atrás es solo - = de lo que tienes aquí. ¿Cómo hago para que se mueva hacia la izquierda o hacia la derecha?
rphello101
@ rphello101 Buena pregunta, debe hacer una nueva pregunta. Se beneficiarán más personas y puede obtener una mejor respuesta que la que yo tengo.
MichaelHouse
3

Obtienes la posición del mouse

mouseX = ... 
mouseY = ...

Obtienes la posición del sprite

spriteX = ...
spriteY = ...

Tu encuentras el angulo

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

Tu movimiento será:

moveX = Math.cos(angle) * speed * time;
moveY = Math.sin(angle) * speed * time;
AturSams
fuente
Como consejo: cree una tabla (matriz) para cos y sin con valores calculados previamente. así que puedes hacer cosTable [(int) angle] * speed * time y sinTable [(int) angle] * speed * time) No es tan preciso. Pero obtienes tus valores mucho más rápido.
Sidar
Esto moverá el sprite hacia el mouse, pero eso no es lo mismo que la dirección que está mirando el sprite. El sprite aún podría estar girando hacia el mouse si su velocidad de rotación está limitada o por alguna otra razón. Básicamente, estás respondiendo la pregunta equivocada.
MichaelHouse
@ Byte56 dijo "Cuando golpeo" hacia adelante ", el sprite no necesariamente se mueve hacia el mouse" Creo que eso es lo que preguntó. Aunque podrías tener razón.
AturSams
Es un poco ambiguo seguro. Acabo de omitir el título de la pregunta en este caso. No me malinterpretes, tu respuesta es buena. Supongo que descubriremos qué quería el OP cuando / si regresan.
MichaelHouse
2
@Sidar Eso sería una optimización prematura. Construir tablas sin / cos sin identificar las operaciones sin / cos como cuello de botella es una pérdida de tiempo.
bummzack