zoukankan      html  css  js  c++  java
  • 【弹道】Cocos 跟踪导弹

    cocos版本:2.4.4

    Demo地址:跟踪导弹Demo

    效果图:

     

    实现原理:

    需求是导弹飞到目的地

    cocos坐标系中角度

    通过Math.atan2可以获得导弹和目的地之间的角度

    let missile:cc.Node;      //导弹
    let targetPos:cc.Vec2;   //目的地
    let radian = Math.atan2(targetPos.y - missile.y, targetPos.x - missile.x);  //导弹和目的地之间弧度
    let angle = radian*180/Math.PI;   //弧度转换成角度

    导弹每帧进行角度旋转和移动

    let moveAngle = 2;                                    //角速度(每帧角度变化)
    let moveRadian = moveAngle*Math.PI/180;               //弧度(角速度转成弧度)
    let moveSpeed = 5;                                    //移动速度
    missile.angle += moveAngle;                           //角度每帧变化
    missile.x += Math.cos(moveRadian)*moveSpeed;          //x变化
    missile.y += Math.sin(moveRadian)*moveSpeed;          //y变化
    

    导弹位置都到达目的地,那么导弹的追踪完成。

    15是临近值,如果直接判断 导弹位置 = 目的地位置,那么导弹可能会在目的地附近不停的抖动。

    //判断导弹和目的地的距离,如果小于一定值(这里取15),则判定到达目的地。
    if(cc.Vec2.distance(missile.position,  targetPosition) < 15){
         //导弹到达目的地
    } 

      

    跟踪导弹效果就是追着一个位置变化的物体,所以只要不停的改变目的地targetPos,再进行计算就行了。

    注意点:

    由于Math.atan2在边界值180和-180交接处,从-180瞬间变化到180,或者从180瞬间变化到-180,所以在计算时要处理这种情况,不然导弹会反复绕圈。

     

    导弹的代码:

    const { ccclass, property } = cc._decorator;
    
    @ccclass
    export default class Missile extends cc.Component {
    
        /**目标地点 */
        public targetPos: cc.Vec2 = new cc.Vec2();
        /**角速度 */
        public angleSpeed: number = 5;
        /**移动速度 */
        public moveSpeed: number = 5;
    
        /**移动限制距离,相距目的地距离>moveLimit时才会移动,防止抖动 */
        private moveLimit: number = 20;
        /**每帧变化的角度 */
        private stepAngle: number = null;
    
        /**
         * 设置目标点
         * @param xPos x坐标
         * @param yPos y坐标
         */
        public setTargetPos(xPos: number, yPos: number) {
            this.targetPos.x = xPos;
            this.targetPos.y = yPos;
            this.stepAngle = null;
        }
    
        /**重置 */
        public reset() {
            this.stepAngle = null;
        }
    
        update() {
            //距离目的地一定距离才会移动,防止抖动
            if (Math.sqrt(Math.pow(this.node.x - this.targetPos.x, 2) + Math.pow(this.node.y - this.targetPos.y, 2)) > this.moveLimit) {
                //导弹和目标点之间弧度、角度  
                let targetRadian = Math.atan2(this.targetPos.y - this.node.y, this.targetPos.x - this.node.x);
                let targetAngle = targetRadian * 180 / Math.PI;
                //导弹当前角度
                let curAngle = this.node.angle;
                //导弹当前角度和导弹最终指向角度的差
                let distAngle = targetAngle - curAngle;
                //导弹转动的角速度,根据角度差来判断顺时针或逆时针。( stepAngle=null时才会计算旋转角度,为了防止导弹出现在边界值附近左右摇摆的问题,一旦确定旋转角度方向,则不再改变)
                if (this.stepAngle == null) {
                    this.stepAngle = distAngle > 0 ? this.angleSpeed : -this.angleSpeed;
                }
                //临界值判断 (Math.atan2会在边界值位置直接从180变成-180,或-180变成180,导致永远到不了目标角度)
                if (Math.abs((curAngle + 360) % 360 - (targetAngle + 360) % 360) > (Math.abs(this.stepAngle) + 1)) {
                    //角度未达到临近值才会++,防止抖动
                    if (Math.abs(this.node.angle - targetAngle) > (Math.abs(this.stepAngle) + 1)) {
                        this.node.angle += this.stepAngle;
                    }
                }
                //移动
                let nextRadian = this.node.angle * Math.PI / 180;
                this.node.x += Math.cos(nextRadian) * this.moveSpeed;
                this.node.y += Math.sin(nextRadian) * this.moveSpeed;
            }
        }
    }
    

      

  • 相关阅读:
    redis修改密码
    redis配置
    django中日志配置
    django中缓存配置
    navicat批量导入数据
    django添加REST_FRAMEWORK 接口浏览
    django验证码配置与使用
    LUA_OBJECT
    LUA comment
    lua-redis
  • 原文地址:https://www.cnblogs.com/gamedaybyday/p/15620058.html
Copyright © 2011-2022 走看看