Skip to main content

Collider2D

Base class for 2D collision shapes.

TypeNameInterface Description
VariablesemitCollisionEvent: boolean

Function: Gets or sets whether this collider should emit scripted 2D collision callbacks. When enabled, the native 2D listener buffers hit data and APJS emits , , and during update. Disabling it clears the buffered events.

VariablesisTangible: boolean

Function: Gets or sets whether this 2D collider is tangible. When true, the collider participates in normal collision response. When false, it behaves like a trigger: objects can pass through it, but contacts can still be reported through .

Variablesoffset: Vector2f

Function: Gets or sets the collider shape offset authored in the collider object's local 2D space.

VariablesphysicsMaterial: PhysicsMaterial | null

Function: Gets or sets the physics material used by this collider. The assigned material provides dynamic friction, static friction, and bounciness values for contact response.

Functionsconstructor()

Examples

constructor()

let obj = new APJS.Collider2D();

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 — Tap to drop a ball/coin that bounces multiple times on a static floor — full Physics Matter resource flow (DSL: add_builtin_resource → set_resource_properties →…

@component()
export class TapToDropBouncy extends APJS.BasicScriptComponent {
private rb: APJS.RigidBody2D | null = null;
private collider: APJS.CircleCollider2D | null = null;
private touchCallback: ((event: APJS.IEvent) => void) | null = null;
private collisionCallback: ((event: APJS.IEvent) => void) | null = null;
private dropped = false;
private bounceCount = 0;

onStart(): void {
const obj = this.getSceneObject();
this.rb = obj.getComponent("RigidBody2D") as APJS.RigidBody2D;
this.collider = obj.getComponent("CircleCollider2D") as APJS.CircleCollider2D;
if (!this.rb || !this.collider) return;

// emitCollisionEvent is APJS-runtime-only — must set in onStart, not in DSL.
this.collider.emitCollisionEvent = true;

this.touchCallback = (event: APJS.IEvent) => {
const touch = event.args[0] as APJS.TouchData;
if (touch.phase === APJS.TouchPhase.Began && !this.dropped && this.rb) {
this.dropped = true;
this.rb.static = false; // gravity now applies
}
};
APJS.EventManager.getGlobalEmitter().on(APJS.EventType.Touch, this.touchCallback);

this.collisionCallback = (event: APJS.IEvent) => {
this.bounceCount++;
// Optional: stop tracking after 5 bounces, or play SFX, or update score, etc.
if (this.bounceCount === 1) console.log("[Bouncy] first impact");
};
const emitter = APJS.EventManager.getObjectEmitter(this.collider);
emitter.on(APJS.CollisionEvent2D.Enter, this.collisionCallback, this);
}

onDestroy(): void {
if (this.touchCallback) {
APJS.EventManager.getGlobalEmitter().off(APJS.EventType.Touch, this.touchCallback);
}
if (this.collisionCallback && this.collider) {
APJS.EventManager.getObjectEmitter(this.collider).off(APJS.CollisionEvent2D.Enter, this.collisionCallback, this);
}
}
}
Copyright © 2026 TikTok. All rights reserved.
About TikTokHelp CenterCareersContactLegalTerms of ServicePrivacy PolicyCookies