当前位置: 首页 > news >正文

如今做啥网站能致富网络营销教学大纲

如今做啥网站能致富,网络营销教学大纲,最好看免费观看高清大全八百电影,企业做网站需要注意什么问题版本: cocosCreator 3.4.0 语言: TypeScript 环境: Mac NodePool 在项目中频繁的使用instantiate和node.destory对性能有很大的耗费,比如飞机射击中的子弹使用和销毁。 因此官方提供了NodePool,它被作为管理节点对象…

版本: cocosCreator 3.4.0

语言: TypeScript

环境: Mac


NodePool


在项目中频繁的使用instantiatenode.destory对性能有很大的耗费,比如飞机射击中的子弹使用和销毁。

因此官方提供了NodePool,它被作为管理节点对象的缓存池使用。定义如下:

export class NodePool {// 缓冲池处理组件,用于节点的回收和复用逻辑,这个属性可以是组件类名或组件的构造函数poolHandlerComp?: Constructor<IPoolHandlerComponent> | string;// 构造函数,可传递组件或名称,用于处理节点的复用和回收constructor(poolHandlerComp?: Constructor<IPoolHandlerComponent> | string);// 获取当前缓冲池的可用对象数量size(): number;// 销毁对象池中缓存的所有节点clear(): void;/*@func: 向缓冲池中存入一个不再需要的节点对象@param: 回收的目标节点注意:1. 该函数会自动将目标节点从父节点上移除,但是不会进行 cleanup 操作2. 如果存在poolHandlerComp组件和函数,会自动调用 unuse函数*/put(obj: Node): void;/*@func: 获取对象池中的对象,如果对象池没有可用对象,则返回空@param: 如果组件和函数存在,会向 poolHandlerComp 中的 'reuse' 函数传递的参数*/get(...args: any[]): Node | null;
}

接口汇总:

接口说明
new()创建对象池
put()将节点放到对象池中
get()从对象池中获取节点
size()获取对象池中对象的数目
clear()销毁对象池中的所有对象

使用NodePool的大概思路:

  • 通过NodePool创建对象池
  • 获取节点时,可先检测对象池的数目;如果 =0 则克隆节点并放到对象池中,如果 >0 则从对象池中获取
  • 节点不使用的时候,如果没有对象池,则调用node.destory,否则将节点放到对象池中

在对象池中,有个get(...args: any[])的方法,方法参数的使用主要针对于:对象池创建时添加了可选参数。

以飞机射击中子弹的构建为目的,看下关于对象池的使用示例相关:

// GameManager.ts 游戏管理类
import { BulletItem } from '../bullet/BulletItem';@ccclass('GameManager')
export class GameManager extends Component {@property(Prefab) bullet: Prefab = null;		// 子弹预制体private _bulletPool: NodePool = null;				// 子弹对象池onLoad() {// 创建子弹对象池this._bulletPool = new NodePool();}// 创建玩家子弹private createPlayerBullet() {// 获取子弹节点const bulletNode = this.getBulletNode();const bulletItem = bulletNode.getComponent(BulletItem);// 此处将子弹对象池传入子弹对象脚本bulletItem.init(this._bulletPool);}// 获取子弹节点private getBulletNode(): Node {const size = this._bulletPool.size();if (size <= 0) {// 克隆子弹节点const bulletNode = instantiate(this.bullet);// 将子弹节点添加到对象池中this._bulletPool.put(bulletNode);}// 从对象池中获取节点return this._bulletPool.get();}onDestroy() {// 销毁对象池this._bulletPool.clear();}
}// BulletItem.ts 子弹对象组件脚本
export class BulletItem extends Component {private _bulletPool: NodePool = null;public init(bulletPool: NodePool) {this._bulletPool = bulletPool;}private destroyBullet() {// 检测是否存在对象池,如果存在,则将对象放到对象池中,否则销毁if (this._bulletPool) {this._bulletPool.put(this.node);}else {this.node.destory();}}
}

如上例子,简单演示了下NodePool对象池的使用,但需要注意:

  • 最好存储同类型的节点,方便管理
  • 注意检测对象池内的对象数目或通过get获取对象后,进行安全判定,避免null
  • 注意对象池对象的释放

构造函数的可选参数

在上面的定义文件中,针对于对象池的构建,有着可选参数的支持,代码如下:

// 缓冲池处理组件,用于节点的回收和复用逻辑,这个属性可以是组件类名或组件的构造函数
poolHandlerComp?: Constructor<IPoolHandlerComponent> | string;
// 构造函数,可传递组件或名称,用于处理节点的复用和回收事件逻辑
constructor(poolHandlerComp?: Constructor<IPoolHandlerComponent> | string);

可选参数的支持主要有两种形式:

  1. string字符串形式
  2. IPoolHandlerComponent 缓存池处理组件形式

对于这两种形式,其本质就是增加了对对象池中对象的自定义逻辑处理,以组件为参数,看下它的定义:

export interface IPoolHandlerComponent extends Component {// 在对象被放入对象池的时候进行调用unuse(): void;// 从对象池中获取对象的时候被调用reuse(args: any): void;
}

这两个方法的调用,看下源码的实现:

// 来源于 node-pool.ts
export class NodePool {// 向对象缓存池存入不需要的对象public put (obj: Node) {if (obj && this._pool.indexOf(obj) === -1) {// 从父节点移除,但并不cleanupobj.removeFromParent();// 获取组件poolHandlerComp,并检测是否存在 unuse方法,如果存在则调用const handler = this.poolHandlerComp?obj.getComponent(this.poolHandlerComp):null;if (handler && handler.unuse) {handler.unuse();}this._pool.push(obj);}}// 获取对象池中的对象public get (...args: any[]): Node | null {// 检测对象池中是否有对象const last = this._pool.length - 1;if (last < 0) {return null;} else {// 将对象从缓存池中取出const obj = this._pool[last];this._pool.length = last;// 获取组件poolHandlerComp,并检测是否存在reuse方法,如果存在则调用const handler=this.poolHandlerComp?obj.getComponent(this.poolHandlerComp):null;if (handler && handler.reuse) {handler.reuse(arguments);}return obj;}}
}

上面的代码有助于对两个方法的调用时机增加一些了解。

下面我们依然以飞机的子弹构建为例,代码增加一些拓展,用于支持对象池的自定义逻辑处理。

// GameManager.ts 游戏管理类
import { BulletItem } from '../bullet/BulletItem';@ccclass('GameManager')
export class GameManager extends Component {  onLoad() {// 创建子弹对象池, 参数设定为子弹类的名字this._bulletPool = new NodePool("BulletItem");}private getBulletNodePool() {const size = this._bulletPool.size();if (size <= 0) {const bulletNode = instantiate(this.bullet_1);this._bulletPool.put(bulletNode);}// 获取子弹节点时,可以设置自定义的参数相关return this._bulletPool.get();}
}// BulletItem.ts 子弹对象组件脚本,增加
export class BulletItem extends Component implements IPoolHandlerComponent {unuse(): void {console.log("------ 调用了组件的 unuse 方法");}reuse(args: any): void {console.log("------ 调用了组件的 reuse 方法");}
}

增加对对象的自定义逻辑处理,其要点就是:

  • 构建对象池时,需要添加可选参数,参数的名字或组件一定要是对象的脚本组件相关
  • 对象的组件脚本类,需要增加implements IPoolHandlerComponent 的实现,也就是unusereuse方法
  • 根据情况,自定义设定NodePool.get的参数相关

到这里,关于NodePool的基本使用介绍完毕。


NodePool管理器


在上面的例子中,关于对象池的使用存在着几个问题:

  1. 从对象池获取对象和将对象放入对象池的调用在不同的脚本文件中,可能会出现维护比较困难的问题

  2. 对象池的构建不仅针对于子弹,而且可能还有敌机,道具等,可能会出现多个对象池且代码重复的问题。

因此,我们可构建一个对象池的管理类,来统一管理多个不同的对象池,类似于cocos2d-x中的PoolManager

大致的属性和接口是:

属性或方法说明
_nodePoolMap保存所有对象池的容器,结构是Map<对象池名, NodePool池>
getNodePoolByName():NodePool通过名字从容器中获取对象池,如果没有则创建,如果存在则获取
getNodeFromPool():Node通过名字从对象池中获取节点,如果没有则克隆,如果存在则获取
putNodeToPool()将节点放入对象池中
clearNodePoolByName()通过名字将对象池从容器中移除
clearAll()移除容器中的所有对象池

该类使用的是单例模式,详细的代码如下:

// 对象池管理器
import { _decorator, Component, instantiate, NodePool, Prefab} from 'cc';
const { ccclass } = _decorator;export class NodePoolManager {private static _instance: NodePoolManager = null;private _nodePoolMap: Map<string, NodePool> = null;static get instance() {if (this._instance) {return this._instance;}this._instance = new NodePoolManager();return this._instance;}constructor() {this._nodePoolMap = new Map<string, NodePool>();}/*@func 通过对象池名字从容器中获取对象池@param name 对象池名字@return 对象池*/private getNodePoolByName(name: string): NodePool {if (!this._nodePoolMap.has(name)) {let nodePool = new NodePool(name);this._nodePoolMap.set(name, nodePool);}let nodePool = this._nodePoolMap.get(name);return nodePool;}/*@func 通过对象池名字从对象池中获取节点@param name 对象池名字@param prefab 可选参数,对象预制体@return 对象池中节点 */public getNodeFromPool(name: string, prefab?: Prefab): Node | null {let nodePool = this.getNodePoolByName(name);const poolSize = nodePool.size();if (poolSize <= 0) {let node = instantiate(prefab);nodePool.put(node);}return nodePool.get();}/*@func 将节点放入对象池中@param name 对象池名字@param node 节点*/public putNodeToPool(name: string, node: Node) {let nodePool = this.getNodePoolByName(name);nodePool.put(node);}// 通过名字将对象池从容器中移除public clearNodePoolByName(name: string) {// 销毁对象池中对象let nodePool = this.getNodePoolByName(name);nodePool.clear();// 删除容器元素this._nodePoolMap.delete(name);}// 移除所有对象池public clearAll() {this._nodePoolMap.forEach((value: NodePool, key: string) => {value.clear();});this._nodePoolMap.clear();}static destoryInstance() {this._instance = null;}
}

测试示例:

// GameManager.ts 
const BULLET_POOL_NAME = "BulletItem"       // 子弹内存池// 创建玩家子弹
private createPlayerBullet() {// 获取子弹节点,参数:节点名,子弹预制体const poolManager = NodePoolManager.instance;const bulletNode = poolManager.getNodeFromPool(BULLET_POOL_NAME, this.bulletPrefab);bulletNode.parent = this.bulletRoot;
}// BulletItem.ts
private destroyBullet() {// 检测是否存在对象池,如果存在,则将对象放到对象池中,否则销毁if (this._bulletPool) {//this._bulletPool.put(this.node);const poolManager = NodePoolManager.instance;poolManager.putNodeToPool(BULLET_POOL_NAME, this.node);}else {this.node.destory();}
}

管理类中有个接口叫做getNodeFromPool(name: string, prefab?: Prefab),第二个参数也可以为prefabName,然后通过resource.load进行动态加载,类似实现:

public getNodeFromPool(name: string, prefabName?: string): Node | null {let nodePool = this.getNodePoolByName(name);const poolSize = nodePool.size();if (poolSize <= 0) {const url = "prefab/" + prefabName;resources.load(url, (err, prefab) => {if (err) {return console.err("getNodeFromPool resourceload failed:" + err.message);}let node = instantiate(prefab);nodePool.put(node);});}return nodePool.get();
}

resouces.load属于异步操作,可能会出现代码未加载完成就获取的问题,因此可使用异步编程

public getNodeFromPool(name: string, prefabName?: string): Promise<Node | null> {return new Promise<Node | null>((resolve, reject) => {let nodePool = this.getNodePoolByName(name);const poolSize = nodePool.size();if (poolSize <= 0) {const url = "prefab/" + prefabName;resources.load(url, (err, prefab) => {if (err) {console.error("getNodeFromPool resourceload failed:" + err.message);reject(err);} else {let node = instantiate(prefab);nodePool.put(node);resolve(nodePool.get());}});} else {resolve(nodePool.get());}});
}

关于一些TypeScript的语法相关,可参考博客:

TypeScript 之 Map

TypeScript 之 异步编程

因工作的某些缘故,可能对NodePool的理解及编写示例有所不当,请不吝赐教,感激不尽!

最后祝大家学习生活愉快!


文章转载自:
http://dinncogca.bkqw.cn
http://dinncosightseeing.bkqw.cn
http://dinncodictatorial.bkqw.cn
http://dinncomisword.bkqw.cn
http://dinncothence.bkqw.cn
http://dinncothiuram.bkqw.cn
http://dinncoslaughterhouse.bkqw.cn
http://dinncogolliwog.bkqw.cn
http://dinncoampullae.bkqw.cn
http://dinncoacrodrome.bkqw.cn
http://dinncodeclivitous.bkqw.cn
http://dinncofurrier.bkqw.cn
http://dinncocharacterization.bkqw.cn
http://dinncodoggie.bkqw.cn
http://dinncoearthbound.bkqw.cn
http://dinncoppm.bkqw.cn
http://dinncozymoscope.bkqw.cn
http://dinncodecretal.bkqw.cn
http://dinncogynoecium.bkqw.cn
http://dinnconicish.bkqw.cn
http://dinncotransilluminate.bkqw.cn
http://dinncophrasemongering.bkqw.cn
http://dinncointegral.bkqw.cn
http://dinncojuniorate.bkqw.cn
http://dinncodekametric.bkqw.cn
http://dinncoscreen.bkqw.cn
http://dinncospodumene.bkqw.cn
http://dinncoirreconcilable.bkqw.cn
http://dinncoantelucan.bkqw.cn
http://dinncodiathermization.bkqw.cn
http://dinncoacclamation.bkqw.cn
http://dinncodiazotization.bkqw.cn
http://dinncopolystylar.bkqw.cn
http://dinncoatopy.bkqw.cn
http://dinncosmouch.bkqw.cn
http://dinncoomdurman.bkqw.cn
http://dinncopolyglotter.bkqw.cn
http://dinncocrossite.bkqw.cn
http://dinncoundertook.bkqw.cn
http://dinncolipbrush.bkqw.cn
http://dinncomythologer.bkqw.cn
http://dinncoantonym.bkqw.cn
http://dinncounabridged.bkqw.cn
http://dinncojuvenal.bkqw.cn
http://dinncoescrow.bkqw.cn
http://dinncobronzer.bkqw.cn
http://dinncoloudmouthed.bkqw.cn
http://dinncostygian.bkqw.cn
http://dinncopractic.bkqw.cn
http://dinncomicromole.bkqw.cn
http://dinncosabulite.bkqw.cn
http://dinncohypoallergenic.bkqw.cn
http://dinncozionite.bkqw.cn
http://dinncomen.bkqw.cn
http://dinncodysphagy.bkqw.cn
http://dinncosparkling.bkqw.cn
http://dinncofelsite.bkqw.cn
http://dinnconisus.bkqw.cn
http://dinncodioxin.bkqw.cn
http://dinncodispensary.bkqw.cn
http://dinncoblackhead.bkqw.cn
http://dinncorhodo.bkqw.cn
http://dinncoboart.bkqw.cn
http://dinncorestrictionist.bkqw.cn
http://dinncoevenfall.bkqw.cn
http://dinnconor.bkqw.cn
http://dinncomicrotone.bkqw.cn
http://dinncomeninx.bkqw.cn
http://dinnconarrow.bkqw.cn
http://dinncophasemeter.bkqw.cn
http://dinncotriggerman.bkqw.cn
http://dinncodissatisfy.bkqw.cn
http://dinncooxaloacetate.bkqw.cn
http://dinncodeflective.bkqw.cn
http://dinncoslugger.bkqw.cn
http://dinncogloat.bkqw.cn
http://dinncodesalination.bkqw.cn
http://dinncoscarfpin.bkqw.cn
http://dinncoplaguy.bkqw.cn
http://dinncotransudatory.bkqw.cn
http://dinncorustle.bkqw.cn
http://dinncograpy.bkqw.cn
http://dinncomoncay.bkqw.cn
http://dinncogoalie.bkqw.cn
http://dinncograndducal.bkqw.cn
http://dinncohiccup.bkqw.cn
http://dinncoultraclean.bkqw.cn
http://dinncoextragovernmental.bkqw.cn
http://dinncoendophilic.bkqw.cn
http://dinncorajahship.bkqw.cn
http://dinncostepbrother.bkqw.cn
http://dinncoinharmonic.bkqw.cn
http://dinncodecadence.bkqw.cn
http://dinncocurrency.bkqw.cn
http://dinncosunbake.bkqw.cn
http://dinncokhamsin.bkqw.cn
http://dinncocanaanite.bkqw.cn
http://dinncopartiality.bkqw.cn
http://dinncohumourously.bkqw.cn
http://dinncomillifarad.bkqw.cn
http://www.dinnco.com/news/102477.html

相关文章:

  • 新手学做网站 视频百度网盘宁波最好的seo外包
  • 鲜花网站建设的利息分析百度竞价推广思路
  • 上海软件网站建设seo每日一帖
  • 网站会员系统wordpress网页制作代码html制作一个网页
  • 滨州正规网站建设公司河南省郑州市金水区
  • 北京企业网站建设公司网推是干什么的
  • 公司网站建设哪家比较好网店推广策略
  • 网站开发 外包空心企业培训内容包括哪些内容
  • 网站公安网备案什么意思seo综合查询是啥意思
  • 电商网站开发目的seo网站推广免费
  • 怎么买域名做企业网站147seo工具
  • 网站需求清单百度官方电话号码
  • 怎么做win10原版系统下载网站网页快速收录
  • 长沙做网站最好的公司有哪些谷歌广告推广怎么做
  • 怎么做网站论坛株洲seo推广
  • 旅行社 网站系统最近发生的热点新闻事件
  • 中国建设银行的网站南宁网站seo优化公司
  • 网站建设公司创意国内十大搜索引擎排名
  • 徐州网站制作苏视竞价交易规则
  • 山东聊城网站建设重庆seo排名外包
  • 网站banner代码百度收录平台
  • 网站建设优化的作用友链交换网站
  • 网站怎么做透明导航栏营销型网站和普通网站
  • 如何做类似于淘宝的网站2023年免费进入b站
  • 深圳网站建设工作室今日重大国际新闻军事
  • 国外有哪做交互设计网站武汉seo报价
  • 深圳福田区住房和建设局官方网站大型集团网站建设公司
  • 微购电商小程序广州网站优化
  • 建站制作企业百度刷排名优化软件
  • 莱芜企业建站公司磁力最好用的搜索引擎