私は 2D ピンボール ゲームを作成しており、ショートカットとしてヒット ボックスに BoundingSphere を使用しています。
私が抱えている問題は、多くのものが常に回転しており、ボールが他の円形のオブジェクトに当たったときの「正確な」反発角度を計算する方法を考え出す必要があることです。
どんな助け、ナッジ、手がかりも大歓迎です
/編集何も見つかりませんでしたが、なんとかこれを解決しました。
これは、2 つの BoundingSphere 間の衝突が検出されると呼び出されます。
private void CollisionRebound(Sprites.BaseSprite attacker, Vector2 defender)
{
//Work out the rotation that would result in a "dead on" collision
//thus rebounding the attacker straight back the way they came.
float directHitRotation = (float)Math.Atan2(defender.Y - attacker.Position.Y , defender.X - attacker.Position.X);
//only really needed if the rotation is a negative value but is easier to work from in general.
float attackerRotation = attacker.rotation;
//This makes the rotation a positive number, it cant be less that -2PI
//so adding 2PI will leave us with a positive rotation.
if (attackerRotation < 0)
{
attackerRotation += (float)(Math.PI * 2);
}
//If the rotation is greater than the "dead on" rotation the rotation
//needs to increase.
if (attackerRotation > directHitRotation)
{
//we add "PiOver2" or "90 degrees" to "dead on" rotation because we do, dont know enough
//trig to explain it just know it works, we then add 90 degrees minus the difference between
//our two rotation to give us our outgoing angle, the +0.01f is for the rare case where the
//difference is 90 which would give us no change in rotation but if the two spheres have collided
//(which they have to before coming to this code chunk) there will be at least some change.
attackerRotation = directHitRotation + (float)MathHelper.PiOver2 + ((float)MathHelper.PiOver2 -
(attackerRotation - directHitRotation) + 0.01f);
}
//If the rotation is less than the "dead on" rotation the rotation
//need to decrease.
else if (attackerRotation < directHitRotation)
{
//same as previous chunk but we will be minusing the angle
attackerRotation = directHitRotation - (float)MathHelper.PiOver2 - ((float)MathHelper.PiOver2 -
(attackerRotation - directHitRotation) - 0.01f);
}
else if (attackerRotation == directHitRotation)
{
//either of the two calculations could be used here but would result in the same outcome
//which is rotating the attacker 180 degrees, so just add 2PI instead.
attackerRotation += (float)Math.PI;
}
//Here we just assign out new output rotation to the attacker entity.
attacker.rotation = attackerRotation;
}
「攻撃者」が「防御者」に時々くっつくだけですが、これを修正するための提案はありますか?
コードの使用に関心のある他のユーザー向けにコードを説明するコメントを追加しました。