Alex H.
Alex H.

Reputation: 89

Move canvas image across circular path

I am currently working on a 2D javascript game and I am doing the movement mechanics right now. I want players to be able to move forward and backward, towards or away from the mouse, while also having the ability to strafe.

I got the mouse following down pretty well but I am stuck on how to implement the strafing. I need my player to move along a dynamic circular path that changes sizes depending on how far away the player is from the mouse.

ex: If the mouse was the red X, I want to move the player along the green circular path. This path of course will be changing size based on how far away the player is from the mouse.

I am updating the players position by moving whenever the movement keys are pressed so I am really looking for an equation to move the player in the correct circular path that can be implemented in a "position updated every second" sort of way.

I know that for a circular path, the coordinates can be found by:

x = centerX * radius * Math.cos(theta); y = centerY * radius * Math.sin(theta);

But I am having trouble implementing. Here is some of my framework, but I am afraid all the solutions I have tried haven't even gotten me close so I will not post the broken math I have already deleted

  Player.prototype.update = function(delta){

       this.playerCenter = [this.x+this.width/2, this.y+this.height/2];

       let dX = (GAME.mouse.position.x - this.playerCenter[0]),
           dY = (GAME.mouse.position.y - this.playerCenter[1]);
           radius = Math.sqrt(dX * dX + dY * dY);


       // Movement Forward
       if(GAME.keyDown[87] && radius >= 50){
         this.x += (dX / radius) * this.movementSpeed * delta;
         this.y += (dY / radius) * this.movementSpeed * delta;
       }

       // Movement Backward
       if(GAME.keyDown[83]){
         this.x -= (dX / radius) * this.movementSpeed * delta;
         this.y -= (dY / radius) * this.movementSpeed * delta;
       }

       // Strafe left
       if(GAME.keyDown[65]){


       }

       // Strafe right
       if(GAME.keyDown[68]){

       }

     }

Upvotes: 0

Views: 191

Answers (1)

Blindman67
Blindman67

Reputation: 54026

You almost have the solution.

You need to go at 90 deg to the forward vector. To rotate a vector 90cw you swap the x,and y and negate the new x.

EG

dx = ?;  // forward direction
dy = ?;  
// rotate 90 clockwise
dx1 = -dy;
dy1 = dx;

Thus you can update your code as follows

   var dX = (GAME.mouse.position.x - this.playerCenter[0]);
   var dY = (GAME.mouse.position.y - this.playerCenter[1]);
   var  radius = Math.sqrt(dX * dX + dY * dY);
   //normalise       
   if(radius > 0){
       dX = (dX / radius) * this.movementSpeed * delta;
       dY = (dY / radius) * this.movementSpeed * delta;;
   }else{
       dX = dY = 0;  // too close need to set this or you will get NaN propagating through your position variables.
   }



   if(GAME.keyDown[87] && radius >= 50){ // Movement Forward
     this.x += dX;
     this.y += dY;
   }
   if(GAME.keyDown[83]){ // Movement Backward
     this.x -= dX;
     this.y -= dY;
   }
   if(GAME.keyDown[65]){ // Strafe left
      this.x += -dY;     // swap x and y negate new x to rotate vector 90
      this.y += dX; 
   }       
   if(GAME.keyDown[68]){ // Strafe right
      this.x -= -dY;     // swap x and y negate new x to rotate vector 90
      this.y -= dX; 
   }

Upvotes: 1

Related Questions