我正在用 javascript 制作一个游戏,其中一个对象应该从墙上反弹。我真的试图让它自己工作,但它从来没有正常工作。
假设有一个球在这个笼子里弹跳(蓝色 = 30°,棕色 = 60°);
球的坐标是已知的。运动的 Angular 是已知的。碰撞点 (P) 坐标是已知的。壁的 Angular 是已知的。球的位置正在使用此函数更新其在 setInterval 函数内的坐标:
function findNewPoint(x, y, angle, distance) {
var result = {};
result.x =(Math.cos(angle * Math.PI / 180) * distance + x);
result.y = (Math.sin(angle * Math.PI / 180) * distance + y);
return result;
因此,在发生碰撞时,应该有一个函数可以适本地改变球的 Angular 。这看起来是一个非常复杂的问题,因为即使我知道墙是 30°,知道球从哪一侧撞到它也很重要。我尝试使用“平面中一条线的反射”公式和一些向量,但它对我来说从来没有成功过。我不期待代码的完整答案,如果有人可以建议应该以何种方式对其进行编程,它也会有所帮助。
编辑: 谢谢你们的提示,我意识到是什么造成了最大的困惑;如果我用鼠标在 Canvas 上选择一个 Angular ,则起始坐标 (0,0) 位于左下角。但由于 Canvas 的起始坐标在左上角,因此必须考虑这一点。
基本上使用这个公式来计算 Angular :
function angle(cx, cy, ex, ey) {
var dy = ey - cy;
var dx = ex - cx;
var theta = Math.atan2(dy, dx);
theta *= 180 / Math.PI;
return theta;
如果球从 (50,50) 移动到 (100,100),则 Angular 将为 -45。
老实说,我是通过反复试验得出这些结果的,我不太明白为什么是 60 和 120。
最佳答案
动球用 Angular ,一遍又一遍的计算Cos/Sin是不明智的。而是使用具有组件 vx, vy
的单位速度方向矢量,如下所示:
new_x = old_x + vx * Velocity_Magnitude * Time_Interval
请注意,vx = Cos(angle), vy = Sin(angle)
,但使用方向法时,您很少需要使用三 Angular 函数。
Angular 为 Fi 的倾斜墙具有法线
nx = -Sin(Fi)
ny = Cos(Fi)
要找到反射,你需要计算速度和法线的点积
dot = vx * nx + vy * ny
反射变换后的速度:
vnewx = v.x - 2 * dot * n.x
vnewy = v.y - 2 * dot * n.y
使用这些值进一步移动
(请注意,您可以同时使用内部法线方向和外部法线方向,因为方向翻转会改变两个分量,并且 2 * dot * n.x
的符号保持不变)
例子:
horizontal moving right
vx=1, vy=0
30 degrees wall has normal
nx=-1/2, ny=Sqrt(3)/2
dot = -1/2
vnewx = 1 - 2 * (-1/2) * (-1/2) = 1/2
vnewy = 0 - 2 * (-1/2) * Sqrt(3)/2 = Sqrt(3)/2
(velocity direction angle becomes 60 degrees)
horizontal moving left
vx=-1, vy=0
330 degrees wall (left bottom corner) has normal
nx=1/2, ny=Sqrt(3)/2
dot = -1/2
vnewx = -1 - 2 * (-1/2) * (1/2) = -1/2
vnewy = 0 - 2 * (-1/2) * (Sqrt(3)/2) = Sqrt(3)/2
(velocity direction angle becomes 120 degrees)
关于javascript - 计算撞击倾斜墙壁后的 Angular 变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45154176/