Keith Peters的<<Foundation ActionScript 3.0 Animation - Making Things Move>>一书中谈舞台边界反弹时,讲的方法主要是当对象超出边界时,简单的将目标与边界垂直的那个轴位移回来,调整到紧贴边界,如图1。
作者也详细的解释了这种处理方式存在的问题。因为真实情况下目标不可能到达图中虚线球的位置,所以实际上目标与边界平行的那个轴坐标也需要调整,那么应该位移多少呢?请看图2。我们把球沿着它来的方向轨迹往回拉,如图所示,绿球才是实际上正确的与边界接触的位置。
正如作者所说,这个小瑕疵在实际的应用当中基本可以忽略,只有当目标速度较快、每一帧的移动幅度较大或入射角度较小时才可能有视觉上的影响。作者也告诉了大家这个问题可以用三角函数解决。来看一下的已知数:图3。
我们知道球半径、当前位置(虚线球)和角度(用atan函数速度求出),要算出yd的值。大家看一下我的解决方法(数学初中水平,请见谅,完全是后来自己可汗学院补的)。
角度 = atan(y轴速度, x轴速度)
再算出xd这条边的值,xd = ball的半径 - (舞台宽度 - ball.x)
然后,斜边 = xd / cosθ
最后,yd = 斜边 * sinθ,再把这个值从y轴上减去就可以了。
最后附上实际的actionscript3的代码:
1 var left:Number = 0; 2 var top:Number = 0; 3 var right:Number = stage.stageWidth; 4 var bottom:Number = stage.stageHeight; 5 6 var angle:Number = Math.atan2(ball.vy, ball.vx); 7 var dist:Number = 0; 8 if (ball.x - ball.radius < left) 9 { 10 dist = (ball.x - ball.radius) / Math.cos(angle); 11 ball.y -= Math.sin(angle) * dist; 12 ball.x = ball.radius; 13 ball.vx *= bounce; 14 } 15 else if (ball.x + ball.radius > right) 16 { 17 dist = (ball.radius - (right - ball.x)) / Math.cos(angle); 18 ball.y -= Math.sin(angle) * dist; 19 ball.x = right - ball.radius; 20 ball.vx *= bounce; 21 } 22 23 if (ball.y - ball.radius < top) 24 { 25 dist = (ball.y - ball.radius) / Math.sin(angle); 26 ball.x -= Math.cos(angle) * dist; 27 ball.y = ball.radius; 28 ball.vy *= bounce; 29 } 30 else if (ball.y + ball.radius > bottom) 31 { 32 dist = (ball.radius - (bottom - ball.y)) / Math.sin(angle); 33 ball.x -= Math.cos(angle) * dist; 34 ball.y = bottom - ball.radius; 35 ball.vy *= bounce; 36 }
时间: 2024-10-12 15:32:56