IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> [学习笔记]cocos creator 3.0,实现飞行射击游戏的激光鞭(二) -> 正文阅读

[游戏开发][学习笔记]cocos creator 3.0,实现飞行射击游戏的激光鞭(二)

三、代码实现逻辑

3.1 普通子弹

? ? ? ? 此处的普通子弹的作用有两个,提供坐标给Line组件绘制激光,与敌机产生碰撞。

? ? ? ? 普通子弹的运行较为简单,因为教程很多,不赘述了,与普通子弹不同是,需要添加一个boolean值,用于判断子弹是否已经销毁,因为如果销毁了,就不再用其坐标绘制激光。

3.2 子弹控制器

? ? ? ?因为子弹的密度越高,激光会越平滑,所以需要设定一下子弹的数量上限,达到上限后的子弹自动销毁,优化一部分性能。

? ? ? ? 初始化的子弹节点存入数组bulletNodes,子弹数量达到上限后,销毁最早发射的子弹,并把最近生成的子弹存入数组。


                if (self.bulletNodes.length < self.maxPointNum) {
                    newBulletNode.getComponent(BulletByUpdate)?.init(
                        BulletDirection.TO_UP,  //子弹朝向
                        self.oriPos,            //子弹发射坐标
                        self.distance,          //子弹移动距离
                        self.speed,             //子弹速度
                        90,                     //子弹角度
                        self.bulletSprite,      //子弹的精灵
                        BulletExplodeAnimation.NONE     //子弹爆炸 动画
                    )
                    self.bulletNodes.push(newBulletNode);
                    find("Canvas/BulletLayer")!.addChild(newBulletNode);
                }

                else
                {
                    self.bulletNodes.push(newBulletNode);
                    self.bulletNodes[0].destroy();
                    self.bulletNodes.shift();

                    self.bulletNodes[self.bulletNodes.length - 1].getComponent(BulletByUpdate)?.init(
                        BulletDirection.TO_UP,
                        self.oriPos,
                        self.distance,
                        self.speed,
                        90,
                        self.bulletSprite,
                        BulletExplodeAnimation.NONE
                    )
                    find("Canvas/BulletLayer")!.addChild(self.bulletNodes[self.bulletNodes.length - 1]);
                }

3.3 Line组件绘制激光

? ? ? ? 有了bulletNodes后就可以每帧遍历数组内的子弹坐标绘制激光了,此时需要处理第一个问题,如下图:

????????当敌机从侧面碰撞子弹后(碰撞了橙色点的子弹),此时绿色点的子弹并未消失,Line的绘制仍会将绿色点和蓝色点连接起来,造成激光穿过敌机的现象,此时应该在update里,每帧获取子弹的碰撞状态,并通过计算仅在bulletNodes数组内保留蓝色的子弹节点。

        let i = 0;
        let destroyNodes;
        for (i = 0; i < this.bulletNodes.length; i++) {
            if (this.bulletNodes[i].position != null && this.bulletNodes[i].position != undefined) {
                if (this.bulletNodes[i].getComponent(BulletLaserByUpdate)?.hasCrash()) {
                    // console.log("i:" + i);
                    destroyNodes = this.bulletNodes.splice(0, i);   //获取撞击的拐点,并将其之前的拐点全部删除
                    let j = 0;
                    for (j = 0; j < destroyNodes.length; j++) {
                        destroyNodes[j].destroy();      //将删除的拐点全部销毁
                    }
                }
            }
        }

????????然后再遍历bulletNodes,获取坐标,存入数组,用于最后给LINE组件绘制用:

            this.pointVec = new Array<Vec3>();
            let a = 0;
            for(a = 0;a<this.bulletNodes.length;a++)
            {
                if(this.bulletNodes[a].active != false)
                {
                    this.pointVec.push(this.bulletNodes[a].getWorldPosition());
                }

            }

????????之后还需要处理第二个问题,因为每个子弹发射有一定的时间间隔,在下一发子弹未出现前,激光的两端以第一颗和最后一颗子弹为拐点,那在最新一发子弹发出前后,LINE组件分别如下图绘制:

? ? ? ? 这样会导致激光发射位置持续反复横跳,看着很不舒服,所以此时需要设置一个固定的起始点作为Line组件的发射点。

            let planeHead: Vec3 = null!;
            //如果未定义子弹的初始发射位置,则把发射初始位置设置在预制体前部中间位置
            if (this.shotPos != null && this.shotPos != undefined) {
                planeHead = new Vec3(this.fatherNode.worldPosition.x + this.shotPos.x,
                    this.fatherNode.worldPosition.x + this.shotPos.y,
                    0)
            }
            else if (this.shotPos == null) {
                if (this.direction == BulletDirection.TO_UP) {
                    planeHead = new Vec3(this.fatherNode.getWorldPosition().x,
                        this.fatherNode.getWorldPosition().y
                        + this.fatherNode.getComponent(UITransform)?.height! / 2);
                }
                else if (this.direction == BulletDirection.TO_DOWN) {
                    planeHead = new Vec3(this.fatherNode.getWorldPosition().x,
                        this.fatherNode.getWorldPosition().y
                        - this.fatherNode.getComponent(UITransform)?.height! / 2);
                }
            }
    
            this.pointVec.push(planeHead);

?最后为Line组件设置拐点:

????????????this.laserLine.positions?=?this.pointVec?as?never;

就完成了。

四、效果显示优化。

? ? ? ? 因为Line只是单纯的一条直线,可以通过粒子效果分别在激光头尾部挂载,实现看起来比较酷炫的效果。

? ? ? ? 效果如下:

? ? ? ? 配置如下:

? ? ? ? ?PositionType需要设置成RELATIVE效果。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 12:24:41  更:2021-08-07 12:25:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 19:11:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码