Stuck on creating a 2D motion engine

I am making a motion mechanism for my 2D top-down game, but I am stuck trying to solve the following problem:

  • The player can be moved using the arrow keys, which accelerate you in the appropriate directions. There is friction, so you stop moving after you release the keys, although not right away.
  • When you hold two perpendicular keys, you are accelerated in this direction by 45 ° at the same speed as on the same axis.
  • There is a maximum speed that you cannot accelerate above you , having passed , which also limits your maximum walking speed. You can be dropped and thus exceed this speed.
  • If you are moving faster max. walkspeed, you can slow down if you hold the keys in the opposite direction.

Pseudocode for the first point without friction:

gameTick(){

  tempX += LeftKeyHeld ? -1 : 0;
  tempX += RightKeyHeld ? 1 : 0;
  tempY += UpKeyHeld ? -1 : 0;
  tempY += DownKeyHeld ? 1 : 0;
  ratio = 0.71;

  if( |tempX| == |tempY| ) {
    tempX =tempX* ratio;
    tempY =tempY* ratio;
  }
  player.x += tempX;
  player.y += tempY;
}

I can solve the friction (by getting the length of the motion vector, decreasing it by the friction, projecting it with the same x: y ratio), however I cannot wrap my head around getting maxSpeed.

I tried the decision not to let the player walk at all when higher than maxSpeed, but this violates point 4. In addition, it had an unpleasant side effect: when you moved to MaxSpeed ​​to the left and started to click, the direction of movement did not change or barely changed.

Then I started thinking about the many products, differences and other things with vectors, but basically I could no longer follow it or ran into early problems.

, - , , , , ? , - , , .

!

+3
3

, , , . ( )

, , :

updateGame(){
  player.walk();
  player.move();
}
player.move(){
  player.x += player.speedX
  player.y += player.speedY
}  

(java):

public void walk() {
    float tempX = 0;
    float tempY = 0;
    float accelX;
    float accelY;
    float nextSpeedX;
    float nextSpeedY;
    float nextSpeed;
    float speed;
    tempX += walkLeft ? -1 : 0;
    tempX += walkRight ? 1 : 0;
    tempY += walkUp ? -1 : 0;
    tempY += walkDown ? 1 : 0;

    if (Math.abs(tempX) == Math.abs(tempY)) {
        tempX = (float) tempX * rat;
        tempY = (float) tempY * rat;
    }

    accelX = tempX * (float) runSpeed;
    accelY = tempY * (float) runSpeed;
    speed = (float) Math.sqrt(speedX * speedX + speedY * speedY);
    nextSpeedX = speedX + accelX;
    nextSpeedY = speedY + accelY;
    nextSpeed = (float) Math.sqrt(nextSpeedX * nextSpeedX + nextSpeedY * nextSpeedY);

    if (nextSpeed > maxSpeed) { //can't accelerate by running
        if (nextSpeed > speed) {  //wants to accelerate
            if (speed > maxSpeed) {  //the current speed is larger than maximum.
                float diff = (float)(speed / nextSpeed);
                float greenX = nextSpeedX*diff;
                float greenY = nextSpeedY*diff;
                accelX = greenX-speedX;
                accelY = greenY-speedY;
            } else { //speed <= maxspeed
                float diff = (float)(maxSpeed / nextSpeed);
                float greenX = nextSpeedX*diff;
                float greenY = nextSpeedY*diff;
                accelX = greenX-speedX;
                accelY = greenY-speedY;
            }
        } else { //wants to slow! allow it!
            //acceleration doesn't need to be changed
        }
    } else { //no problem, allow it!
        //acceleration doesn't need to be changed
    }
    speedX += accelX;
    speedY += accelY;
}

, , . , , .

+1

:

 If (|tempX|>maxSpeed)
   tempX=maxSpeed*sign(tempX);

 If (|tempY|>maxSpeed)
   tempY=maxSpeed*sign(tempX);

   int sign (x)    {         x < 0         return -1;    }

0

I would suggest associating a certain speed with the player in addition to the position and only check this speed against maxSpeed ​​when pressing the arrow keys.

If the DOES speed exceeds maxSpeed ​​but the arrow keys are pressed on the opposite side, you should keep the current speed above maxSpeed ​​and just apply negative acceleration.

0
source

All Articles