中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

數(shù)據(jù)庫(kù)支持的網(wǎng)站怎么做北京疫情最新情況

數(shù)據(jù)庫(kù)支持的網(wǎng)站怎么做,北京疫情最新情況,做金融的網(wǎng)站有哪些,網(wǎng)站開(kāi)發(fā)的前端到底是什么版本: cocosCreator 3.4.0 語(yǔ)言: TypeScript 環(huán)境: Mac NodePool 在項(xiàng)目中頻繁的使用instantiate和node.destory對(duì)性能有很大的耗費(fèi),比如飛機(jī)射擊中的子彈使用和銷(xiāo)毀。 因此官方提供了NodePool,它被作為管理節(jié)點(diǎn)對(duì)象…

版本: cocosCreator 3.4.0

語(yǔ)言: TypeScript

環(huán)境: Mac


NodePool


在項(xiàng)目中頻繁的使用instantiatenode.destory對(duì)性能有很大的耗費(fèi),比如飛機(jī)射擊中的子彈使用和銷(xiāo)毀。

因此官方提供了NodePool,它被作為管理節(jié)點(diǎn)對(duì)象的緩存池使用。定義如下:

export class NodePool {// 緩沖池處理組件,用于節(jié)點(diǎn)的回收和復(fù)用邏輯,這個(gè)屬性可以是組件類(lèi)名或組件的構(gòu)造函數(shù)poolHandlerComp?: Constructor<IPoolHandlerComponent> | string;// 構(gòu)造函數(shù),可傳遞組件或名稱(chēng),用于處理節(jié)點(diǎn)的復(fù)用和回收constructor(poolHandlerComp?: Constructor<IPoolHandlerComponent> | string);// 獲取當(dāng)前緩沖池的可用對(duì)象數(shù)量size(): number;// 銷(xiāo)毀對(duì)象池中緩存的所有節(jié)點(diǎn)clear(): void;/*@func: 向緩沖池中存入一個(gè)不再需要的節(jié)點(diǎn)對(duì)象@param: 回收的目標(biāo)節(jié)點(diǎn)注意:1. 該函數(shù)會(huì)自動(dòng)將目標(biāo)節(jié)點(diǎn)從父節(jié)點(diǎn)上移除,但是不會(huì)進(jìn)行 cleanup 操作2. 如果存在poolHandlerComp組件和函數(shù),會(huì)自動(dòng)調(diào)用 unuse函數(shù)*/put(obj: Node): void;/*@func: 獲取對(duì)象池中的對(duì)象,如果對(duì)象池沒(méi)有可用對(duì)象,則返回空@param: 如果組件和函數(shù)存在,會(huì)向 poolHandlerComp 中的 'reuse' 函數(shù)傳遞的參數(shù)*/get(...args: any[]): Node | null;
}

接口匯總:

接口說(shuō)明
new()創(chuàng)建對(duì)象池
put()將節(jié)點(diǎn)放到對(duì)象池中
get()從對(duì)象池中獲取節(jié)點(diǎn)
size()獲取對(duì)象池中對(duì)象的數(shù)目
clear()銷(xiāo)毀對(duì)象池中的所有對(duì)象

使用NodePool的大概思路:

  • 通過(guò)NodePool創(chuàng)建對(duì)象池
  • 獲取節(jié)點(diǎn)時(shí),可先檢測(cè)對(duì)象池的數(shù)目;如果 =0 則克隆節(jié)點(diǎn)并放到對(duì)象池中,如果 >0 則從對(duì)象池中獲取
  • 節(jié)點(diǎn)不使用的時(shí)候,如果沒(méi)有對(duì)象池,則調(diào)用node.destory,否則將節(jié)點(diǎn)放到對(duì)象池中

在對(duì)象池中,有個(gè)get(...args: any[])的方法,方法參數(shù)的使用主要針對(duì)于:對(duì)象池創(chuàng)建時(shí)添加了可選參數(shù)。

以飛機(jī)射擊中子彈的構(gòu)建為目的,看下關(guān)于對(duì)象池的使用示例相關(guān):

// GameManager.ts 游戲管理類(lèi)
import { BulletItem } from '../bullet/BulletItem';@ccclass('GameManager')
export class GameManager extends Component {@property(Prefab) bullet: Prefab = null;		// 子彈預(yù)制體private _bulletPool: NodePool = null;				// 子彈對(duì)象池onLoad() {// 創(chuàng)建子彈對(duì)象池this._bulletPool = new NodePool();}// 創(chuàng)建玩家子彈private createPlayerBullet() {// 獲取子彈節(jié)點(diǎn)const bulletNode = this.getBulletNode();const bulletItem = bulletNode.getComponent(BulletItem);// 此處將子彈對(duì)象池傳入子彈對(duì)象腳本bulletItem.init(this._bulletPool);}// 獲取子彈節(jié)點(diǎn)private getBulletNode(): Node {const size = this._bulletPool.size();if (size <= 0) {// 克隆子彈節(jié)點(diǎn)const bulletNode = instantiate(this.bullet);// 將子彈節(jié)點(diǎn)添加到對(duì)象池中this._bulletPool.put(bulletNode);}// 從對(duì)象池中獲取節(jié)點(diǎn)return this._bulletPool.get();}onDestroy() {// 銷(xiāo)毀對(duì)象池this._bulletPool.clear();}
}// BulletItem.ts 子彈對(duì)象組件腳本
export class BulletItem extends Component {private _bulletPool: NodePool = null;public init(bulletPool: NodePool) {this._bulletPool = bulletPool;}private destroyBullet() {// 檢測(cè)是否存在對(duì)象池,如果存在,則將對(duì)象放到對(duì)象池中,否則銷(xiāo)毀if (this._bulletPool) {this._bulletPool.put(this.node);}else {this.node.destory();}}
}

如上例子,簡(jiǎn)單演示了下NodePool對(duì)象池的使用,但需要注意:

  • 最好存儲(chǔ)同類(lèi)型的節(jié)點(diǎn),方便管理
  • 注意檢測(cè)對(duì)象池內(nèi)的對(duì)象數(shù)目或通過(guò)get獲取對(duì)象后,進(jìn)行安全判定,避免null
  • 注意對(duì)象池對(duì)象的釋放

構(gòu)造函數(shù)的可選參數(shù)

在上面的定義文件中,針對(duì)于對(duì)象池的構(gòu)建,有著可選參數(shù)的支持,代碼如下:

// 緩沖池處理組件,用于節(jié)點(diǎn)的回收和復(fù)用邏輯,這個(gè)屬性可以是組件類(lèi)名或組件的構(gòu)造函數(shù)
poolHandlerComp?: Constructor<IPoolHandlerComponent> | string;
// 構(gòu)造函數(shù),可傳遞組件或名稱(chēng),用于處理節(jié)點(diǎn)的復(fù)用和回收事件邏輯
constructor(poolHandlerComp?: Constructor<IPoolHandlerComponent> | string);

可選參數(shù)的支持主要有兩種形式:

  1. string字符串形式
  2. IPoolHandlerComponent 緩存池處理組件形式

對(duì)于這兩種形式,其本質(zhì)就是增加了對(duì)對(duì)象池中對(duì)象的自定義邏輯處理,以組件為參數(shù),看下它的定義:

export interface IPoolHandlerComponent extends Component {// 在對(duì)象被放入對(duì)象池的時(shí)候進(jìn)行調(diào)用unuse(): void;// 從對(duì)象池中獲取對(duì)象的時(shí)候被調(diào)用reuse(args: any): void;
}

這兩個(gè)方法的調(diào)用,看下源碼的實(shí)現(xiàn):

// 來(lái)源于 node-pool.ts
export class NodePool {// 向?qū)ο缶彺娉卮嫒氩恍枰膶?duì)象public put (obj: Node) {if (obj && this._pool.indexOf(obj) === -1) {// 從父節(jié)點(diǎn)移除,但并不cleanupobj.removeFromParent();// 獲取組件poolHandlerComp,并檢測(cè)是否存在 unuse方法,如果存在則調(diào)用const handler = this.poolHandlerComp?obj.getComponent(this.poolHandlerComp):null;if (handler && handler.unuse) {handler.unuse();}this._pool.push(obj);}}// 獲取對(duì)象池中的對(duì)象public get (...args: any[]): Node | null {// 檢測(cè)對(duì)象池中是否有對(duì)象const last = this._pool.length - 1;if (last < 0) {return null;} else {// 將對(duì)象從緩存池中取出const obj = this._pool[last];this._pool.length = last;// 獲取組件poolHandlerComp,并檢測(cè)是否存在reuse方法,如果存在則調(diào)用const handler=this.poolHandlerComp?obj.getComponent(this.poolHandlerComp):null;if (handler && handler.reuse) {handler.reuse(arguments);}return obj;}}
}

上面的代碼有助于對(duì)兩個(gè)方法的調(diào)用時(shí)機(jī)增加一些了解。

下面我們依然以飛機(jī)的子彈構(gòu)建為例,代碼增加一些拓展,用于支持對(duì)象池的自定義邏輯處理。

// GameManager.ts 游戲管理類(lèi)
import { BulletItem } from '../bullet/BulletItem';@ccclass('GameManager')
export class GameManager extends Component {  onLoad() {// 創(chuàng)建子彈對(duì)象池, 參數(shù)設(shè)定為子彈類(lèi)的名字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);}// 獲取子彈節(jié)點(diǎn)時(shí),可以設(shè)置自定義的參數(shù)相關(guān)return this._bulletPool.get();}
}// BulletItem.ts 子彈對(duì)象組件腳本,增加
export class BulletItem extends Component implements IPoolHandlerComponent {unuse(): void {console.log("------ 調(diào)用了組件的 unuse 方法");}reuse(args: any): void {console.log("------ 調(diào)用了組件的 reuse 方法");}
}

增加對(duì)對(duì)象的自定義邏輯處理,其要點(diǎn)就是:

  • 構(gòu)建對(duì)象池時(shí),需要添加可選參數(shù),參數(shù)的名字或組件一定要是對(duì)象的腳本組件相關(guān)
  • 對(duì)象的組件腳本類(lèi),需要增加implements IPoolHandlerComponent 的實(shí)現(xiàn),也就是unusereuse方法
  • 根據(jù)情況,自定義設(shè)定NodePool.get的參數(shù)相關(guān)

到這里,關(guān)于NodePool的基本使用介紹完畢。


NodePool管理器


在上面的例子中,關(guān)于對(duì)象池的使用存在著幾個(gè)問(wèn)題:

  1. 從對(duì)象池獲取對(duì)象和將對(duì)象放入對(duì)象池的調(diào)用在不同的腳本文件中,可能會(huì)出現(xiàn)維護(hù)比較困難的問(wèn)題

  2. 對(duì)象池的構(gòu)建不僅針對(duì)于子彈,而且可能還有敵機(jī),道具等,可能會(huì)出現(xiàn)多個(gè)對(duì)象池且代碼重復(fù)的問(wèn)題。

因此,我們可構(gòu)建一個(gè)對(duì)象池的管理類(lèi),來(lái)統(tǒng)一管理多個(gè)不同的對(duì)象池,類(lèi)似于cocos2d-x中的PoolManager。

大致的屬性和接口是:

屬性或方法說(shuō)明
_nodePoolMap保存所有對(duì)象池的容器,結(jié)構(gòu)是Map<對(duì)象池名, NodePool池>
getNodePoolByName():NodePool通過(guò)名字從容器中獲取對(duì)象池,如果沒(méi)有則創(chuàng)建,如果存在則獲取
getNodeFromPool():Node通過(guò)名字從對(duì)象池中獲取節(jié)點(diǎn),如果沒(méi)有則克隆,如果存在則獲取
putNodeToPool()將節(jié)點(diǎn)放入對(duì)象池中
clearNodePoolByName()通過(guò)名字將對(duì)象池從容器中移除
clearAll()移除容器中的所有對(duì)象池

該類(lèi)使用的是單例模式,詳細(xì)的代碼如下:

// 對(duì)象池管理器
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 通過(guò)對(duì)象池名字從容器中獲取對(duì)象池@param name 對(duì)象池名字@return 對(duì)象池*/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 通過(guò)對(duì)象池名字從對(duì)象池中獲取節(jié)點(diǎn)@param name 對(duì)象池名字@param prefab 可選參數(shù),對(duì)象預(yù)制體@return 對(duì)象池中節(jié)點(diǎn) */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 將節(jié)點(diǎn)放入對(duì)象池中@param name 對(duì)象池名字@param node 節(jié)點(diǎn)*/public putNodeToPool(name: string, node: Node) {let nodePool = this.getNodePoolByName(name);nodePool.put(node);}// 通過(guò)名字將對(duì)象池從容器中移除public clearNodePoolByName(name: string) {// 銷(xiāo)毀對(duì)象池中對(duì)象let nodePool = this.getNodePoolByName(name);nodePool.clear();// 刪除容器元素this._nodePoolMap.delete(name);}// 移除所有對(duì)象池public clearAll() {this._nodePoolMap.forEach((value: NodePool, key: string) => {value.clear();});this._nodePoolMap.clear();}static destoryInstance() {this._instance = null;}
}

測(cè)試示例:

// GameManager.ts 
const BULLET_POOL_NAME = "BulletItem"       // 子彈內(nèi)存池// 創(chuàng)建玩家子彈
private createPlayerBullet() {// 獲取子彈節(jié)點(diǎn),參數(shù):節(jié)點(diǎn)名,子彈預(yù)制體const poolManager = NodePoolManager.instance;const bulletNode = poolManager.getNodeFromPool(BULLET_POOL_NAME, this.bulletPrefab);bulletNode.parent = this.bulletRoot;
}// BulletItem.ts
private destroyBullet() {// 檢測(cè)是否存在對(duì)象池,如果存在,則將對(duì)象放到對(duì)象池中,否則銷(xiāo)毀if (this._bulletPool) {//this._bulletPool.put(this.node);const poolManager = NodePoolManager.instance;poolManager.putNodeToPool(BULLET_POOL_NAME, this.node);}else {this.node.destory();}
}

管理類(lèi)中有個(gè)接口叫做getNodeFromPool(name: string, prefab?: Prefab),第二個(gè)參數(shù)也可以為prefabName,然后通過(guò)resource.load進(jìn)行動(dòng)態(tài)加載,類(lèi)似實(shí)現(xiàn):

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屬于異步操作,可能會(huì)出現(xiàn)代碼未加載完成就獲取的問(wèn)題,因此可使用異步編程

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());}});
}

關(guān)于一些TypeScript的語(yǔ)法相關(guān),可參考博客:

TypeScript 之 Map

TypeScript 之 異步編程

因工作的某些緣故,可能對(duì)NodePool的理解及編寫(xiě)示例有所不當(dāng),請(qǐng)不吝賜教,感激不盡!

最后祝大家學(xué)習(xí)生活愉快!

http://www.risenshineclean.com/news/33095.html

相關(guān)文章:

  • 金壇做網(wǎng)站鏈接交易網(wǎng)
  • 淘寶放單網(wǎng)站怎么做推客平臺(tái)
  • 如何做網(wǎng)站seo優(yōu)化惠州seo報(bào)價(jià)
  • 哪些網(wǎng)站可以做外部錨文本seo營(yíng)銷(xiāo)推廣全程實(shí)例
  • 莆田 做網(wǎng)站的公司騰訊企點(diǎn)是干嘛的
  • 網(wǎng)站平臺(tái)搭建要多少錢(qián)seo發(fā)帖論壇
  • 東莞企業(yè)網(wǎng)站推廣哪里好網(wǎng)絡(luò)游戲推廣員的真實(shí)經(jīng)歷
  • 免費(fèi)空間asp網(wǎng)站知名品牌營(yíng)銷(xiāo)策略
  • 怎么用手機(jī)自己做網(wǎng)站巨量引擎廣告投放平臺(tái)登錄入口
  • 一個(gè)做搞笑類(lèi)視頻的網(wǎng)站取名seo工具下載
  • 做競(jìng)價(jià)網(wǎng)站訪(fǎng)問(wèn)突然變少淮北seo
  • 中山網(wǎng)站設(shè)計(jì)制作免費(fèi)發(fā)廣告的網(wǎng)站大全
  • 備案網(wǎng)站內(nèi)容怎么寫(xiě)信息流推廣渠道
  • 推廣網(wǎng)站排行榜網(wǎng)站推廣和網(wǎng)站優(yōu)化
  • 網(wǎng)絡(luò)營(yíng)銷(xiāo)具體推廣方案seo查詢(xún)網(wǎng)站
  • 電子商務(wù)網(wǎng)站建設(shè)個(gè)人總結(jié)推廣學(xué)院seo教程
  • 網(wǎng)站工商備案查詢(xún)2020年關(guān)鍵詞排名
  • 如何做一個(gè)網(wǎng)頁(yè)布局如何快速優(yōu)化網(wǎng)站排名
  • 做熟食的網(wǎng)站美食網(wǎng)站東莞最新消息今天
  • 有哪些學(xué)做衣服的網(wǎng)站網(wǎng)站推廣如何引流
  • 淘寶網(wǎng)站建設(shè)協(xié)議谷歌瀏覽器下載手機(jī)版安卓官網(wǎng)
  • 昭陽(yáng)區(qū)住房和城鄉(xiāng)建設(shè)管理局網(wǎng)站重慶關(guān)鍵詞seo排名
  • 京東網(wǎng)上商城投訴電話(huà)天津seo托管
  • 網(wǎng)站開(kāi)發(fā)地圖板塊浮動(dòng)青島谷歌優(yōu)化
  • 旅游網(wǎng)站制作百度云網(wǎng)站搜索排名優(yōu)化軟件
  • 定制網(wǎng)站建設(shè)報(bào)價(jià)單網(wǎng)址導(dǎo)航下載到桌面
  • 原創(chuàng)網(wǎng)站模版營(yíng)銷(xiāo)策劃方案模板范文
  • 溫州專(zhuān)業(yè)網(wǎng)站建設(shè)推廣seo信息是什么
  • 南通企業(yè)網(wǎng)頁(yè)制作江西省seo
  • 大連日文網(wǎng)站設(shè)計(jì)營(yíng)銷(xiāo)型網(wǎng)站建設(shè)策劃書(shū)