13
\$\begingroup\$

I'm using Java/Slick 2D. I'm trying to use the mouse to rotate the sprite and the arrow keys to move the sprite. I can get the sprite to rotate no problem, but I cannot get it to move in the direction it is supposed to. When I hit "forwards", the sprite doesn't necessarily move towards the mouse. Actually, it will only move towards the left of the screen really. I'm sure there has to be some standard code for this since many games use this style of motion. Can anyone help me out with what the trig is supposed to be? Thanks

EDIT: Here is the rotation code (which does something else weird: https://stackoverflow.com/questions/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); 

And the movement code. I can only move towards the left of the screen...

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;
            }
\$\endgroup\$
4
  • \$\begingroup\$ What's the point of the code you've added? Is this a new problem? If it's a new problem, please open a new question. Please only update this question with information related to moving the sprite in the direction it's facing. \$\endgroup\$
    – House
    Commented Sep 28, 2012 at 18:15
  • \$\begingroup\$ No it's the code I used that caused the problem. See the comments below. Someone asked for it. \$\endgroup\$
    – rphello101
    Commented Sep 28, 2012 at 19:21
  • \$\begingroup\$ I don't see where you calculate sprite.movespeed? \$\endgroup\$
    – AturSams
    Commented Sep 28, 2012 at 20:00
  • \$\begingroup\$ movespeed is a constant, in this case set at .3 \$\endgroup\$
    – rphello101
    Commented Sep 29, 2012 at 22:33

2 Answers 2

16
\$\begingroup\$

You'll want to get a vector based on your current velocity and heading. Then use that vector to increment your 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;

So now you know your velocity based on your rotation. You can the update your position with that information.

//Update the position based on our current speed
//This is basic s = vt physics
position.x += velocity.x * timeElapsed;
position.y += velocity.y * timeElapsed;
\$\endgroup\$
4
  • \$\begingroup\$ For a (sloppy) class that contains all this, you can see a Ludum Dare 21 entry I put together here: bitbucket.org/byte56/ld21/src/af3dfc2c4c48/src/Byte56_LD21/… \$\endgroup\$
    – House
    Commented Sep 24, 2012 at 21:18
  • \$\begingroup\$ Thank you. After a few modifications, this did work. I have another question for you though if you happen to read this: getting the sprite to move backwards is just -= of what you have here. How do I make it move left or right though? \$\endgroup\$
    – rphello101
    Commented Oct 2, 2012 at 16:31
  • \$\begingroup\$ @rphello101 Good question, you should ask a new question. More people will benefit and you may get a better answer than the one I have. \$\endgroup\$
    – House
    Commented Oct 2, 2012 at 16:45
  • \$\begingroup\$ What is direction an instance of here? I tried implementing the above code using just float, but it doesn't quite work. I think I need to add that if statement, but I don't know what it does. \$\endgroup\$
    – qwerty
    Commented Jul 23, 2020 at 23:17
3
\$\begingroup\$

You get the mouse position

mouseX = ... 
mouseY = ...

You get the sprite position

spriteX = ...
spriteY = ...

You find the angle

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

Your movement will be:

moveX = Math.cos(angle) * speed * time;
moveY = Math.sin(angle) * speed * time;
\$\endgroup\$
9
  • \$\begingroup\$ As a tip : Create a table( array ) for cos and sin with pre-computed values. so you can just do cosTable[(int)angle] * speed * time and sinTable[(int)angle] * speed * time It's not as accurate. But you get your values way faster. \$\endgroup\$
    – Sidar
    Commented Sep 24, 2012 at 20:42
  • \$\begingroup\$ This will move the sprite towards the mouse, but that is not the same as the direction the sprite is facing. The sprite could still be turning to face the mouse if it's rotation speed is capped or some other reason. Basically, you're answering the wrong question. \$\endgroup\$
    – House
    Commented Sep 24, 2012 at 21:01
  • \$\begingroup\$ @Byte56 he said "When I hit "forwards", the sprite doesn't necessarily move towards the mouse" I think that is what he asked about. You could be right though. \$\endgroup\$
    – AturSams
    Commented Sep 25, 2012 at 4:30
  • \$\begingroup\$ It's kind of ambiguous for sure. I just defaulted to the title of the question in this case. Don't get me wrong, your answer is good. I guess we'll find out what the OP wanted when/if they come back. \$\endgroup\$
    – House
    Commented Sep 25, 2012 at 4:39
  • 2
    \$\begingroup\$ @Sidar That would be premature optimization. Building sin/cos tables without identifying the sin/cos operations as bottleneck is a waste of time. \$\endgroup\$
    – bummzack
    Commented Sep 25, 2012 at 7:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .