cocos creator 模拟纸飞机运动动画
模拟纸飞机运动动画 PaperPlaneAnim
项目需要模拟一个纸飞机飞到目的地的动画,用cocos的moveto动画不能满足需求,因为纸飞机总是向着飞机头朝向移动。
所以需要考虑飞机头的朝向,计算目标点和飞机的夹角,飞机前进的过程中按转向角速度this.angularSpeed
修改飞机的角度angle
fly函数 传入飞机的目的地位置targetPos
,初始化数据
public fly(targetPos: cc.Vec2, cb?: () => void, circleAngle?) {this._targetCallBack = cb;targetPos = this.flyNd.parent.convertToNodeSpaceAR(targetPos);this._targetPos = targetPos;this._speed = 0;this._circleAngleCnt = 0;this._circleFactor = 0;this.circleAngle = circleAngle == null ? this.circleAngle : circleAngle;this._flyStatus = FlyStatus.AccCircle;
}
update里根据飞机的位置this.flyNd.position
和targetPos
计算得到夹角this._targetAngle
//计算目标位置在飞机的方位。let radian = Math.atan2(this.flyNd.y - this._targetPos.y, this.flyNd.x - this._targetPos.x);
this._targetAngle = 180 / Math.PI * radian;
this._targetAngle = (360 + this._targetAngle) % 360;
计算飞机当前角度 curAngle
并计算curAngle
与this._targetAngle
的差diffAngle
let curAngle = (360 + (this.flyNd.angle + this.defaultPlaneAngleOffset) % 360) % 360;
let diffAngle = this._targetAngle - curAngle;
根据设置的角速度angularSpeed
修改飞机的角度
if (Math.abs(diffAngle) > 1) {let factorAngle = this._targetAngle - curAngle > 0 ? 1 : -1;if (Math.abs(this._targetAngle - curAngle) > 180) {factorAngle *= -1;}this.flyNd.angle += factorAngle * this.angularSpeed;}
飞机总是向着飞机头的方向前进,根据飞机角度curAngle
计算飞机x y上的速度分量因素factor
let factor = this._getDirection(curAngle);private _getDirection(curAngle: number): cc.Vec2 {let factorX = 0;let factorY = 0;if (curAngle > 90 && curAngle < 270) {let deacc = (90 - (Math.abs(180 - curAngle))) / 90;factorX = 1 * deacc;} else if (curAngle < 90 || curAngle > 270) {let deacc = 1;if (curAngle < 90) {deacc = (90 - curAngle) / 90} else if (curAngle > 270) {deacc = (90 - (360 - curAngle)) / 90}factorX = -1 * deacc;}if (curAngle > 180) {let deacc = (90 - (Math.abs(270 - curAngle))) / 90;factorY = 1 * deacc;} else if (curAngle < 180) {let deacc = (90 - (Math.abs(90 - curAngle))) / 90;factorY = -1 * deacc;}return cc.v2(factorX, factorY);}
根据factor
修改飞机位置,这里还设置了飞机的加速减速运动
//加速this._speed = cc.misc.clampf(this._speed - this.acc, this.speed * 0.9, this.speed*1.5);//移动posthis.flyNd.x += factor.x * this._speed;this.flyNd.y += factor.y * this._speed;
最后达到目的地判断 ,并执行完成回调
//判断到达let distance = Math.abs(this.flyNd.getPosition().sub(this._targetPos).mag());if (distance <= 15) {this._flyStatus = FlyStatus.Idle;if (this._targetCallBack! = null) {this._targetCallBack();this._targetCallBack = null;}}
最终效果就是飞机先转一圈,让后自己调整角度朝着目的地前进
完整代码
const { ccclass, property } = cc._decorator;enum FlyStatus {Idle = 0,TargetMoving = 1,AccCircle = 2 //加速
}@ccclass
export default class PaperPlaneAnim extends cc.Component {@property(cc.Node)flyNd: cc.Node = null;@property({tooltip: "定义9点方向为初始方向, 逆时针方向为正 飞机图片在angle为0时,飞机头和初始方向的角度偏差."})defaultPlaneAngleOffset: number = 0;@property({tooltip: "飞到目的地过程中要做转圈表演的角度."})circleAngle: number = 0;@property({tooltip: "飞行速度."})speed: number = 12;@property({tooltip: "掉头角速度."})angularSpeed: number = 6;@property({tooltip: "加速度."})acc: number = 0.15;private _flyStatus: FlyStatus = FlyStatus.Idle;private _targetAngle: number = 0; //飞机到目标的最终角度private _targetPos: cc.Vec2 = cc.v2(0, 0);private _targetCallBack: Function = null;private _circleAngleCnt: number = 0;private _speed: number = 0;private _circleFactor: number = 0;// LIFE-CYCLE CALLBACKS:start() {//test// let canvas = cc.find("Canvas/testnod");// canvas.on(cc.Node.EventType.TOUCH_END, (t) => {// let pos = t.touch._point;// this.fly(pos);// }, this);}lateUpdate(dt) {//模拟飞机只能像飞机头朝向前进,到达目的地的方式就是不断修改飞机头朝向。if (this._flyStatus == FlyStatus.TargetMoving) {//计算目标位置在飞机的方位。let radian = Math.atan2(this.flyNd.y - this._targetPos.y, this.flyNd.x - this._targetPos.x);this._targetAngle = 180 / Math.PI * radian;this._targetAngle = (360 + this._targetAngle) % 360;//判断飞机头在哪个象限let curAngle = (360 + (this.flyNd.angle + this.defaultPlaneAngleOffset) % 360) % 360;let factor = this._getDirection(curAngle);//修改anglelet diffAngle = this._targetAngle - curAngle;if (Math.abs(diffAngle) > 1) {let factorAngle = this._targetAngle - curAngle > 0 ? 1 : -1;if (Math.abs(this._targetAngle - curAngle) > 180) {factorAngle *= -1;}this.flyNd.angle += factorAngle * this.angularSpeed;}//加速this._speed = cc.misc.clampf(this._speed - this.acc, this.speed * 0.9, this.speed*1.5);//移动posthis.flyNd.x += factor.x * this._speed;this.flyNd.y += factor.y * this._speed;//判断到达let distance = Math.abs(this.flyNd.getPosition().sub(this._targetPos).mag());if (distance <= 15) {this._flyStatus = FlyStatus.Idle;if (this._targetCallBack! = null) {this._targetCallBack();this._targetCallBack = null;}}} else if (this._flyStatus == FlyStatus.AccCircle) {//转圈表演if (this._circleAngleCnt >= this.circleAngle) {this._flyStatus = FlyStatus.TargetMoving;}let curAngle = (360 + (this.flyNd.angle + this.defaultPlaneAngleOffset) % 360) % 360;let factor = this._getDirection(curAngle);if (this._speed > this.speed * 0.3) {if (this._circleFactor == 0) {this._circleFactor = this._targetAngle - curAngle > 0 ? 1 : -1;if (Math.abs(this._targetAngle - curAngle) > 180) {this._circleFactor *= -1;}}this.flyNd.angle += this._circleFactor * this.angularSpeed;this._circleAngleCnt += this.angularSpeed;}//加速this._speed = cc.misc.clampf(this._speed + this.acc, this.speed * 0.2, this.speed*1.5);//移动posthis.flyNd.x += factor.x * this._speed;this.flyNd.y += factor.y * this._speed;}}private _getDirection(curAngle: number): cc.Vec2 {let factorX = 0;let factorY = 0;if (curAngle > 90 && curAngle < 270) {let deacc = (90 - (Math.abs(180 - curAngle))) / 90;factorX = 1 * deacc;} else if (curAngle < 90 || curAngle > 270) {let deacc = 1;if (curAngle < 90) {deacc = (90 - curAngle) / 90} else if (curAngle > 270) {deacc = (90 - (360 - curAngle)) / 90}factorX = -1 * deacc;}if (curAngle > 180) {let deacc = (90 - (Math.abs(270 - curAngle))) / 90;factorY = 1 * deacc;} else if (curAngle < 180) {let deacc = (90 - (Math.abs(90 - curAngle))) / 90;factorY = -1 * deacc;}return cc.v2(factorX, factorY);}public fly(targetPos: cc.Vec2, cb?: () => void, circleAngle?) {this._targetCallBack = cb;targetPos = this.flyNd.parent.convertToNodeSpaceAR(targetPos);this._targetPos = targetPos;this._speed = 0;this._circleAngleCnt = 0;this._circleFactor = 0;this.circleAngle = circleAngle == null ? this.circleAngle : circleAngle;this._flyStatus = FlyStatus.AccCircle;}
}
github 链接
cocos creator 模拟纸飞机运动动画相关推荐
- 用 Cocos Creator 模拟书本翻页效果
本篇文章作者:乐府-贝塔 乐府-贝塔:乐府前端核心开发,从事游戏开发多年,从 Cocos2d-x 做到 Cocos Creator,擅长渲染技术的相关优化.多年的前端开发经验激发了对技术研究的深厚兴趣 ...
- Cocos Creator - 制作精灵帧动画
本文档主要根据官方文档上的图集资源.动画系统.音乐和音效等章节内容进行综合使用. 1.制作图集 制作图集有两种工具: TexturePacker Zwoptex(只能在Windows上使用) 我这里使 ...
- 进击3D游戏界!Cocos Creator快速实现骨骼动画交互!
文章目录 前言 一.Cocos Creator简介? 二.快速上手Cocos Creator 1.任何语言学习,先概览一遍文档 2.跟随官方Demo,进行游戏的制作 三.如何自己实现骨骼模型和界面交互 ...
- 用Cocos Creator 模拟书本翻页效果
1.简介 本文主要探讨了如何使用CocosCreator来模拟书本翻页效果,分别介绍了通过使用贝塞尔曲线和verlet积分算法来模拟书页底边在翻页过程中的弯曲形变,最后通过自定义assembler传入 ...
- Cocos Creator 优化,帧动画优化
需求背景·:在游戏中使用了大量的帧动画,并且为了drawcall的优化使用了 cocos的自动合集功能,因为帧动画的动作效果需要统一 所以图片会有大量空白部分,虽然cocos有自己的trim,但在自动 ...
- Cocos Creator模拟砸金蛋3d旋转效果 | 附代码
1 获取代码 关注微信公众号,发送[砸蛋]获取代码 2 效果预览 3 使用说明 点击add,添加蛋到盘子上,蛋的数量后台可配置: 点击move,让蛋在盘子上转动起来: 点击stop,让蛋停止转动. 4 ...
- cocos creator 模拟重力爆炸效果
最近在写一个用collider和rigidbody来模拟爆炸一下掉落的效果.(因为是测试版,所以素材很low.仅供参考) 先上层级关系图 场景视图 pot是中间的那个小的图.也是模拟爆炸的中心点随便用 ...
- Cocos Creator模拟射箭效果 | 附代码
1 获取代码 感谢「一枚小工」的投稿,关注他的微信公众号,发送[射箭]获取代码 2 效果预览 3 操作方法 点击屏幕,屏幕出现起始位置标志的圆点,不松开手指,滑动屏幕,控制力度和方向,移动距离越大,弓 ...
- Cocos Creator中的动画支持技术
Cocos Creator主要亮点 官方的权威描述是:Cocos Creator是以内容创作为核心的一体化游戏开发工具,这个引擎基于Cocos2d-x,组件化,脚本化,数据驱动,跨平台发布. 本人使用 ...
最新文章
- 关联规则挖掘算法_#数据挖掘初体验 使用weka做关联规则
- 深度学习100问:图像语义分割有哪些经典的上采样方法?
- .net页面数据传递
- [原]关于鼠标滚轮的编程
- Android在ListView滑动数据混乱
- Error:Execution failed for task ':app:clean'.
- DRF数据验证+数据存储
- 开课吧Java课堂:线程间是如何实现通信
- dblink 同步数据_使用DBLINK同步TC数据库
- 实体类转换为XML字符串
- 遗传算法原理及应用二(交叉算子、变异算子与运行参数选择)
- FreeCAD源码分析:FreeCADApp模块
- Android 学习过程中遇到的知识点
- 计算机病毒互助百科,病毒百科——计算机病毒分类
- [201011][Maven 实战][许晓斌][著]
- 计算机笔记检讨,上课没做笔记的反省检讨书
- 明日之后android和ios,明日之后互通区有哪些 明日之后ios和安卓互通区一览
- vue导出word纯前端实现
- 从GraalVM到Quarkus系列-B002篇-Quarkus中的字节码框架gizmo
- 编写操作norflash的裸机程序