Я использую вращающуюся пушку на танке. Пушка NPC следует за танком игрока (автоматически вращается).
Я рассчитываю:
Math.min
и Math.abs
после googling)Проблема в том, что прыжок с 0 градусов до 360 или от 360 до 0 делает пушку "свободным" в танке игрока, и пушка вращается один раз вокруг.
Сейчас это делается так:
Vector2 Tank2Enemy = tank.getPosition().sub(closestEnemyTank.getPosition());
float angleTank2Enemy = Tank2Enemy.angleRad(); // this is the angle of the vector tank -> enemy in radians
float angleCannon = tank.cannon.getOwnAngle(); // this is the cannon-angle in radians
float diffAngle = Math.min(Math.abs(angleCannon - angleTank2Enemy), MathUtils.PI - Math.abs(angleCannon - angleTank2Enemy));
if (diffAngle > 0.01f || diffAngle < -0.01f) { // dead zone
if (diffAngle > 0.01f) {
direction = -1; // this goes to cannon.getBody().setAngularVelocity(cannonAngularVelocity);
}
else if (diffAngle < 0.01f) {
direction = 1; // this goes to cannon.getBody().setAngularVelocity(cannonAngularVelocity);
}
}
return direction;
Хорошая практика заключается в том, чтобы угол всегда был положительным, например, чтобы не путаться с разными знаками в углах. Вы могли заметить, что угол 270 будет работать так же, как -90 градусов. Ваша проблема может быть решена путем простой проверки:
while(angle >= 2*Math.PI) //angle in radians
angle -= 2*Math.PI;
while(angle < 0)
angle += 2*Math.PI;
Обновление: я думаю, проблема кроется в том, как вы вычисляете diffAngle. Не могли бы вы попробовать следующее?
float diffAngle = angleCannon - angleTank2Enemy; // or angleTank2Enemy - angleCannon, depending on the direction of angles in your game
double sign = Math.signum(diffAngle);
float diffAngle = sign >= 0 ? Math.min(diffAngle, 2*MathUtils.PI - diffAngle) : Math.max(diffAngle, -(2*MathUtils.PI - diffAngle));
Хорошо, я решил это так:
if (angleTank2Enemy > angleCannon) {
diffAngle = angleTank2Enemy - angleCannon;
if (diffAngle > MathUtils.PI) {
rotDirRight = true;
}
else rotDirRight = false;
}
else {
diffAngle = angleCannon - angleTank2Enemy;
if (diffAngle > MathUtils.PI) {
rotDirRight = false;
}
else rotDirRight = true;
}
if ((diffAngle) > 0.05f) { // dead zone
if (rotDirRight) direction = 1; // this goes to cannon.getBody().setAngularVelocity(cannonAngularVelocity);
else direction = -1; // this goes to cannon.getBody().setAngularVelocity(cannonAngularVelocity);
}
return direction;