- 通过简单的直线相交,判定玩家是否射击打中了敌人,在类似的射击游戏的碰撞检测中没有必要用到物理引擎,就可以通过这种方式判断是否击中的队友。
以下代码来源 smart fox server Fps Demo
// Checking if the player hits enemy using simple line intersection and
// the known players position and rotation angles
private boolean checkHit(CombatPlayer player, CombatPlayer enemy) {
if (enemy.isDead()) {
return false;
}
// First of all checking the line intersection with enemy in top projection
double radius = enemy.getCollider().getRadius();
double height = enemy.getCollider().getHeight();
double myAngle = player.getTransform().getRoty();
double vertAngle = player.getTransform().getRotx();
// Calculating an angle relatively to X axis anti-clockwise
double normalAngle = normAngle(360 + 90 - myAngle);
//Calculating the angle of the line between player and enemy center point
double difx = enemy.getX() - player.getX();
double difz = enemy.getZ() - player.getZ();
double ang = 0;
if (difx == 0) {
ang = 90;
}
else {
ang = Math.toDegrees(Math.atan(Math.abs(difz / difx)));
}
// Modifying angle depending on the quarter
if (difx <= 0) {
if (difz <= 0) {
ang += 180;
}
else {
ang = 180 - ang;
}
}
else {
if (difz <= 0) {
ang = 360 - ang;
}
}
ang = normAngle(ang);
// Calculating min angle to hit
double angDif = Math.abs(ang - normalAngle);
double d = Math.sqrt(difx * difx + difz * difz);
double maxDif = Math.toDegrees(Math.atan(radius / d));
if (angDif > maxDif) {
return false;
}
// Now calculating the shot in the side projection
// Correction value to fit the model visually (as the collider may not totally fit the model height on client)
final double heightCorrection = 0.3;
if (vertAngle > 90) {
vertAngle = 360 - vertAngle;
}
else {
vertAngle = -vertAngle;
}
double h = d * Math.tan(Math.toRadians(vertAngle));
double dif = enemy.getTransform().getY() - player.getTransform().getY() - h + heightCorrection;
if (dif < 0 || dif > height) {
return false;
}
return true;
}
private double normAngle(double a) {
if (a >= 360) {
return a - 360;
}
return a;
}