Comment déplacer un sprite dans la direction à laquelle il fait face?

11

J'utilise Java / Slick 2D. J'essaie d'utiliser la souris pour faire tourner le sprite et les touches fléchées pour déplacer le sprite. Je peux faire tourner le sprite sans problème, mais je ne peux pas le faire bouger dans la direction où il est censé le faire. Lorsque je frappe "en avant", le sprite ne se déplace pas nécessairement vers la souris. En fait, il ne se déplacera vraiment que vers la gauche de l'écran. Je suis sûr qu'il doit y avoir un code standard pour cela, car de nombreux jeux utilisent ce style de mouvement. Quelqu'un peut-il m'aider avec ce que le trig est censé être? Merci

EDIT: Voici le code de rotation (qui fait autre chose de bizarre: /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); 

Et le code du mouvement. Je ne peux que me déplacer vers la gauche de l'écran ...

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
la source
Quel est l'intérêt du code que vous avez ajouté? Est-ce un nouveau problème? S'il s'agit d'un nouveau problème, veuillez ouvrir une nouvelle question. Veuillez mettre à jour cette question uniquement avec des informations relatives au déplacement du sprite dans la direction à laquelle il fait face.
MichaelHouse
Non, c'est le code que j'ai utilisé qui a causé le problème. Voir les commentaires ci-dessous. Quelqu'un l'a demandé.
rphello101
Je ne vois pas où vous calculez sprite.movespeed?
AturSams du
movespeed est une constante, dans ce cas fixée à .3
rphello101

Réponses:

14

Vous voudrez obtenir un vecteur basé sur votre vitesse et votre cap actuels. Utilisez ensuite ce vecteur pour augmenter votre position.

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

Alors maintenant, vous connaissez votre vitesse en fonction de votre rotation. Vous pouvez mettre à jour votre position avec ces informations.

//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
la source
Pour une classe (bâclée) qui contient tout cela, vous pouvez voir une entrée Ludum Dare 21 que j'ai réunie ici: bitbucket.org/byte56/ld21/src/af3dfc2c4c48/src/Byte56_LD21/…
MichaelHouse
Je vous remercie. Après quelques modifications, cela a fonctionné. J'ai une autre question à vous poser si vous lisez ceci: amener le sprite à reculer est juste - = de ce que vous avez ici. Comment puis-je le faire bouger à gauche ou à droite?
rphello101
@ rphello101 Bonne question, vous devriez poser une nouvelle question. Plus de personnes en bénéficieront et vous obtiendrez peut-être une meilleure réponse que la mienne.
MichaelHouse
3

Vous obtenez la position de la souris

mouseX = ... 
mouseY = ...

Vous obtenez la position du sprite

spriteX = ...
spriteY = ...

Vous trouvez l'angle

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

Votre mouvement sera:

moveX = Math.cos(angle) * speed * time;
moveY = Math.sin(angle) * speed * time;
AturSams
la source
Conseil: créez un tableau (tableau) pour cos et sin avec des valeurs précalculées. vous pouvez donc simplement faire cosTable [(int) angle] * speed * time et sinTable [(int) angle] * speed * time Ce n'est pas aussi précis. Mais vous obtenez vos valeurs beaucoup plus rapidement.
Sidar
Cela déplacera le sprite vers la souris, mais ce n'est pas la même chose que la direction du sprite. Le sprite peut toujours tourner pour faire face à la souris si sa vitesse de rotation est limitée ou pour une autre raison. Fondamentalement, vous répondez à la mauvaise question.
MichaelHouse
@ Byte56, il a dit "Quand je frappe" en avant ", le sprite ne se déplace pas nécessairement vers la souris" Je pense que c'est ce qu'il a demandé. Vous pourriez avoir raison cependant.
AturSams du
C'est un peu ambigu, c'est sûr. Je viens de passer par défaut au titre de la question dans ce cas. Ne vous méprenez pas, votre réponse est bonne. Je suppose que nous découvrirons ce que le PO voulait quand / s'il reviendrait.
MichaelHouse
2
@Sidar Ce serait une optimisation prématurée. Construire des tables sin / cos sans identifier les opérations sin / cos comme goulot d'étranglement est une perte de temps.
bummzack