CocosCreate3D 下实现抛物线轨迹操作

最近在做小游戏时遇到个物体沿着抛物线运动,并且要显示抛物线轨迹。由于第一次弄CocosCreate3D 引擎开发,查了网上好多资料发现都是在2d下实现没有3d。因为我一直是unity引擎开发,所以将以前写的代码改变,用到Create3D中来实现功能。下面我直接将代码贴出来做个记录。

1:抛物线具体实现方法

import { _decorator, Vec3,} from "cc";
const { ccclass, property } = _decorator;

@ccclass("PhysicsUtil")
export class PhysicsUtil {
    private m_start:Vec3
    private m_end:Vec3
    private m_height:number
    private m_gravity:number
    private m_upTime:number
    private m_downTime:number
    private m_totalTime:number
    private m_velocityStart:Vec3
    private m_position:Vec3
    private m_time:number

    /// <summary> 起点 </summary>
    public get start():Vec3{return this.m_start} 
    /// <summary> 终点 </summary>
    public get end():Vec3 {return this.m_end}
    /// <summary> 目标高度 </summary>
    public get height():number {return this.m_height}
    /// <summary> 重力加速度 </summary>
    public get gravity():number { return this.m_gravity}
    /// <summary> 上升时间 </summary>
    public get upTime():number {return this.m_upTime}
    /// <summary> 下降时间 </summary>
    public get downTime():number {return this.m_downTime}
    /// <summary> 总运动时间 </summary>
    public get totalTime():number {return this.m_totalTime}
    /// <summary> 顶点 </summary>
    public get top():Vec3 {return this.GetPosition(this.m_upTime)}
    /// <summary> 初始速度 </summary>
    public get velocityStart():Vec3 {return this.m_velocityStart}
    /// <summary> 当前位置 </summary>
    public get position():Vec3 {return this.m_position}
    /// <summary> 当前速度 </summary>
    public get velocity():Vec3 {return this.GetVelocity(this.m_time)}
    /// <summary> 当前时间 </summary>
    public get time() {return this.m_time;}
    public set time(val) {
        this.m_time = val;
        this.m_position = this.GetPosition(this.m_time);
    }

    /// <summary> 初始化抛物线运动轨迹 </summary>
    /// <param name="start">起点</param>
    /// <param name="end">终点</param>
    /// <param name="height">高度(相对于两个点的最高位置 高出多少)</param>
    /// <param name="gravity">重力加速度(负数)</param>
    init(start:Vec3,end:Vec3,height:number=10,gravity:number=-9.8)
    {
        let topY:number = Math.max(start.y, end.y) + height;
        let d1:number  = topY - start.y;
        let d2:number  = topY - end.y;
        let g2:number  = 2 / -gravity;
        let t1:number  = Math.sqrt(g2 * d1);
        let t2:number  = Math.sqrt(g2 * d2);
        let t:number  = t1 + t2;
        let vX:number  = (end.x - start.x) / t;
        let vZ:number  = (end.z - start.z) / t;
        let vY:number  = -gravity * t1;
        this.m_start = start;
        this.m_end = end;
        this.m_height = height;
        this.m_gravity = gravity;
        this.m_upTime = t1;
        this.m_downTime = t2;
        this.m_totalTime = t;
        this.m_velocityStart = new Vec3(vX, vY, vZ);
        this.m_position = this.m_start;
        this.m_time = 0;
    }

    /// <summary> 获取某个时间点的位置 </summary>
    public GetPosition(time:number):Vec3
    {
        if (time == 0) {
            return this.m_start;
        }
        if (time == this.m_totalTime) {
            return this.m_end;
        }
        let dY:number = 0.5 * this.m_gravity * time * time;
        let vector3:Vec3= new Vec3(this.m_velocityStart.x*time,this.m_velocityStart.y*time,this.m_velocityStart.z*time)
        let dYVec3:Vec3=new Vec3(0+this.m_start.x+vector3.x, dY+this.m_start.y+vector3.y, (0+this.m_start.z+vector3.z))
        return dYVec3
    }

    /// <summary> 获取某个时间点的速度 </summary>
    public GetVelocity(time:number):Vec3
    {
        if (time == 0) return this.m_velocityStart;
        let dYVec3=new Vec3(0+this.m_velocityStart.x, this.m_velocityStart.y +this.m_velocityStart.y + (this.m_gravity * time), this.m_velocityStart.z)
        return dYVec3
    }
}

2:抛物线调用

import { _decorator, Component, Node,Vec3,instantiate, Prefab } from "cc";
import {PhysicsUtil} from "./PhysicsUtil"
const { ccclass, property } = _decorator;
@ccclass("Missile")
export class Missile extends Component {
    lineList: { [key: number]: Node } = {};
    _Physics:PhysicsUtil   //抛物线运动轨迹
    @property(Node)
    play:Node = null    // 飞行对象
    @property(Node)
    target:Node = null    // 目标
    @property
    height:number=16      // 高度
    @property
    gravity:number = -9.8;   // 重力加速度
    @property(Prefab)
    pointPrefab:Prefab = null;   
    @property
    segmentCount:number=20  //抛物线预测计数

    private playPos:Vec3 = null    // 飞行对象位置点
    private targetPos:Vec3 = null    // 目标位置点

    isStart:boolean = false
    isLine:boolean=false

    _deltaTime:number
    start () {
        this.CreateLine()
        this._Physics = new PhysicsUtil();
        this.isLine=true
    }

    //控制物体开始移动
    SetStart()
    {
        this.isLine=false
        this.isStart=true
    }

    update (deltaTime: number) {
        this._deltaTime=deltaTime
        if(this.isStart)
        {
            this.StartMove()
        }
        if(this.isLine)
        {
            this.DrawLine()
        }
    }

    //创建虚拟轨迹线
    CreateLine()
    {
        this.lineList=[]
        let scene = cc.director.getScene()
        let mNode:Node=scene.getChildByName('Node')
        mNode.removeAllChildren()
        for(let i=0;i<this.segmentCount;i++)
        {
            let pointNode:Node =instantiate(this.pointPrefab);
            pointNode.setParent(mNode)
            pointNode.setPosition(Vec3.ZERO)
            this.lineList[i]=pointNode
            pointNode.active=false
        }
    }

    //根据目标点画轨迹线
    DrawLine()
    {
        this.playPos=this.play.position.clone()
        this.targetPos=this.target.position.clone()
        this._Physics.init(this.playPos,this.targetPos,this.height, this.gravity)
        this.play.lookAt(this._Physics.GetPosition(this._Physics.time + this._deltaTime));

        let timeStep = this._Physics.totalTime/this.segmentCount
        if(this.lineList!=null)
        {
            for(let i=0;i<this.segmentCount;i++)
            {
                let pointNode:Node = this.lineList[i]
                pointNode.active=true
                let pos = this._Physics.GetPosition(timeStep*i)
                pointNode.setPosition(pos)
            }
        }
    }

    //物体沿着抛物线轨迹开始移动
    StartMove()
    {
        //隐藏轨迹线        
        for(let i=0;i<this.segmentCount;i++)
        {
            let pointNode:Node = this.lineList[i]
            pointNode.active=false
        }
        this._Physics.time=this._Physics.time+this._deltaTime
        this.play.position =  this._Physics.position;
        this.playPos=this.play.position.clone()
        // 计算转向
        this.play.lookAt(this._Physics.GetPosition(this._Physics.time + this._deltaTime));
        // 简单模拟一下碰撞检测
        if (this._Physics.time >= this._Physics.totalTime) 
        {
           this.play.position=this.target.position
           this.play.rotation=this.target.rotation
           console.log("==简单模拟一下碰撞检测==")
           this.isStart=false
           this.isLine=true
        }      
    }
}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值