feat: spawn score object

main
tiendat3699 2024-03-08 00:45:13 +07:00
parent a5995a7942
commit 712cb8aa30
14 changed files with 4324 additions and 178 deletions

View File

@ -0,0 +1,303 @@
[
{
"__type__": "cc.AnimationClip",
"_name": "ScoreObjectSpawn",
"_objFlags": 0,
"__editorExtras__": {
"embeddedPlayerGroups": []
},
"_native": "",
"sample": 60,
"speed": 1,
"wrapMode": 1,
"enableTrsBlending": false,
"_duration": 0.3333333333333333,
"_hash": 500763545,
"_tracks": [
{
"__id__": 1
},
{
"__id__": 12
}
],
"_exoticAnimation": null,
"_events": [],
"_embeddedPlayers": []
},
{
"__type__": "cc.animation.VectorTrack",
"_binding": {
"__type__": "cc.animation.TrackBinding",
"path": {
"__id__": 2
},
"proxy": null
},
"_channels": [
{
"__id__": 4
},
{
"__id__": 6
},
{
"__id__": 8
},
{
"__id__": 10
}
],
"_nComponents": 3
},
{
"__type__": "cc.animation.TrackPath",
"_paths": [
{
"__id__": 3
},
"position"
]
},
{
"__type__": "cc.animation.HierarchyPath",
"path": "Sprite"
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 5
}
},
{
"__type__": "cc.RealCurve",
"_times": [],
"_values": [],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 7
}
},
{
"__type__": "cc.RealCurve",
"_times": [
0,
0.16666666666666666
],
"_values": [
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": 50,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": null
},
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": -25,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": null
}
],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 9
}
},
{
"__type__": "cc.RealCurve",
"_times": [],
"_values": [],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 11
}
},
{
"__type__": "cc.RealCurve",
"_times": [],
"_values": [],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.VectorTrack",
"_binding": {
"__type__": "cc.animation.TrackBinding",
"path": {
"__id__": 13
},
"proxy": null
},
"_channels": [
{
"__id__": 15
},
{
"__id__": 17
},
{
"__id__": 19
},
{
"__id__": 21
}
],
"_nComponents": 3
},
{
"__type__": "cc.animation.TrackPath",
"_paths": [
{
"__id__": 14
},
"scale"
]
},
{
"__type__": "cc.animation.HierarchyPath",
"path": "Sprite"
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 16
}
},
{
"__type__": "cc.RealCurve",
"_times": [],
"_values": [],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 18
}
},
{
"__type__": "cc.RealCurve",
"_times": [
0,
0.08333333333333333,
0.18333333333333332,
0.2833333333333333,
0.3333333333333333
],
"_values": [
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": 1,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": null
},
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": 1,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": null
},
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": 0.5,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": null
},
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": 1.100000023841858,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": null
},
{
"__type__": "cc.RealKeyframeValue",
"interpolationMode": 0,
"tangentWeightMode": 0,
"value": 1,
"rightTangent": 0,
"rightTangentWeight": 1,
"leftTangent": 0,
"leftTangentWeight": 1,
"easingMethod": 0,
"__editorExtras__": null
}
],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 20
}
},
{
"__type__": "cc.RealCurve",
"_times": [],
"_values": [],
"preExtrapolation": 1,
"postExtrapolation": 1
},
{
"__type__": "cc.animation.Channel",
"_curve": {
"__id__": 22
}
},
{
"__type__": "cc.RealCurve",
"_times": [],
"_values": [],
"preExtrapolation": 1,
"postExtrapolation": 1
}
]

View File

@ -0,0 +1,13 @@
{
"ver": "2.0.3",
"importer": "animation-clip",
"imported": true,
"uuid": "cfd9afd6-9345-446c-bf56-b7ac3dbf2c1e",
"files": [
".cconb"
],
"subMetas": {},
"userData": {
"name": "ScoreObjectSpawn"
}
}

View File

@ -16,32 +16,85 @@
"_objFlags": 0, "_objFlags": 0,
"__editorExtras__": {}, "__editorExtras__": {},
"_parent": null, "_parent": null,
"_children": [], "_children": [
"_active": true,
"_components": [
{ {
"__id__": 2 "__id__": 2
}, }
{ ],
"__id__": 4 "_active": true,
}, "_components": [
{
"__id__": 6
},
{ {
"__id__": 8 "__id__": 8
}, },
{ {
"__id__": 10 "__id__": 10
},
{
"__id__": 12
},
{
"__id__": 14
},
{
"__id__": 16
} }
], ],
"_prefab": { "_prefab": {
"__id__": 12 "__id__": 18
}, },
"_lpos": { "_lpos": {
"__type__": "cc.Vec3", "__type__": "cc.Vec3",
"x": 0, "x": 0,
"y": -521.891, "y": 0,
"z": 0
},
"_lrot": {
"__type__": "cc.Quat",
"x": 0,
"y": 0,
"z": 0,
"w": 1
},
"_lscale": {
"__type__": "cc.Vec3",
"x": 1,
"y": 1,
"z": 1
},
"_mobility": 0,
"_layer": 33554432,
"_euler": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_id": ""
},
{
"__type__": "cc.Node",
"_name": "Sprite",
"_objFlags": 0,
"_parent": {
"__id__": 1
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 3
},
{
"__id__": 5
}
],
"_prefab": {
"__id__": 7
},
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": -25,
"z": 0 "z": 0
}, },
"_lrot": { "_lrot": {
@ -72,11 +125,11 @@
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 1 "__id__": 2
}, },
"_enabled": true, "_enabled": true,
"__prefab": { "__prefab": {
"__id__": 3 "__id__": 4
}, },
"_contentSize": { "_contentSize": {
"__type__": "cc.Size", "__type__": "cc.Size",
@ -86,24 +139,24 @@
"_anchorPoint": { "_anchorPoint": {
"__type__": "cc.Vec2", "__type__": "cc.Vec2",
"x": 0.5, "x": 0.5,
"y": 0.5 "y": 0
}, },
"_id": "" "_id": ""
}, },
{ {
"__type__": "cc.CompPrefabInfo", "__type__": "cc.CompPrefabInfo",
"fileId": "dd1k5yz/9Jw7Y3h/ln7e+D" "fileId": "7eQbUjrCxCdqX0lbHJJf5m"
}, },
{ {
"__type__": "cc.Sprite", "__type__": "cc.Sprite",
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
"__id__": 1 "__id__": 2
}, },
"_enabled": true, "_enabled": true,
"__prefab": { "__prefab": {
"__id__": 5 "__id__": 6
}, },
"_customMaterial": null, "_customMaterial": null,
"_srcBlendFactor": 2, "_srcBlendFactor": 2,
@ -136,10 +189,23 @@
}, },
{ {
"__type__": "cc.CompPrefabInfo", "__type__": "cc.CompPrefabInfo",
"fileId": "33Vv42hplKv6Fr1cHzlkpg" "fileId": "8f4n9BtRRP+4F8ppzXIOAb"
}, },
{ {
"__type__": "ab3adcigCNMO4YLHg1OcMdG", "__type__": "cc.PrefabInfo",
"root": {
"__id__": 1
},
"asset": {
"__id__": 0
},
"fileId": "58e2t45HZDcaGTymn9uf1N",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
"__type__": "cc.UITransform",
"_name": "", "_name": "",
"_objFlags": 0, "_objFlags": 0,
"node": { "node": {
@ -147,21 +213,23 @@
}, },
"_enabled": true, "_enabled": true,
"__prefab": { "__prefab": {
"__id__": 7 "__id__": 9
}, },
"_collider": { "_contentSize": {
"__id__": 8 "__type__": "cc.Size",
"width": 20,
"height": 50
}, },
"_sprite": { "_anchorPoint": {
"__id__": 4 "__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
}, },
"_score": 10,
"_flySpeed": 500,
"_id": "" "_id": ""
}, },
{ {
"__type__": "cc.CompPrefabInfo", "__type__": "cc.CompPrefabInfo",
"fileId": "fc99DKgwZBHalLOt5fRIss" "fileId": "dd1k5yz/9Jw7Y3h/ln7e+D"
}, },
{ {
"__type__": "cc.BoxCollider2D", "__type__": "cc.BoxCollider2D",
@ -172,7 +240,7 @@
}, },
"_enabled": true, "_enabled": true,
"__prefab": { "__prefab": {
"__id__": 9 "__id__": 11
}, },
"tag": 0, "tag": 0,
"_group": 16, "_group": 16,
@ -205,7 +273,7 @@
}, },
"_enabled": true, "_enabled": true,
"__prefab": { "__prefab": {
"__id__": 11 "__id__": 13
}, },
"enabledContactListener": true, "enabledContactListener": true,
"bullet": false, "bullet": false,
@ -229,6 +297,62 @@
"__type__": "cc.CompPrefabInfo", "__type__": "cc.CompPrefabInfo",
"fileId": "bbOXJ9GJVHppWgt0OjwEBK" "fileId": "bbOXJ9GJVHppWgt0OjwEBK"
}, },
{
"__type__": "3bd17tsjpdMZqOLOE4CWMkE",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 15
},
"_collider": {
"__id__": 10
},
"_sprite": {
"__id__": 5
},
"_spawnAnimation": {
"__id__": 16
},
"_score": 10,
"_flySpeed": 500,
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "f3W6S5U0BKM6/Fx3RiEC8W"
},
{
"__type__": "cc.Animation",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 1
},
"_enabled": true,
"__prefab": {
"__id__": 17
},
"playOnLoad": false,
"_clips": [
{
"__uuid__": "cfd9afd6-9345-446c-bf56-b7ac3dbf2c1e",
"__expectedType__": "cc.AnimationClip"
}
],
"_defaultClip": {
"__uuid__": "cfd9afd6-9345-446c-bf56-b7ac3dbf2c1e",
"__expectedType__": "cc.AnimationClip"
},
"_id": ""
},
{
"__type__": "cc.CompPrefabInfo",
"fileId": "9cExf3IzxEa53jorYVyMdR"
},
{ {
"__type__": "cc.PrefabInfo", "__type__": "cc.PrefabInfo",
"root": { "root": {
@ -238,6 +362,7 @@
"__id__": 0 "__id__": 0
}, },
"fileId": "31K2tUn39G47RitJdKcKW+", "fileId": "31K2tUn39G47RitJdKcKW+",
"instance": null,
"targetOverrides": null "targetOverrides": null
} }
] ]

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
import { _decorator, CCInteger, Collider2D, Component, Contact2DType, Node } from 'cc'; import { _decorator, CCInteger, Collider2D, Component, Contact2DType, Node } from 'cc';
import { GameManager } from '../Manager/GameManager'; import { GameManager } from '../Manager/GameManager';
import ObjectPool from '../Pool/ObjectPool';
const { ccclass, property, float } = _decorator; const { ccclass, property, float } = _decorator;
@ccclass('Goal') @ccclass('Goal')
@ -14,6 +15,7 @@ export class Goal extends Component {
} }
private onContactBegin(selfCollider: Collider2D, otherCollider: Collider2D) { private onContactBegin(selfCollider: Collider2D, otherCollider: Collider2D) {
GameManager.instance.goal(this._score, otherCollider.node); ObjectPool.release(otherCollider.node);
GameManager.instance.goal(this._score);
} }
} }

View File

@ -1,13 +1,31 @@
import { _decorator, CCFloat, CCInteger, Collider2D, Color, Component, Contact2DType, Sprite, Vec3 } from 'cc'; import {
_decorator,
Animation,
CCFloat,
CCInteger,
Collider2D,
Color,
Component,
Contact2DType,
Sprite,
Vec3,
} from 'cc';
import { GameManager } from '../Manager/GameManager'; import { GameManager } from '../Manager/GameManager';
import IPoolable from '../Pool/IPoolable';
import ObjectPool from '../Pool/ObjectPool';
import Utilities from '../Utilities/Utilities';
import { EventManger } from '../Manager/EventManger';
import GameEvent from '../Events/GameEvent';
const { ccclass, property, float } = _decorator; const { ccclass, property, float } = _decorator;
@ccclass('DamageableObject') @ccclass('ScoreObject')
export class DamageableObject extends Component { export class ScoreObject extends Component implements IPoolable {
@property({ type: Collider2D, visible: true }) @property({ type: Collider2D, visible: true })
private _collider: Collider2D; private _collider: Collider2D;
@property({ type: Sprite, visible: true }) @property({ type: Sprite, visible: true })
private _sprite: Sprite; private _sprite: Sprite;
@property({ type: Animation, visible: true })
private _spawnAnimation: Animation;
@property({ type: CCInteger, visible: true }) @property({ type: CCInteger, visible: true })
private _score: number; private _score: number;
@property({ type: CCFloat, visible: true }) @property({ type: CCFloat, visible: true })
@ -15,10 +33,12 @@ export class DamageableObject extends Component {
private _flyDirection: Vec3; private _flyDirection: Vec3;
private _targetColor: Color; private _targetColor: Color;
private _originColor: Color;
private _hitted = false; private _hitted = false;
protected onLoad(): void { protected onLoad(): void {
this._collider.on(Contact2DType.BEGIN_CONTACT, this.onContactBegin, this); this._collider.on(Contact2DType.BEGIN_CONTACT, this.onContactBegin, this);
this._originColor = this._sprite.color.clone();
} }
protected update(dt: number): void { protected update(dt: number): void {
@ -28,13 +48,15 @@ export class DamageableObject extends Component {
this.node.worldPosition = this.node.getWorldPosition().add(pos); this.node.worldPosition = this.node.getWorldPosition().add(pos);
const scale = new Vec3(); const scale = new Vec3();
Vec3.multiplyScalar(scale, Vec3.ONE.clone(), 0.5 * dt); Vec3.multiplyScalar(scale, Vec3.ONE.clone(), 1 * dt);
this.node.scale = this.node.getScale().add(scale); this.node.scale = this.node.getScale().add(scale);
this.node.angle += 800 * dt; this.node.angle += 800 * dt;
this._sprite.color = this._sprite.color.clone().lerp(this._targetColor, 2 * dt); this._sprite.color = this._sprite.color.clone().lerp(this._targetColor, 1 * dt);
if (this._sprite.color.a == 0) { if (this._sprite.color.a == 0) {
EventManger.instance.emit(GameEvent.ScoreObjectRelease, this.node);
ObjectPool.release(this.node);
} }
} }
} }
@ -54,4 +76,16 @@ export class DamageableObject extends Component {
GameManager.instance.destroyEnviromentsObject(this._score); GameManager.instance.destroyEnviromentsObject(this._score);
} }
} }
public reuse() {
this._spawnAnimation.play();
this._collider.enabled = true;
}
public unuse() {
this._hitted = false;
this.node.angle = 0;
this.node.setScale(Vec3.ONE);
this._sprite.color = this._originColor;
}
} }

View File

@ -2,7 +2,7 @@
"ver": "4.0.23", "ver": "4.0.23",
"importer": "typescript", "importer": "typescript",
"imported": true, "imported": true,
"uuid": "ab3ad722-8023-4c3b-860b-1e0d4e70c746", "uuid": "3bd17b6c-8e97-4c66-a38b-384e0258c904",
"files": [], "files": [],
"subMetas": {}, "subMetas": {},
"userData": {} "userData": {}

View File

@ -1,19 +1,23 @@
import { Node } from 'cc';
import GameState from '../Enum/GameState'; import GameState from '../Enum/GameState';
import ScoreType from '../Enum/ScoreType'; import ScoreType from '../Enum/ScoreType';
enum GameEvent { enum GameEvent {
GameStateChange, GameStateChange,
Score, Score,
ScoreObjectRelease,
} }
export interface GameEventCallbackMap { export interface GameEventCallbackMap {
[GameEvent.GameStateChange]: (state: GameState) => void; [GameEvent.GameStateChange]: (state: GameState) => void;
[GameEvent.Score]: (type: ScoreType, score: number) => void; [GameEvent.Score]: (type: ScoreType, score: number) => void;
[GameEvent.ScoreObjectRelease]: (obj: Node) => void;
} }
export interface GameEventArgMap { export interface GameEventArgMap {
[GameEvent.GameStateChange]: GameState; [GameEvent.GameStateChange]: GameState;
[GameEvent.Score]: [ScoreType, number]; [GameEvent.Score]: [ScoreType, number];
[GameEvent.ScoreObjectRelease]: Node;
} }
export default GameEvent; export default GameEvent;

View File

@ -23,6 +23,7 @@ import IPoolable from '../Pool/IPoolable';
import { SoundManager } from '../Manager/SoundManager'; import { SoundManager } from '../Manager/SoundManager';
import PhysicsGroup from '../Enum/PhysicGroup'; import PhysicsGroup from '../Enum/PhysicGroup';
import ObjectPool from '../Pool/ObjectPool'; import ObjectPool from '../Pool/ObjectPool';
import Utilities from '../Utilities/Utilities';
const { ccclass, property } = _decorator; const { ccclass, property } = _decorator;
@ccclass('Ball') @ccclass('Ball')
@ -83,7 +84,11 @@ export class Ball extends Component implements IPoolable {
} }
} }
private onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null) { private async onBeginContact(
selfCollider: Collider2D,
otherCollider: Collider2D,
contact: IPhysics2DContact | null,
) {
if (this._hitted) return; if (this._hitted) return;
this._hitted = true; this._hitted = true;
if (this._rigidbody.linearVelocity.length() >= 3) { if (this._rigidbody.linearVelocity.length() >= 3) {
@ -101,6 +106,8 @@ export class Ball extends Component implements IPoolable {
hitfx.node.setWorldPosition(new Vec3(hitPoint.x, hitPoint.y, 10)); hitfx.node.setWorldPosition(new Vec3(hitPoint.x, hitPoint.y, 10));
hitfx.play(); hitfx.play();
SoundManager.instance.playSfx(this._hitSound); SoundManager.instance.playSfx(this._hitSound);
await Utilities.waitUntil(() => hitfx.isStopped, 100);
this._impactPool.release(hitfx.node);
} }
} }

View File

@ -1,5 +1,6 @@
import { _decorator, Collider2D, Component, Contact2DType, Node } from 'cc'; import { _decorator, Collider2D, Component, Contact2DType, Node } from 'cc';
import { GameManager } from '../Manager/GameManager'; import { GameManager } from '../Manager/GameManager';
import ObjectPool from '../Pool/ObjectPool';
const { ccclass, property } = _decorator; const { ccclass, property } = _decorator;
@ccclass('Outer') @ccclass('Outer')
@ -12,6 +13,7 @@ export class Outer extends Component {
} }
private onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D) { private onBeginContact(selfCollider: Collider2D, otherCollider: Collider2D) {
GameManager.instance.ballOut(otherCollider.node); ObjectPool.release(otherCollider.node);
GameManager.instance.ballOut();
} }
} }

View File

@ -62,18 +62,17 @@ export class GameManager extends Component {
return ball; return ball;
} }
public async ballOut(ball: Node) { public async ballOut() {
this._balls--; this._balls--;
this._ballPool.release(ball);
if (this._balls === 0) { if (this._balls === 0) {
this._ballPool.clear();
return; return;
} }
await Utilities.delay(1000); await Utilities.delay(1000);
this.spawnBall(); this.spawnBall();
} }
public async goal(bonusScore: number, ball: Node) { public async goal(bonusScore: number) {
this._ballPool.release(ball);
this.addScore(bonusScore, ScoreType.Goal); this.addScore(bonusScore, ScoreType.Goal);
await Utilities.delay(1000); await Utilities.delay(1000);
this.spawnBall(); this.spawnBall();

View File

@ -1,4 +1,8 @@
import { _decorator, Component, Node, Prefab } from 'cc'; import { _decorator, CCFloat, Component, Node, Prefab, randomRangeInt } from 'cc';
import ObjectPool from '../Pool/ObjectPool';
import { ScoreObject } from '../Environments/ScoreObject';
import { EventManger } from './EventManger';
import GameEvent from '../Events/GameEvent';
const { ccclass, property } = _decorator; const { ccclass, property } = _decorator;
@ccclass('SpawnObjectManager') @ccclass('SpawnObjectManager')
@ -14,8 +18,49 @@ export class SpawnObjectManager extends Component {
private _objects: Prefab[] = []; private _objects: Prefab[] = [];
@property({ type: [Node], visible: true }) @property({ type: [Node], visible: true })
private _spawnPoints: Node[] = []; private _spawnPoints: Node[] = [];
@property({ type: CCFloat, visible: true, range: [1, 10], slide: true })
private _spawnTime;
private _pools: ObjectPool[] = [];
private _usedPoints: { [key: string]: Node } = {};
private _timer = 0;
protected onLoad(): void { protected onLoad(): void {
SpawnObjectManager._instance = this; SpawnObjectManager._instance = this;
EventManger.instance.on(GameEvent.ScoreObjectRelease, this.onObjectRelease, this);
for (let i = 0; i < this._objects.length; i++) {
const prefab = this._objects[i];
this._pools[i] = new ObjectPool(prefab, 10, true, ScoreObject);
}
}
protected start(): void {
for (let i = 0; i < randomRangeInt(5, 10); i++) {
this.spawn();
}
}
protected update(dt: number): void {
this._timer += dt;
if (this._timer >= this._spawnTime) {
this._timer = 0;
this.spawn();
}
}
private spawn() {
if (Object.keys(this._usedPoints).length == this._spawnPoints.length) return;
var randomPool = this._pools[randomRangeInt(0, this._pools.length)];
do {
var randomPoint = this._spawnPoints[randomRangeInt(0, this._spawnPoints.length)];
} while (Object.values(this._usedPoints).indexOf(randomPoint) != -1);
const obj = randomPool.get(this.node);
obj.setWorldPosition(randomPoint.worldPosition);
this._usedPoints[obj.uuid] = randomPoint;
}
private onObjectRelease(obj: Node) {
delete this._usedPoints[obj.uuid];
} }
} }

View File

@ -28,9 +28,17 @@ export default class ObjectPool {
let obj = instantiate(this._prefab); // create node instance let obj = instantiate(this._prefab); // create node instance
obj.removeFromParent(); obj.removeFromParent();
this._inactives.push(obj); this._inactives.push(obj);
ObjectPool._poolLookUp[obj.uuid] = this;
} }
} }
//#region Static
private static _poolLookUp: { [key: string]: ObjectPool } = {};
public static release(obj: Node) {
ObjectPool._poolLookUp[obj.uuid].release(obj);
}
//#endregion
public get(parent?: Node): Node; public get(parent?: Node): Node;
public get<T extends Component>(parent?: Node, classConstructor?: new () => T): T; public get<T extends Component>(parent?: Node, classConstructor?: new () => T): T;
public get<T extends Component>(parent?: Node, classConstructor?: new () => T): T | Node { public get<T extends Component>(parent?: Node, classConstructor?: new () => T): T | Node {
@ -42,6 +50,7 @@ export default class ObjectPool {
} else if (this._expandable) { } else if (this._expandable) {
// if not enough node in the pool, we call cc.instantiate to create node // if not enough node in the pool, we call cc.instantiate to create node
obj = instantiate(this._prefab); obj = instantiate(this._prefab);
ObjectPool._poolLookUp[obj.uuid] = this;
} else { } else {
obj = this._actives.shift(); obj = this._actives.shift();
} }
@ -57,7 +66,6 @@ export default class ObjectPool {
if (classConstructor) { if (classConstructor) {
return handler == classConstructor ? handler : obj.getComponent(classConstructor); return handler == classConstructor ? handler : obj.getComponent(classConstructor);
} }
return obj; return obj;
} }
@ -84,5 +92,10 @@ export default class ObjectPool {
this._inactives.forEach((obj) => obj.destroy()); this._inactives.forEach((obj) => obj.destroy());
this._inactives = []; this._inactives = [];
this._actives = []; this._actives = [];
Object.keys(ObjectPool._poolLookUp).forEach((key) => {
if (ObjectPool._poolLookUp[key] === this) {
delete ObjectPool._poolLookUp[key];
}
});
} }
} }

View File

@ -8,6 +8,17 @@ export default class Utilities {
return new Promise((resolve) => setTimeout(resolve, time)); return new Promise((resolve) => setTimeout(resolve, time));
} }
/**
*@param predicate
* @param time (ms)
* @returns
*/
public static async waitUntil(predicate: () => boolean, timeCheck = 10) {
while (!predicate()) {
await this.delay(timeCheck);
}
}
public static getJson(json: string): any { public static getJson(json: string): any {
try { try {
return JSON.parse(json); return JSON.parse(json);