Libgdx 近战攻击碰撞检测
Libgdx Melee Attack Collision Detection
我有一个带有 3D 模型实例的 3D 场景;我想做碰撞检测。我目前正在学习本教程 (http://blog.xoppa.com/using-the-libgdx-3d-physics-bullet-wrapper-part1/)。不过,我想要的有点复杂。
有一个角色(一个 knight.g3db 模型,是 Libgdx 基本 3d 模型类的示例代码的一部分),它可以用剑攻击。我还有另一个模型实例,我想 "attack" 用剑。
检查两个对象是否发生碰撞不是问题,因为可以从 Bullet 库中轻松检测到。我想要的可能是以下内容,但我不确定如何实现:
- 以剑为碰撞对象,或
- 如果只有骑士 "box" 的前部与其他物体发生碰撞,或者
则执行检查
- 在骑士角色前面创建一个单独的不可见虚拟框,并在发生碰撞时将其用作基础。
您是否知道有任何参考资料可以做到这一点(如果上述建议的解决方案甚至可行的话)?或者如果有更好的解决办法,请告诉我。
我要避免的是:骑士在另一个物体背后攻击时仍然被击中。
提前致谢。
如果你只是想避免你背后的敌人被击中,你可以检查你是否面对他们。我假设你有一个移动方向矢量,检查该矢量的旋转与根据你的位置和敌人计算的矢量的差异。
类似这样的事情(免责声明:出乎我的意料,不确定这是否有效,只是给你一个想法):
float yourAngle = direction.angle();
float enemyAngle = new Vector2(enemyPos.x - playerPos.X, enemyPos.y - playerPos.y).angle();
if (yourAngle - enemyAngle < 30 && yourAngle - enemyAngle > -30) //enemy within a 60 degree cone in front of you.
这可能不是理想的解决方案,但它确实是一种廉价的解决方案,而且可能效果很好。
这些是我用来检查敌人对象是否在英雄的 'field of view' 范围内的代码(工作代码):
/**
*
* @param localAngle - the current yaw of the Player
* @param angleTarget - the angle between the player and the target receipent of the attack -- use RotationHelper.angle() method
* @param offset - the difference in localAngle(hero) and angleTarget(enemy)
* @return
*/
public static float angleDifference(float localAngle, float angleTarget, int offset) {
float newLocalAngle = (convert180to360(localAngle) + offset) % 360;
AppLog.log("ANGLE_DIFFERENCE2", "localAngle(yaw, degrees, with offset): " + newLocalAngle + ", angleTarget: " + angleTarget);
float result = 180 - Math.abs(Math.abs(newLocalAngle - angleTarget) - 180);
AppLog.log("ANGLE_DIFFERENCE2", "result : " + result);
AppLog.log("ANGLE_DIFFERENCE2", "==================================");
return result;
}
public static float angle(Vector3 vectorA, Vector3 vectorB) {
return new Vector2(vectorB.x - vectorA.x, (-vectorB.z) - (-vectorA.z)).angle();
}
public static float convert180to360(float originalAngle) {
float newAngle = 0;
if(originalAngle < 0) {
newAngle = (originalAngle + 180) + 180;
} else {
newAngle = originalAngle;
}
return newAngle;
}
感谢@Menno Gouw 提出从 Vector3 获取角度的想法。
下面的代码是我如何使用这些辅助方法的:
float angleTarget = RotationHelper.angle(hero.transform.getTranslation(hero.tmpVector), enemy.transform.getTranslation(enemy.tmpVector));
float angleDifference = RotationHelper.angleDifference(hero.transform.getRotation(playerObject.tmpRotation).nor().getYaw(), angleTarget, CHARACTER_TO_WORLD_ROTATION_OFFSET);
AppLog.log("ANGLE_DIFFERENCE2", " angle from point hero to enemy): " + angleTarget);
if(angleDifference < VIEW_ANGLE_THRESHOLD) { //use 'angleDifference < VIEW_ANGLE_THRESHOLD'
enemy.hurt(hero.stats.damage);
AppLog.log("HERO_STATE", "Enemy monkey hit!");
}
if(enemy.stats.hp <= 0) {
AppLog.log("ENEMY_STATE", "Dead monkey");
//TODO: Remove monkey from game
enemy.die();
instances.removeValue(gameObject, true);
}
如果您遇到同样的问题,希望这对您有所帮助。如果有改进或问题,请随时进行更改。
我有一个带有 3D 模型实例的 3D 场景;我想做碰撞检测。我目前正在学习本教程 (http://blog.xoppa.com/using-the-libgdx-3d-physics-bullet-wrapper-part1/)。不过,我想要的有点复杂。
有一个角色(一个 knight.g3db 模型,是 Libgdx 基本 3d 模型类的示例代码的一部分),它可以用剑攻击。我还有另一个模型实例,我想 "attack" 用剑。
检查两个对象是否发生碰撞不是问题,因为可以从 Bullet 库中轻松检测到。我想要的可能是以下内容,但我不确定如何实现:
- 以剑为碰撞对象,或
- 如果只有骑士 "box" 的前部与其他物体发生碰撞,或者 则执行检查
- 在骑士角色前面创建一个单独的不可见虚拟框,并在发生碰撞时将其用作基础。
您是否知道有任何参考资料可以做到这一点(如果上述建议的解决方案甚至可行的话)?或者如果有更好的解决办法,请告诉我。
我要避免的是:骑士在另一个物体背后攻击时仍然被击中。
提前致谢。
如果你只是想避免你背后的敌人被击中,你可以检查你是否面对他们。我假设你有一个移动方向矢量,检查该矢量的旋转与根据你的位置和敌人计算的矢量的差异。
类似这样的事情(免责声明:出乎我的意料,不确定这是否有效,只是给你一个想法):
float yourAngle = direction.angle();
float enemyAngle = new Vector2(enemyPos.x - playerPos.X, enemyPos.y - playerPos.y).angle();
if (yourAngle - enemyAngle < 30 && yourAngle - enemyAngle > -30) //enemy within a 60 degree cone in front of you.
这可能不是理想的解决方案,但它确实是一种廉价的解决方案,而且可能效果很好。
这些是我用来检查敌人对象是否在英雄的 'field of view' 范围内的代码(工作代码):
/**
*
* @param localAngle - the current yaw of the Player
* @param angleTarget - the angle between the player and the target receipent of the attack -- use RotationHelper.angle() method
* @param offset - the difference in localAngle(hero) and angleTarget(enemy)
* @return
*/
public static float angleDifference(float localAngle, float angleTarget, int offset) {
float newLocalAngle = (convert180to360(localAngle) + offset) % 360;
AppLog.log("ANGLE_DIFFERENCE2", "localAngle(yaw, degrees, with offset): " + newLocalAngle + ", angleTarget: " + angleTarget);
float result = 180 - Math.abs(Math.abs(newLocalAngle - angleTarget) - 180);
AppLog.log("ANGLE_DIFFERENCE2", "result : " + result);
AppLog.log("ANGLE_DIFFERENCE2", "==================================");
return result;
}
public static float angle(Vector3 vectorA, Vector3 vectorB) {
return new Vector2(vectorB.x - vectorA.x, (-vectorB.z) - (-vectorA.z)).angle();
}
public static float convert180to360(float originalAngle) {
float newAngle = 0;
if(originalAngle < 0) {
newAngle = (originalAngle + 180) + 180;
} else {
newAngle = originalAngle;
}
return newAngle;
}
感谢@Menno Gouw 提出从 Vector3 获取角度的想法。
下面的代码是我如何使用这些辅助方法的:
float angleTarget = RotationHelper.angle(hero.transform.getTranslation(hero.tmpVector), enemy.transform.getTranslation(enemy.tmpVector));
float angleDifference = RotationHelper.angleDifference(hero.transform.getRotation(playerObject.tmpRotation).nor().getYaw(), angleTarget, CHARACTER_TO_WORLD_ROTATION_OFFSET);
AppLog.log("ANGLE_DIFFERENCE2", " angle from point hero to enemy): " + angleTarget);
if(angleDifference < VIEW_ANGLE_THRESHOLD) { //use 'angleDifference < VIEW_ANGLE_THRESHOLD'
enemy.hurt(hero.stats.damage);
AppLog.log("HERO_STATE", "Enemy monkey hit!");
}
if(enemy.stats.hp <= 0) {
AppLog.log("ENEMY_STATE", "Dead monkey");
//TODO: Remove monkey from game
enemy.die();
instances.removeValue(gameObject, true);
}
如果您遇到同样的问题,希望这对您有所帮助。如果有改进或问题,请随时进行更改。