游戏中,经常会遇到发射炮弹的问题,通常是知道大炮的位置,知道目标位置,求炮弹运动轨迹。
我们可以用贝塞尔曲线来生成运动轨迹,可以得到一个比较漂亮的曲线,但是使用贝塞尔曲线有一个问题,就是运动速度不符合物理规律。炮弹的运动轨迹应该是一条“抛物线”(我们姑且就叫它抛物线)。
根据给定的条件,是不足以计算出运动轨迹的,需要在给定一些条件,比如发射角度,或者初始x或y方向的速度,如果没有附加条件,我们需要自己加一些约束。
下面的方法对于速度(或时间)做了约束。
var g:Number=1;
stage.addEventListener(MouseEvent.CLICK,clickHandler);
function clickHandler(e:MouseEvent):void{
var zidan:MovieClip=new Mc();
addChild(zidan);
zidan.x=mc.x;
zidan.y=mc.y;
fashe(zidan,stage.mouseX,stage.mouseY);
}
function fashe(zidan:MovieClip,targetX:Number,targetY:Number):void{
//计算距离
var dis:Number=Math.sqrt((targetX-zidan.x)*(targetX-zidan.x)+(targetY-zidan.y)*(targetY-zidan.y));
//根据距离粗略算出一个时间
var v:Number=Math.sqrt(Math.abs(2*dis*g))*1.0;//最后乘的1.0可以调整。
var t:Number=v/g;
//根据算出的时间,计算xy方向的初始速度
zidan.vx0=(targetX-zidan.x)/t;
zidan.vy0=(targetY-zidan.y-0.5*g*t*t)/t;
//记录总时间
zidan.totalT=t;
//计时器清0
zidan.t=0;
//记录初始坐标
zidan.ox=zidan.x;
zidan.oy=zidan.y;
//定时刷新位置
zidan.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
//trace(zidan.vx0,zidan.vy0,t);
}
function enterFrameHandler(e:Event):void{
var zidan:MovieClip=e.currentTarget as MovieClip;
zidan.t+=1;//时间递增
if(zidan.t>=zidan.totalT){
zidan.t=zidan.totalT;
zidan.removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
zidan.parent.removeChild(zidan);
}
//更新坐标
zidan.x=zidan.vx0*zidan.t+zidan.ox;
zidan.y=zidan.vy0*zidan.t+0.5*g*zidan.t*zidan.t+zidan.oy;
}效果(点击舞台,发射炮弹):
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。