我正在为自上而下的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;
}
可以更短,可以更优化,但是可以。希望这对以后遇到此问题的人有所帮助。