/ / 2Dのゲームの動きのエンジンを作ることにこだわった - 2d

2Dのゲームの動きのエンジン作りにこだわった - 2d

トップダウンの2Dゲームのための動きエンジンを作っていますが、次の問題を解決しようとしています。

  • プレーヤーは矢印キーを使用して移動することができ、それぞれの方向であなたを加速させます。摩擦があるので、瞬時にではなく、キーを離した後で動きを止めます。
  • 2つの垂直キーを保持すると、この45°の方向に1つの軸と同じ速度で加速します
  • あなたの上には加速できない最高速度があります 徒歩でこれは明らかに最大歩行速度を制限します。あなたはノックアウトすることができ、したがってこのスピードを超えます。
  • あなたがmaxより速く動くならば。 walkspeedを使用すると、反対方向にキーを押したままにすると速度がさらに速くなります

摩擦のない最初のポイントの擬似コード:

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で左に移動して押し下げ始めると、動きの方向がほとんど変わらない、という厄介な副作用がありました。

その後、私はベクトルを使って数多くの製品、相違点などについて考え始めましたが、ほとんどこれをフォローしたり、早期の問題に遭遇したりしませんでした。

結論として、誰かがシステムを説明できるか上記のすべての点を満たしているか、このようなシステムをどのように実装できるかを説明する記事を参照してください。複雑なものを示唆することを心配しないで、しばらく与えられた難しい概念さえも把握できます。

ご協力いただきありがとうございます!

回答:

回答№1は1

申し訳ありませんが、これについて1日以上考えることはできませんが、私はそれを解決することができ、2行のコードはありません(アイデアの皆様にもありがとうございます)

私は怠惰で疲れているので、次の2つの方法を除いて、擬似コードに変更しません。

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

短いかもしれないし、もう少し最適化することができますが、それは動作します。私はこれが将来この問題につまずく人を助けることを願っています。


回答№2の場合は0

下に追加:

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

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

どこで int sign(x) { x <0の場合 -1を返します。 }


回答№3の場合は0

私は位置に加えてプレーヤーに特定の速度を関連付けることを提案し、矢印キーが押されたときにその速度をmaxSpeedに対してチェックするだけである。

速度が最大スピードを超えていて、反対側の矢印キーが押されている場合は、現在の速度をmaxSpeedより上に保ち、単純に負の加速度を適用します。