cocos creator 3.8 打飞机Demo 9

打印 上一主题 下一主题

主题 769|帖子 769|积分 2307

简单的demo实现,没优化以及加上音频文件,没有开始结束暂停等逻辑。
首先2D状态下,担当的素材

1、首先实现背景的移动

根本逻辑如下 关于fixUpdate,可以写一个基类,然后继续它
  1.     //固定帧计时
  2.     private _now_time = 0;
  3.     //固定帧时间
  4.     private frameTime = 0.016;
  5.    
  6.     start() {
  7.         this.gameBg1.setPosition(0, 0, 0);
  8.         this.gameBg2.setPosition(0, this._maxRange, 0);
  9.     }
  10.     update(deltaTime: number) {
  11.         this._now_time += deltaTime;
  12.         while (this._now_time >= this.frameTime) {
  13.             //迭代逻辑
  14.             this.childUpdate(this.frameTime);
  15.             this._now_time -= this.frameTime;
  16.         }
  17.     }
  18.     childUpdate(deltaTime: number) {
  19.         this.gameBg1.setPosition(0, this.gameBg1.position.y - this._moveSpeed * deltaTime, 0);
  20.         this.gameBg2.setPosition(0, this.gameBg2.position.y - this._moveSpeed * deltaTime, 0);
  21.         if (this.gameBg1.position.y <= -this._maxRange) {
  22.             this.gameBg1.setPosition(0, this.gameBg2.position.y + this._maxRange, 0);
  23.         } else if (this.gameBg2.position.y <= -this._maxRange) {
  24.             this.gameBg2.setPosition(0, this.gameBg1.position.z + this._maxRange, 0);
  25.         }
  26.     }
复制代码
2、创建角色小飞机,来一个脚本控制小飞机的移动

3.x上
 Input该输入类管理全部的输入事件,包括:触摸、鼠标、加速计、游戏手柄、6DOF手柄、头戴显示器 和 键盘。

所以Node与Input的这连个监听事件,都可以利用
  1. //玩家飞机
  2.     @property(Node)
  3.     userPlane: Node = null;
  4.     protected onLoad(): void {
  5.         this.userPlane.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
  6.         this.userPlane.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
  7.         this.userPlane.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
  8.         this.userPlane.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
  9.         // input.on(Input.EventType.TOUCH_START, this.onTouchEventStart, this);
  10.         // input.on(Input.EventType.TOUCH_MOVE, this.onTouchEventMove, this);
  11.         // input.on(Input.EventType.TOUCH_CANCEL, this.onTouchEventCanel, this);
  12.         // input.on(Input.EventType.TOUCH_END, this.onTouchEventEnd, this);
  13.         this.userPlane.setPosition(v3(0, -300, 0));
  14.     }
  15. onTouchMove(event: EventTouch) {
  16.         // 获取触点距离上一次事件移动的距离对象,对象包含 x 和 y 属性。
  17.         const delta = event.getDelta();
  18.         const position = this.userPlane.position;
  19.         this.userPlane.setPosition(v3(position.x + delta.x, position.y + delta.y, position.z));
  20.     }
复制代码

  • 创建敌方小飞机,挂上脚本,设置预制体

  1. //小飞机的移动速度
  2.     _moveSpeed: number = 10;
  3.     //背景移动的上线距离
  4.     _maxRange: number = 740;//大于1/2的界面高度
  5.     update(deltaTime: number) {
  6.         const postion = this.node.position;
  7.         //移动的距离
  8.         const moveLength = postion.y - this._moveSpeed;
  9.         this.node.setPosition(postion.x, moveLength, postion.z);
  10.         if (moveLength <= -this._maxRange) {
  11.             this.node.destroy();
  12.         }
  13.     }
复制代码

  • 创建己方子弹,挂上脚本,设置预制体
  1. //自方的移动速度
  2.     _moveSpeed: number = 15;
  3.     //子弹移动的上线距离
  4.     _maxRange: number = 1344;
  5.     update(deltaTime: number) {
  6.         let position = this.node.position;
  7.         this.node.setPosition(position.x, position.y + this._moveSpeed, position.z);
  8.         position = this.node.position;
  9.         if (position.y > this._maxRange) {
  10.             this.node.destroy();
  11.         }
  12.     }
复制代码

  • 创建敌方子弹,挂上脚本,设置预制体
  1. //敌方的移动速度
  2.     _moveSpeed: number = 15;
  3.     //子弹移动的上线距离
  4.     _maxRange: number = 1344/2;
  5.     update(deltaTime: number) {
  6.         let position = this.node.position;
  7.         this.node.setPosition(position.x, position.y - this._moveSpeed, position.z);
  8.         position = this.node.position;
  9.         if (position.y < -this._maxRange) {
  10.             this.node.destroy();
  11.         }
  12.     }
复制代码

  • 创建一个空节点,放置生成的子弹的容器


  • 由于敌机上也要生成子弹,而且还是预制体,这个容器节点就没法挂载了,那就来一个控制类。GameCtrl或者GameManager名字本身好记就弄那个名字呗。
在这个类上写方法创建子弹,并引入,这样就会袒露个问题,引入的GameCtrl为空或者null,
两种方法
1>在GameCtrl 的onLoad中让它赋值this,window[“GameCtrl”] = this,然后在其他的脚本中调用它下面的方法。
2>找到这里节点上挂载的这个脚本,用一个方法在onLoad中,不一定是onLoad,总之就是提前传入:让这个类指向this,让脚本能够找到这个类。
  1. createPlayer() {
  2.         // const playerBullet: Node = instantiate(this.playerBullet);
  3.         // const position = rootNode.position;
  4.         // playerBullet.setParent(rootNode);
  5.         // playerBullet.setPosition(position.x, position.y, position.z);
  6.         let playerComp = this.userPlane.getComponent(PlayerCtrl);
  7.         playerComp.showBullet(this);
  8.     }
  9.     showBullet(gameCtrl: GameCtrl, needShoot: boolean = false) {
  10.         this.gameCtrl = gameCtrl;
  11.         this.needShoot = needShoot;
  12.     }
复制代码

  • 该分组了,必要的地方加上碰撞器与刚体,这里我勾选了Is Trigger,没有效2D的Collider,创建的是3D项目,就这样吧。

碰撞判定
  1.     protected onEnable(): void {
  2.         const collider = this.node.getComponent(Collider);
  3.         collider.on("onTriggerEnter", this.onTriggerEnter, this);
  4.     }
  5.     protected onDisable(): void {
  6.         const collider = this.node.getComponent(Collider);
  7.         collider.off("onTriggerEnter", this.onTriggerEnter, this);
  8. }
  9.     onTriggerEnter(event: ITriggerEvent) {
  10.         const collisionGroup = event.otherCollider.getGroup();
  11.         //己方小飞机
  12.         if (collisionGroup == 1 << 1) {
  13.             this.node.destroy();
  14.         }
  15.     }
复制代码

  • 简单的一个demo写的差不多了,再来一个节点池NodePool
  1. @ccclass('NodePoolManger')
  2. export class NodePoolManger extends Component {
  3.     //没有继承Component 需要静态的
  4.     //在实际应用中需要实例化,走单例模式
  5.     static _instance: NodePoolManger;
  6.     static instance() {
  7.         //没有就new一个,有就直接返回这个实例
  8.         if (!this._instance) {
  9.             this._instance = new NodePoolManger();
  10.         }
  11.         return this._instance;
  12.     }
  13. }
复制代码
定义两个数据结构的接口
  1. //定义一个数据结构map集合 字典
  2. interface IDicPool {
  3.     [name: string]: NodePool;
  4. }
  5. //数据结构接口 key :value
  6. interface IDicPrefab {
  7.     [name: string]: Prefab;
  8. }
复制代码
在定义两个对象
  1. //两个容器对象 节点与预制
  2. _dicPool: IDicPool = {};
  3. //定义这个对象,根据名字来取对应的prefab
  4. _dicPrefab: IDicPrefab = {};
复制代码
然后一个 get 一个put的实现

  • 替换
  1.   createPlayerbullte(rootNode: any) {
  2.         const playerBullet: Node = NodePoolManger.instance().getNode(this.playerBullet, this.bulletRoot);
  3.         // const playerBullet: Node = instantiate(this.playerBullet);
  4.         // playerBullet.setParent(this.bulletRoot);
  5.         playerBullet.setPosition(rootNode.position.x, rootNode.position.y + 80, rootNode.position.z);
  6. }
  7. onTriggerEnter(event: ITriggerEvent) {
  8.         const collisionGroup = event.otherCollider.getGroup();
  9.         //己方小飞机
  10.         if (collisionGroup == 1 << 1) {
  11.             NodePoolManger.instance().putNode(this.node);
  12.             // this.node.destroy();
  13.         }
  14.     }
复制代码
demo一会儿上传,新手可以看看
  1.     //获取节点 //替换游戏中的instantiate
  2.     getNode(prefab: Prefab, parent: Node) {
  3.         // let name = prefab.name;
  4.         let name = prefab.data.name;
  5.         // console.log("get pool " + name);
  6.         let node: Node = null;
  7.         //先判断这种池子存在否
  8.         this._dicPrefab[name] = prefab;
  9.         let pool = this._dicPool[name];
  10.         //检查有没有这个池子
  11.         if (pool) {
  12.             //检查池子中有没有这个预制体
  13.             if (pool.size() > 0) {
  14.                 node = pool.get();
  15.             } else {
  16.                 //没有就实例化一个
  17.                 node = instantiate(prefab);
  18.             }
  19.         } else {
  20.             //没有这种池子,就新建一个
  21.             this._dicPool[name] = new NodePool();
  22.             node = instantiate(prefab);
  23.         }
  24.         node.parent = parent;
  25.         //激活这个节点
  26.         node.active = true;
  27.         return node;
  28.     }
  29.     //缓存节点 //替换游戏中的node.destroy
  30.     putNode(node: Node) {
  31.         let name = node.name;
  32.         // console.log("put pool " + name);
  33.         //节点被回收,不能再作为场景里面的对象存在与场景中
  34.         node.parent = null;
  35.         //池子中有这种类型的
  36.         if (this._dicPool[name]) {
  37.             this._dicPool[name].put(node);
  38.         } else {
  39.             //没有就创建再放进去
  40.             this._dicPool[name] = new NodePool();
  41.             this._dicPool[name].put(node);
  42.         }
  43.     }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

写过一篇

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表