Como posso mover um sprite na direção em que ele está voltado?

11

Estou usando Java / Slick 2D. Estou tentando usar o mouse para girar o sprite e as setas do teclado para mover o sprite. Posso fazer o sprite girar sem problemas, mas não consigo que ele se mova na direção que deveria. Quando eu clico "para a frente", o sprite não necessariamente se move em direção ao mouse. Na verdade, ele só se moverá realmente para a esquerda da tela. Tenho certeza de que deve haver algum código padrão para isso, pois muitos jogos usam esse estilo de movimento. Alguém pode me ajudar com o que o trigonométrico deve ser? obrigado

EDIT: Aqui está o código de rotação (que faz outra coisa estranha: /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); 

E o código de movimento. Só posso me mover para a esquerda da tela ...

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
fonte
Qual é o sentido do código que você adicionou? Isso é um problema novo? Se for um novo problema, abra uma nova pergunta. Atualize esta pergunta apenas com informações relacionadas à movimentação do sprite na direção em que ele está voltado.
MichaelHouse
Não, é o código que usei que causou o problema. Veja os comentários abaixo. Alguém pediu.
Rphello101 28/09/12
Não vejo onde você calcula sprite.movespeed?
AturSams
movespeed é uma constante, neste caso, em conjunto 0,3
rphello101

Respostas:

14

Você deseja obter um vetor com base em sua velocidade e direção atuais. Em seguida, use esse vetor para aumentar sua posição.

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

Então agora você conhece sua velocidade com base em sua rotação. Você pode atualizar sua posição com essas informações.

//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
fonte
Para uma classe (desleixado) que contém tudo isso, você pode ver um Ludum Atreva 21 entrada eu coloquei aqui: bitbucket.org/byte56/ld21/src/af3dfc2c4c48/src/Byte56_LD21/...
Michaelhouse
Obrigado. Após algumas modificações, isso funcionou. Tenho uma outra pergunta para você, se você ler isso: fazer o sprite se mover para trás é apenas o que você tem aqui. Como faço para mover para a esquerda ou direita?
#
@ rphello101 Boa pergunta, você deve fazer uma nova pergunta. Mais pessoas serão beneficiadas e você poderá obter uma resposta melhor do que a que eu tenho.
MichaelHouse
3

Você obtém a posição do mouse

mouseX = ... 
mouseY = ...

Você obtém a posição de sprite

spriteX = ...
spriteY = ...

Você encontra o ângulo

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

Seu movimento será:

moveX = Math.cos(angle) * speed * time;
moveY = Math.sin(angle) * speed * time;
AturSams
fonte
Dica: Crie uma tabela (matriz) para cos e sin com valores pré-calculados. para que você possa fazer apenas cosTable [(int) ângulo] * velocidade * tempo e sinTable [(int) ângulo] * velocidade * tempo Não é tão preciso. Mas você obtém seus valores muito mais rapidamente.
Sidar
Isso moverá o sprite em direção ao mouse, mas não é o mesmo que a direção que o sprite está voltado. O sprite ainda pode estar virado para o mouse se a velocidade de rotação estiver limitada ou por algum outro motivo. Basicamente, você está respondendo à pergunta errada.
MichaelHouse
@ Byte56, ele disse: "Quando eu clico em" para frente ", o sprite não necessariamente se move em direção ao mouse" Acho que foi isso que ele perguntou. Você pode estar certo.
AturSams
É meio ambíguo, com certeza. Eu simplesmente adotei o título da pergunta neste caso. Não me interpretem mal, sua resposta é boa. Acho que descobriremos o que o OP queria quando / se eles voltarem.
MichaelHouse
2
@ Sidar Isso seria otimização prematura. Construir tabelas sin / cos sem identificar as operações sin / cos como gargalo é uma perda de tempo.
bummzack