CocosCreator 子弹运动轨迹的绘制

实现效果: 子弹在发射之前提前把轨迹绘制出来.类似愤怒小鸟子弹的运动轨迹.

实现步骤分3步: 1 子弹的发射;  2 子弹运动过程中角度的变化;  3 辅助线的绘制.

 

开发工具: CocosCreator, VsCode

场景介绍: 场景是自己随便搭的, 比较简陋.   1:代表子弹, 2:代表炮台.   6, 7 为子弹和辅助线的预制体.  5: Gunmgr挂载在Canvas下.

实现思路: 1点击鼠标炮台向上开始旋转,松手后, 给子弹添加一个力, applyForceToCente(x,y).  用到了Creator提供的物理引擎 

2 在炮台旋转的同时, 通过这个力, 每隔固定的时间间隔(比如0.06s)把位置计算出来, 确定x,y坐标后生成一个小圆点. 重复此步骤,生成若干个小圆点, 模拟轨迹.

组件添加:

子弹上挂载 PhySicsBoxCollider, (RigidBody会自动挂载),  Bullet脚本用来检测当触碰到地面后, 停止炮台角度的旋转.及碰到地面或敌人相应的逻辑操作.  ground地面也要挂载 PhySicsBoxCollider

 

相关代码:

GunMgr, 挂载在Canvs下

在onEventEnd阶段, 会根据当前位置和上一帧的 位置, 计算出子弹的旋转角度.

const {ccclass, property} = cc._decorator;

@ccclass
export default class GunMgr extends cc.Component {

    @property(cc.Node)
    gunNode = null;
    @property(cc.Node)
    bulletNode = null;
    @property(cc.Prefab)
    pointPrefab = null;

    // LIFE-CYCLE CALLBACKS:
    _curAngle =0; 
    gunSchedule = null;   
    bulletfun = null;

    xLi:number = 12000;
    g:number = 600;

    chongX:number =0;
    chongY:number =0;


    onLoad () {
        cc.director.getPhysicsManager().enabled = true;
        cc.director.getPhysicsManager().gravity = cc.v2(0, -this.g);

        var manager = cc.director.getCollisionManager();
        manager.enabled = true;

        this.bulletNode.active = false;
    }

    start () {

        this.node.on(cc.Node.EventType.TOUCH_START, this.onEventStart, this);
        this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onEventMove, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onEventCancel, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this.onEventEnd, this);


        console.log('AAS: ', cc.PhysicsManager.PTM_RATIO);
    }

    update (dt) {
    }

    onEventStart()
    {
        console.log('nodePos: ', this.gunNode.position);
        this._curAngle = 0;
        this.chongX = this.xLi; 
        //通过角度计算力度
        this.chongY = this.chongX * Math.tan(Math.abs(this._curAngle) * (Math.PI / 180)); 
        this.gunSchedule = function(){
          if (this._curAngle < 90){
            this._curAngle -= 1;
            this.updateLine();
            
            this.gunNode.rotation = this._curAngle;
          }
        };
        this.schedule(this.gunSchedule, 0.02);
    }

    onEventMove()
    {

    }

    onEventCancel()
    {

    }

    onEventEnd()
    {
        for(let i =1; i< this.gunNode.childrenCount; i++){
            this.gunNode.children[i].destroy();
        }
        this.bulletNode.position = cc.v2(0,0)
        this.bulletNode.getComponent('Bullet').init(this);
        this.unschedule(this.gunSchedule);
        this.bulletNode.active = true;
        this.chongX = this.xLi; 
        //通过角度计算力度
        this.chongY = this.chongX * Math.tan(Math.abs(this._curAngle) * (Math.PI / 180)); 
        //给子弹设置冲量
        console.log('chongX: ', this.chongX);
        console.log('chongY: ', this.chongY);
        console.log('bulletNodeM: ', this.bulletNode.getComponent(cc.RigidBody).getMass());
        this.bulletNode.getComponent(cc.RigidBody).applyForceToCenter(cc.v2(this.chongX, this.chongY));


        let curPos = this.bulletNode.position;
        let lastPos = curPos;
        this.bulletfun = function(){
        curPos = this.bulletNode.position;
        //计算角度
        let lenX = curPos.x - lastPos.x;
        let lenY = 0;
        let r = 0;
        if(curPos.y < lastPos.y){ //向上运动
            lenY = curPos.y - lastPos.y;
            r = Math.atan2(lenY, lenX) * 180 / Math.PI;
        }
        else{   //向下运动
            lenY = lastPos.y - curPos.y;
            r = -1 * Math.atan2(lenY, lenX) * 180 / Math.PI;
        }
        lastPos = curPos;
        this.bulletNode.rotation = -r;
        };
        this.schedule(this.bulletfun, 0.1);
    }

    insPoint()
    {
        let pointNode = cc.instantiate(this.pointPrefab);
        pointNode.active = true;
        return pointNode;
    }

    updateLine()
    {
        for(let i =1; i< this.gunNode.childrenCount; i++){
            this.gunNode.children[i].destroy();
        }
        let timer =0;
        for(let i=0; i < 15; i++){
            let temp:cc.Node = this.insPoint();
            temp.setParent(this.gunNode);
            timer += 0.06;
            let x = this.chongX/16.1 * timer;
            let y = this.chongY/16.1 * timer - 0.5 * this.g * timer * timer;
            console.log('x, y', x,y);
            temp.setPosition(x, y);
        }
    }


    stopSchedule()
    {
        this.unschedule(this.bulletfun);
    }
}

Bullet

import GunMgr from "./GunMgr";

const {ccclass, property} = cc._decorator;

@ccclass
export default class Bullet extends cc.Component {
    gunMgrTs = null;

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.node.getComponent(cc.RigidBody).enabledContactListener = true;
    }

    start () {

    }

    init( gunMgrTs:GunMgr)
    {
        this.gunMgrTs = gunMgrTs;
    }

    // update (dt) {}

    onBeginContact(contact, selfCollider, otherCollider)
    {
        console.log('other: ', otherCollider);
        console.log('self: ', selfCollider);
        if(otherCollider.node.name == 'ground'){
            this.gunMgrTs.stopSchedule();
            console.log('Pos: ', this.node.position);
        }
    }
}

 

 

 

 

 

 

 

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值