diff --git a/assets/_Game/Prefabs/Ball.prefab b/assets/_Game/Prefabs/Ball.prefab index 0ae4530..7b75c2f 100644 --- a/assets/_Game/Prefabs/Ball.prefab +++ b/assets/_Game/Prefabs/Ball.prefab @@ -962,6 +962,12 @@ "__prefab": { "__id__": 70 }, + "rigidbody": { + "__id__": 67 + }, + "collider": { + "__id__": 65 + }, "_id": "" }, { diff --git a/assets/_Game/Scripts/Gameplay/Ball.ts b/assets/_Game/Scripts/Gameplay/Ball.ts index 806775c..2df4d30 100644 --- a/assets/_Game/Scripts/Gameplay/Ball.ts +++ b/assets/_Game/Scripts/Gameplay/Ball.ts @@ -10,10 +10,12 @@ import { IPhysics2DContact, RigidBody2D, } from 'cc'; +import IPoolable from '../Pool/IPoolable'; +import Utilities from '../Utilities/Utilities'; const { ccclass, property } = _decorator; @ccclass('Ball') -export class Ball extends Component { +export class Ball extends Component implements IPoolable { @property({ visible: true, type: CCFloat }) public maxSpeed: number; @property({ visible: true, type: RigidBody2D }) @@ -47,4 +49,12 @@ export class Ball extends Component { // console.log(otherCollider.tag, otherCollider.node.name); this.hitted = false; } + + reuse() { + console.log('use'); + } + + unuse() { + console.log('unuse'); + } } diff --git a/assets/_Game/Scripts/Manager/GameManager.ts b/assets/_Game/Scripts/Manager/GameManager.ts index 9018d88..5c3a0eb 100644 --- a/assets/_Game/Scripts/Manager/GameManager.ts +++ b/assets/_Game/Scripts/Manager/GameManager.ts @@ -1,6 +1,6 @@ -import { _decorator, Component, Prefab } from 'cc'; +import { _decorator, Component, Prefab, Node } from 'cc'; import ObjectPool from '../Pool/ObjectPool'; -import Utilities from '../Utilities/Utilities'; +import { Ball } from '../Gameplay/Ball'; const { ccclass, property } = _decorator; @ccclass('GameManager') @@ -19,15 +19,7 @@ export class GameManager extends Component { public score = 0; protected onLoad(): void { - this._ballPool = new ObjectPool(this._ballPrefab, 10, false); - } - - protected async start() { - while (true) { - const ball = this._ballPool.get(this.node); - ball.setWorldPosition(this.node.worldPosition); - await Utilities.delay(1000); - } + this._ballPool = new ObjectPool(this._ballPrefab, 10, false, Ball); } public onRevive() { diff --git a/assets/_Game/Scripts/Pool/IPoolable.ts b/assets/_Game/Scripts/Pool/IPoolable.ts index 576724d..a1be534 100644 --- a/assets/_Game/Scripts/Pool/IPoolable.ts +++ b/assets/_Game/Scripts/Pool/IPoolable.ts @@ -1,4 +1,4 @@ export default interface IPoolable { - unuse(): void; - reuse(): void; + reuse(); + unuse(); } diff --git a/assets/_Game/Scripts/Pool/ObjectPool.ts b/assets/_Game/Scripts/Pool/ObjectPool.ts index 1719dfa..4489bea 100644 --- a/assets/_Game/Scripts/Pool/ObjectPool.ts +++ b/assets/_Game/Scripts/Pool/ObjectPool.ts @@ -1,10 +1,12 @@ -import { Component, Node, Prefab, __private, director, instantiate } from 'cc'; +import { Component, Node, Prefab, director, instantiate } from 'cc'; +import IPoolable from './IPoolable'; export default class ObjectPool { private _inactives: Node[] = []; private _actives: Node[] = []; private _prefab: Prefab; private _expandable; + private _poolHandlerComp: new () => any; public get countInactive() { return this._inactives.length; @@ -18,68 +20,65 @@ export default class ObjectPool { return this.countInactive + this.countActive; } - constructor(prefab: Prefab, size: number, expandable = true) { - this._expandable = expandable; + constructor(prefab: Prefab, size: number, expandable = true, poolHandlerComp?: new () => any | string) { this._prefab = prefab; + this._expandable = expandable; + this._poolHandlerComp = poolHandlerComp; for (let i = 0; i < size; ++i) { let obj = instantiate(this._prefab); // create node instance - obj.active = false; - this._inactives.push(obj); // populate your pool with put method + obj.removeFromParent(); + this._inactives.push(obj); } } public get(parent?: Node): Node; - public get( - parent?: Node, - classConstructor?: - | __private._types_globals__Constructor - | __private._types_globals__AbstractedConstructor, - ): T; + public get(parent?: Node, classConstructor?: new () => T): T; - public get( - parent?: Node, - classConstructor?: - | __private._types_globals__Constructor - | __private._types_globals__AbstractedConstructor, - ): T | Node { + public get(parent?: Node, classConstructor?: new () => T): T | Node { let obj: Node = null; let p = parent || director.getScene(); if (this._inactives.length > 0) { - // use size method to check if there're nodes available in the pool + // Pop the last object in pool obj = this._inactives.pop(); - obj.setParent(p); - this._actives.push(obj); } else if (this._expandable) { // if not enough node in the pool, we call cc.instantiate to create node obj = instantiate(this._prefab); - obj.setParent(p); - this._actives.push(obj); } else { obj = this._actives.shift(); - this._actives.push(obj); } - obj.active = true; - if (classConstructor) { - return obj.getComponent(classConstructor); + obj.setParent(p); + this._actives.push(obj); + // Invoke pool handler + const handler = this._poolHandlerComp ? obj.getComponent(this._poolHandlerComp) : null; + if (handler) { + (handler as unknown as IPoolable)?.reuse(); } + + if (classConstructor) { + return handler == classConstructor ? handler : obj.getComponent(classConstructor); + } + return obj; } - public release(obj: Node); - public release(obj: T); - public release(obj: T | Node) { - if (obj instanceof Node) { - obj.active = false; - const index = this._actives.indexOf(obj); - this._actives.splice(index, 1); - this._inactives.push(obj); - } else { - obj.node.active = false; - const index = this._actives.indexOf(obj.node); - this._actives.splice(index, 1); - this._inactives.push(obj.node); + public release(obj: Node): void; + public release(obj: T): void; + public release(obj: T | Node): void { + let node = obj instanceof Node ? obj : obj.node; + const index = this._actives.indexOf(node); + //check obj is belongs to pool + if (index === -1) return; + this._actives.splice(index, 1); + this._inactives.push(node); + // Invoke pool handler + + const handler = this._poolHandlerComp ? node.getComponent(this._poolHandlerComp) : null; + if (handler) { + (handler as unknown as IPoolable)?.unuse(); } + // Remove from parent, but don't cleanup + node.removeFromParent(); } public clear() {