Custom GameObjects
Most behavior belongs in components, because they can be mixed and attached from data. Sometimes a GameObject class of your own is the better fit: when a type of object always needs the same fields, or when you create very many of them.
Creating a class
import { Entity, GameObject, InspectorBaseClass, InspectorField } from 'bare-engine';
// the prefab fields this class adds, for autocomplete and type checks
export interface EnemyEntity extends Entity
{
health?: number;
}
@InspectorBaseClass
export class Enemy extends GameObject
{
declare entity: EnemyEntity | null;
@InspectorField
health = 3;
OnUpdate(deltaTime: number)
{
this.x -= 50 * deltaTime;
}
Hit()
{
if (--this.health <= 0)
this.Remove();
}
}GameObject lifecycle hooks include OnAwake, OnStart, OnAdded, OnUpdate, OnFixedUpdate, OnPreRender, OnRender, OnPostRender, OnRemoved and OnResize. Their ownership and timing differ from scene hooks; see Lifecycle & Cleanup.
Examples: the RPG's Weapon extends ArcadeObject with a strength field and a Slash button, and its Joystick is a GameObject with its own update.
Using it
In code:
const enemy = this.AddGameObject(Enemy);
const goblin = this.AddGameObject<Enemy>({
baseClass: 'Enemy',
texture: 'goblin',
health: 5,
});In a prefab, with baseClass:
{
"name": "goblin",
"baseClass": "Enemy",
"texture": "goblin",
"health": 5
}@InspectorBaseClass registers the class with the engine automatically, so it can be used by name in prefabs and shows up in the Chrome extension. Without it, register the class yourself with bare.AddClass(Enemy).
Fields marked @InspectorField can be set from prefabs and edited in the extension.
Example: the Showcase's extend demo uses an EmojiObject class as a prefab's baseClass, and the prefabs demo does the same with Fruit.
Typed prefab fields
The EnemyEntity interface and the declare entity line in the class above describe the prefab fields your class adds. They make this.AddGameObject<Enemy>({ health: 5 }) type-checked and give you autocomplete. Without them, TypeScript only accepts the standard entity fields, and health: 5 is an error.
Example: the engine's own Button does this with ButtonEntity, which adds text, fontSize, buttonColor and more.
Object pools
Creating and removing many objects, like bullets, costs time and memory. A pool keeps removed objects and hands them out again.
Registered GameObject classes get a pool automatically. When you Remove() a pooled object, it goes back to its pool, and the next AddGameObject(Bullet) reuses it.
To create the objects up front:
bare.RegisterGameObjectPool(Bullet, 200);Pooled objects get their standard values back when they're reused, but your own fields don't. Reset them in OnAwake, and release listeners in OnRemoved; see pooled objects.
bare.pool gives access to all pools by class name, for example bare.pool.get('Bullet').GetSize().