@hiddentao/clockwork-engine
Version:
A TypeScript/PIXI.js game engine for deterministic, replayable games with built-in rendering
137 lines (136 loc) • 4.42 kB
JavaScript
import { EventEmitter } from "./EventEmitter";
export var GameObjectGroupEventType;
(function (GameObjectGroupEventType) {
GameObjectGroupEventType["ITEM_ADDED"] = "itemAdded";
GameObjectGroupEventType["ITEM_REMOVED"] = "itemRemoved";
GameObjectGroupEventType["LIST_CLEARED"] = "listCleared";
GameObjectGroupEventType["DESTROYED_ITEMS_CLEARED"] = "destroyedItemsCleared";
})(GameObjectGroupEventType || (GameObjectGroupEventType = {}));
/**
* A group/collection manager for GameObjects
*/
export class GameObjectGroup extends EventEmitter {
constructor() {
super();
this.gameObjects = new Map();
}
/**
* Add a GameObject to the group
* @param gameObject The GameObject to add
* @returns The same GameObject that was added
*/
add(gameObject) {
const id = gameObject.getId();
const isNew = !this.gameObjects.has(id);
this.gameObjects.set(id, gameObject);
if (isNew) {
this.emit(GameObjectGroupEventType.ITEM_ADDED, gameObject);
}
return gameObject;
}
/**
* Remove a GameObject from the group
* @param gameObject The GameObject to remove
* @returns True if the GameObject was removed, false if it wasn't in the group
*/
remove(gameObject) {
const gameObjectId = gameObject.getId();
const wasRemoved = this.gameObjects.delete(gameObjectId);
if (wasRemoved) {
this.emit(GameObjectGroupEventType.ITEM_REMOVED, gameObjectId);
}
return wasRemoved;
}
/**
* Check if a GameObject is in the group
* @param gameObject The GameObject to check for
* @returns True if the GameObject is in the group
*/
has(gameObject) {
return this.gameObjects.has(gameObject.getId());
}
/**
* Check if a GameObject with the given ID is in the group
* @param id The ID to check for
* @returns True if a GameObject with this ID is in the group
*/
hasId(id) {
return this.gameObjects.has(id);
}
/**
* Get a GameObject by its ID
* @param id The ID of the GameObject to retrieve
* @returns The GameObject with the given ID, or undefined if not found
*/
getById(id) {
return this.gameObjects.get(id);
}
/**
* Get all active (non-destroyed) GameObjects
* @returns Array of active GameObjects
*/
getAllActive() {
return Array.from(this.gameObjects.values()).filter((obj) => !obj.isDestroyed());
}
/**
* Get the number of GameObjects in the group
* @returns Total count of GameObjects (including destroyed ones)
*/
size() {
return this.gameObjects.size;
}
/**
* Get the number of active (non-destroyed) GameObjects
* @returns Count of non-destroyed GameObjects
*/
activeSize() {
return this.getAllActive().length;
}
/**
* Clear all GameObjects from the group
*/
clear() {
this.gameObjects.clear();
this.emit(GameObjectGroupEventType.LIST_CLEARED);
}
/**
* Destroy all active GameObjects and then clear the group
*/
clearAndDestroy() {
for (const gameObject of this.gameObjects.values()) {
if (!gameObject.isDestroyed()) {
gameObject.destroy();
}
}
this.clear();
}
/**
* Remove all destroyed GameObjects from the group
* @returns Number of destroyed GameObjects that were removed
*/
clearDestroyed() {
const destroyedObjects = [];
for (const [id, gameObject] of this.gameObjects) {
if (gameObject.isDestroyed()) {
destroyedObjects.push(gameObject);
this.gameObjects.delete(id);
}
}
if (destroyedObjects.length > 0) {
this.emit(GameObjectGroupEventType.DESTROYED_ITEMS_CLEARED, destroyedObjects);
}
return destroyedObjects.length;
}
/**
* Update all GameObjects in the group
* @param deltaTicks Number of ticks since last update
* @param totalTicks Total number of ticks processed since start
*/
update(deltaTicks, totalTicks) {
for (const gameObject of this.gameObjects.values()) {
if (!gameObject.isDestroyed()) {
gameObject.update(deltaTicks, totalTicks);
}
}
}
}