版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhenyu5211314/article/details/85115516
首先要将startPoint和endPoint转化成一个y轴坐标,然后控制controlPoint_1和controlPoint_2来绘制一个轴对称的抛物线,用height来控制抛物线高度
/*创建一个抛物线动作
参数:
time 时间
startPoint 开始点
endPoint 结束点
height 高度(影响抛物线的高度)
angle 角度(贝塞尔曲线两个控制点与y轴的夹角,直接影响精灵的抛出角度)
*/
createBezierLinsBetweenIslands: function(linePanel, startPoint, endPoint, islast) {
var flipx = (endPoint.x < startPoint.x) ? true : false;
linePanel.setAnchorPoint(cc.p(0, 0));
linePanel.setPosition(startPoint);
var radian = 0;
if (endPoint.y != startPoint.y) {
var dirCur = cc.p(endPoint.x - startPoint.x, endPoint.y - startPoint.y);
var normal = cc.p(1, 0);
radian = cc.pAngleSigned(dirCur, normal);
var angle = radian / 3.1415926 * 180.0;
linePanel.setRotation(angle);
linePanel.lineRotation = angle;
endPoint.x = startPoint.x + (endPoint.x - startPoint.x) / Math.cos(radian);
endPoint.y = startPoint.y;
}
// 创建贝塞尔曲线
var height = 150;
// 第一个控制点为抛物线左半弧的中点
var q1x = startPoint.x + (endPoint.x - startPoint.x) * 0.35;
// 第二个控制点为整个抛物线的中点
var q2x = startPoint.x + (endPoint.x - startPoint.x) * 0.65;
var bezierConfig = {};
bezierConfig.controlPoint_1 = cc.p(q1x, height + startPoint.y);
bezierConfig.controlPoint_2 = cc.p(q2x, height + startPoint.y);
bezierConfig.endPosition = cc.p(endPoint.x, endPoint.y);
linePanel.bezier = bezierConfig;
var footNum = Math.abs(endPoint.x - startPoint.x) / 25;
var boatDelay = (footNum+1) * 0.2;
var boatSailTime = 15 - boatDelay;
for (var i = 0; i <= footNum; ++i) {
var dt = i * (1.0 / footNum);
var dt_next = (i + 1) * (1.0 / footNum);
var curPos = this.getBezieratPos(startPoint, bezierConfig, dt);
var nextPos = this.getBezieratPos(startPoint, bezierConfig, dt_next);
var dirCur = cc.p(nextPos.x - curPos.x, nextPos.y - curPos.y);
var normal = cc.p(1, 0);
var angle = cc.pAngleSigned(dirCur, normal) / 3.1415926 * 180.0;
var linePos = cc.p(curPos.x - startPoint.x, curPos.y - startPoint.y);
var _line = this._lineOne.clone();
_line.setPosition(linePos);
_line.setRotation(angle);
linePanel.addChild(_line, 10);
_line.runAction(cc.Sequence.create(
cc.DelayTime.create(i * 0.2),
cc.Show.create(),
cc.DelayTime.create(0.5+boatDelay+i*(boatSailTime/(footNum+1.0)-0.2)),
cc.CallFunc.create( function (sender) {
sender.loadTexture("res/ui/seaWorld/Route02.png");
}, this)
));
cc.log("pos line : "+ i + "__"+linePos.x+"__"+linePos.y);
}
var boatBezierConfig = this.translateBezierWithRadian(startPoint, bezierConfig, -radian);
this._mineBoatPanel.runAction(cc.Sequence.create(
cc.DelayTime.create(boatDelay),
cc.CallFunc.create( function (sender) {
this._mineBoat.setFlippedX(flipx);
this._mineBoat.effect.setVisible(true);
}, this),
cc.bezierTo(boatSailTime, [boatBezierConfig.controlPoint_1, boatBezierConfig.controlPoint_2, boatBezierConfig.endPosition]),
cc.CallFunc.create( function (sender) {
if (islast) {
this._mineBoat.effect.setVisible(false);
for (var i = 0; i < this._lineList.length; i++) {
this._lineList[i].removeFromParent();
}
this._lineList = [];
}
this.updateSailStatus(false);
}, this)
));
},
然后要根据绘制曲线的中间x轴坐标计算曲线中的y轴坐标来绘制线段
getBezieratPos: function(startPoint, config, dt) {
//bezierat( float a, float b, float c, float d, float t )
var bezierConfig = {};
bezierConfig.controlPoint_1 = cc.p(config.controlPoint_1.x - startPoint.x, config.controlPoint_1.y - startPoint.y);
bezierConfig.controlPoint_2 = cc.p(config.controlPoint_2.x - startPoint.x, config.controlPoint_2.y - startPoint.y);
bezierConfig.endPosition = cc.p(config.endPosition.x - startPoint.x , config.endPosition.y -startPoint.y);
var xa = 0;
var xb = bezierConfig.controlPoint_1.x;
var xc = bezierConfig.controlPoint_2.x;
var xd = bezierConfig.endPosition.x;
var ya = 0;
var yb = bezierConfig.controlPoint_1.y;
var yc = bezierConfig.controlPoint_2.y;
var yd = bezierConfig.endPosition.y;
var x = (Math.pow(1-dt,3) * xa + 3*dt*(Math.pow(1-dt,2))*xb + 3*Math.pow(dt,2)*(1-dt)*xc + Math.pow(dt,3)*xd );
var y = (Math.pow(1-dt,3) * ya + 3*dt*(Math.pow(1-dt,2))*yb + 3*Math.pow(dt,2)*(1-dt)*yc + Math.pow(dt,3)*yd );
var ret_pot = cc.p(startPoint.x,startPoint.y);
return cc.p(ret_pot.x + x , ret_pot.y + y);
},
最后船只要根据cc.bezierTo动作进行贝塞尔曲线移动,保证动作参数和绘制路线一致,动作参数boatBezierConfig需要根据起始点和转角进行转换
translateBezierWithRadian: function(startPoint, config, radian) {
var boatBezierConfig = {};
boatBezierConfig.controlPoint_1 = cc.p((config.controlPoint_1.x - startPoint.x)*Math.cos(radian) + startPoint.x - 150*Math.sin(radian), (config.controlPoint_1.x - startPoint.x)*Math.sin(radian) + startPoint.y + 150*Math.cos(radian));
boatBezierConfig.controlPoint_2 = cc.p((config.controlPoint_2.x - startPoint.x)*Math.cos(radian) + startPoint.x - 150*Math.sin(radian), (config.controlPoint_2.x - startPoint.x)*Math.sin(radian) + startPoint.y + 150*Math.cos(radian));
boatBezierConfig.endPosition = cc.p((config.endPosition.x - startPoint.x)*Math.cos(radian) + startPoint.x, (config.endPosition.x - startPoint.x)*Math.sin(radian) + startPoint.y);
return boatBezierConfig;
},