我正在为自上而下的2D游戏制作运动引擎,但在尝试解决以下问题时遇到了麻烦:


播放器可以使用箭头键移动,这些键会在各个方向上加速您的移动。有摩擦,因此您释放键后会停止移动,尽管不是立即。
按住两个垂直键时,您将在此45°方向上以与在一个轴上相同的速度加速
有一个最大速度,超过该速度您无法通过步行加速,这显然也限制了您的最大步行速度。您可能会被撞开,因此超过此速度。
如果移动速度超过最大速度。步行速度,如果您向相反方向按住键,则可以减慢速度


第一点的伪代码,没有任何摩擦:

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


我可以解决摩擦(获取运动矢量的长度,通过摩擦减小其长度,然后以相同的x:y比例将其投影回去),但是我无法全力以赴完成maxSpeed。

我尝试了一种解决方案,即不允许玩家在maxSpeed之上时完全行走,但这违反了第4点。此外,它还具有令人讨厌的副作用,即当您以MaxSpeed的速度向左移动并开始向下移动时,方向没有改变,或几乎没有改变。

然后,我开始考虑向量的众多乘积,差异和其他内容,但是我几乎不再遵循它,或者遇到了早期问题。

因此,总而言之,有人可以解释一个可以满足以上所有条件的系统,还是可以指向一篇文章,解释如何实现这样的系统?不用担心会提出一些复杂的建议,即使有一段时间,我也可以掌握困难的概念。

谢谢你的帮助!

最佳答案

抱歉,您花了一天多的时间才考虑这个问题,但是我设法解决了这一问题,它不是两行代码。 (尽管仍然感谢大家的想法)

因为我懒惰又累,所以除了以下两种方法外,我不会将其更改为伪代码:

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


可以更短,可以更优化,但是可以。希望这对以后遇到此问题的人有所帮助。

09-25 19:27