注意:*完整的 JSFiddle 可以在我的文章底部找到*。
问题:我试图消灭所有触及 Canvas 中心蓝线的敌人。然而,事实并非如此,我的实现只是“成功了一半”。当一侧起作用时,另一侧不起作用。我该如何解决这个问题?
我尝试了什么:设置基本绘图函数后,我计算了碰撞对象的 x 和 y 之间的差异。使用毕达哥拉斯距离来计算两点之间的距离。最后检查距离是否小于或等于两个对象的组合半径。我使用反正切计算了物体运动的旋转。
我想到的替代解决方案:使用循环沿着蓝线创建各种不可见的圆圈或点作为碰撞接收器。问题是:它占用了更多的资源,而且一点也不优雅。
您最感兴趣的 Javascript 函数是:
function (player, spawn) {
return (this.distance(player, spawn) <= player.radius + spawn.radius) && (this.tangent(player, spawn) <= angle - Math.PI * 1);
}
Angular 为旋转的蓝线(带划线的半圆)的 Angular 。
this.tangent(player, spawn) <= angle - Math.PI * 1)
这仅适用于 -- 和 +- 部分。将 <= 更改为 >= 与预期相反。我需要找到一种从 -1 循环到 1 的方法。
this.tangent(player, spawn) >= angle - Math.PI * 2 && this.tangent(player, spawn) >= angle
适用于 --、-+、++ 但不适用于 +-(右下)。
所以最后我完全困惑为什么我的逻辑不起作用,但我很想知道如何实现这一点:
在 JSFiddle 下方:
我很高兴收到回复,因为我喜欢用 Javascript 学习新事物:)
编辑 (03.11.2015): 如果可能,只提供纯数学解决方案,但也可以随意发布其他解决方案。为了学习新技术,欢迎每一条信息。
最佳答案
简化了磁盘和圆弧之间的碰撞检测问题 http://jsfiddle.net/crl/2rz296tf/31 (编辑:@markE 建议 http://jsfiddle.net/crl/2rz296tf/32/ )(用于调试:http://jsfiddle.net/crl/2rz296tf/27/ )
一些用于比较 Angular 实用函数:
function mod(x, value){ // Euclidean modulo http://jsfiddle.net/cLvmrs6m/4/
return x>=0 ? x%value : value+ x%value;
}
function angularize(x){
return mod(x+pi, 2*pi)-pi;
}
碰撞检测:
var d_enemy_player = dist(enemy.pos, player.pos)
if (d_enemy_player>player.shieldradius-enemy.radius && d_enemy_player<player.shieldradius+enemy.radius){
//only worth checking when we are approaching the shield distance
var angle_enemy = atan2(enemy.pos.y-player.pos.y, enemy.pos.x-player.pos.x)
var delta_with_leftofshield = angularize(angle_enemy-player.angle-player.shieldwidth)
var delta_with_rightofshield = angularize(angle_enemy-player.angle+player.shieldwidth)
var delta_with_shield = angularize(angle_enemy-player.angle)
if (delta_with_leftofshield<0 && delta_with_rightofshield>0){
console.log('boom')
enemy.destroyed = true;
} else if(delta_with_shield>=0 ){
// check distance with right extremety of shield's arc
console.log('right')
var d_rightofshield_enemy = dist(enemy.pos, {x:player.pos.x+player.shieldradius*cos(player.angle+player.shieldwidth), y:player.pos.y+player.shieldradius*sin(player.angle+player.shieldwidth)});
if (d_rightofshield_enemy<enemy.radius){
console.log('right boom')
enemy.destroyed = true;
}
} else {
console.log('left')
var d_leftofshield_enemy = dist(enemy.pos, {x:player.pos.x+player.shieldradius*cos(player.angle-player.shieldwidth), y:player.pos.y+player.shieldradius*sin(player.angle-player.shieldwidth)});
if (d_leftofshield_enemy<enemy.radius){
console.log('left boom')
enemy.destroyed = true;
}
}
}
关于Javascript Canvas : Collision against enemies not entirely working when rotating player,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33454897/