BoxCollider2D
A rectangular 2D collider.
| Type | Name | Interface Description |
|---|---|---|
| Variables | size: Vector2f | • Function: Gets or sets the authored size of the 2D box collider. This is the full width and height of the rectangular shape. |
| Functions | constructor() |
Examples
constructor()
let obj = new APJS.BoxCollider2D();
Use Case
Example 1 — Play a sound effect when a 2D physics object collides — uses CollisionEvent2D.Enter on collider's object emitter
@component()
export class CollisionSoundEffect extends APJS.BasicScriptComponent {
@serializeProperty
sfxPlayer!: APJS.SceneObject;
private sfxAudio!: APJS.AudioComponent;
private collider!: APJS.BoxCollider2D;
private initialized = false;
private collisionCallback!: (event: APJS.IEvent) => void;
onUpdate(dt: number): void {
if (this.initialized) return;
if (!this.sfxPlayer) return;
this.sfxAudio = this.sfxPlayer.getComponent("AudioComponent") as APJS.AudioComponent;
// Get any 2D collider on this object (BoxCollider2D or CircleCollider2D)
this.collider = this.getSceneObject().getComponent("BoxCollider2D") as APJS.BoxCollider2D;
if (!this.sfxAudio || !this.collider) return;
// CRITICAL: enable collision events before registering listener
this.collider.emitCollisionEvent = true;
this.collisionCallback = (event: APJS.IEvent) => {
// Play SFX on each collision
this.sfxAudio.stop();
this.sfxAudio.loopCount = 1;
this.sfxAudio.play();
};
// Use object emitter on the COLLIDER (not global emitter)
const emitter = APJS.EventManager.getObjectEmitter(this.collider);
emitter.on(APJS.CollisionEvent2D.Enter, this.collisionCallback, this);
this.initialized = true;
}
onDestroy(): void {
if (this.collider && this.collisionCallback) {
const emitter = APJS.EventManager.getObjectEmitter(this.collider);
emitter.off(APJS.CollisionEvent2D.Enter, this.collisionCallback, this);
}
}
}
Example 2 — Detect 2D collision and reverse velocity to bounce off obstacles
@component()
export class CollisionBounce extends APJS.BasicScriptComponent {
private collisionCallback: (event: APJS.IEvent) => void;
private collider: APJS.BoxCollider2D;
private velocity: APJS.Vector2f = new APJS.Vector2f(100, 100);
private startVelocity: APJS.Vector2f = new APJS.Vector2f(100, 100);
private startPos!: APJS.Vector2f;
private startGravityOn = true;
private rb!: APJS.RigidBody2D;
private inited = false;
// RecordStart: reset bouncing ball per Physics2D §"RecordStart Reset for 2D Physics"
// (single-body block): velocity → script accumulators (this.velocity) → anchoredPosition
// → useGravity. Listener wiring per GameState §"RecordStart / RecordEnd Lifecycle".
private onRecordStart = (_event: APJS.IEvent) => {
if (!this.inited) return;
this.rb.velocity = new APJS.Vector2f(0, 0);
this.velocity = new APJS.Vector2f(this.startVelocity.x, this.startVelocity.y);
const obj = this.getSceneObject();
const st = obj.getComponent("ScreenTransform") as APJS.ScreenTransform;
if (st && this.startPos) {
st.anchoredPosition = new APJS.Vector2f(this.startPos.x, this.startPos.y);
}
this.rb.useGravity = this.startGravityOn;
};
onStart(): void {
this.collider = this.getSceneObject().getComponent("BoxCollider2D") as APJS.BoxCollider2D;
if (!this.collider) return;
this.collider.emitCollisionEvent = true;
this.collisionCallback = (event: APJS.IEvent) => {
const infos = event.args[0] as APJS.CollisionInfo2D[];
for (const info of infos) {
// Reflect velocity based on collision normal
const normal = info.normal;
const dot = this.velocity.x * normal.x + this.velocity.y * normal.y;
this.velocity = new APJS.Vector2f(
this.velocity.x - 2 * dot * normal.x,
this.velocity.y - 2 * dot * normal.y
);
}
};
const emitter = APJS.EventManager.getObjectEmitter(this.collider);
emitter.on(APJS.CollisionEvent2D.Enter, this.collisionCallback, this);
APJS.EventManager.getGlobalEmitter().on(APJS.EventType.RecordStart, this.onRecordStart);
}
onUpdate(deltaTime: number): void {
const rb = this.getSceneObject().getComponent("RigidBody2D") as APJS.RigidBody2D;
if (!rb) return;
if (!this.inited) {
this.rb = rb;
const st = this.getSceneObject().getComponent("ScreenTransform") as APJS.ScreenTransform;
if (st) this.startPos = new APJS.Vector2f(st.anchoredPosition.x, st.anchoredPosition.y);
this.startGravityOn = rb.useGravity;
this.inited = true;
}
const pos = rb.position;
rb.position = new APJS.Vector2f(
pos.x + this.velocity.x * deltaTime,
pos.y + this.velocity.y * deltaTime
);
}
onDestroy(): void {
if (this.collisionCallback && this.collider) {
const emitter = APJS.EventManager.getObjectEmitter(this.collider);
emitter.off(APJS.CollisionEvent2D.Enter, this.collisionCallback, this);
}
APJS.EventManager.getGlobalEmitter().off(APJS.EventType.RecordStart, this.onRecordStart);
}
}