Collision Events
When shapes touch, code runs
Physics collisions fire the collide event on both participating nodes. Write handler code to respond — destroy enemies, add score, trigger animations.
The collide event
When two physics bodies collide, each node receives a collide event with this data:
| Property | Type | Description |
|---|---|---|
event.target | VNode | The other node in the collision |
event.targetId | string | Name of the other node |
event.collider | string | Name of this node's collider that collided |
event.targetCollider | string | Name of the other node's collider |
event.normal | {x, y} | Contact surface normal vector |
event.point | {x, y} | Contact point in world coordinates |
Basic collision handler
// On the Ball node — destroy bricks on contact
if (event.target.is("brick")) {
event.target.destroy()
}The is() method checks both type and tag. event.target.is("brick") returns true if the target node is tagged "brick".
Multi-collider collisions
With multiple colliders per node, you can distinguish which part collided:
// Character collide handler
if (event.collider === "feet" && event.target.is("ground")) {
// landed — can jump again
this.canJump = true
}
if (event.collider === "body" && event.target.is("enemy")) {
// hit by enemy — take damage
this.health -= 1
}Collision bypass
Sometimes you need two nodes to ignore each other:
// In an event handler
this.disableCollisions(event.target)
// Later, re-enable
this.enableCollisions(event.target)The disabledNodes set tracks bypass pairs. The pre-solve callback calls contact.setEnabled(false) for disabled pairs.
Destroyed node cleanup
When a node is destroyed during play (this.destroy()), the physics system automatically removes it from the simulation. The physicsStep function checks for destroyed nodes and disables their collisions.
title: "Brick breaker"
description: "Ball bounces off a platform and destroys bricks"
nodes:
- type: RECT, name: "Platform", x: 200, y: 380, w: 120, h: 15, fill: "#2C3E50"
- type: ELLIPSE, name: "Ball", x: 200, y: 300, w: 20, h: 20, fill: "#E74C3C"
- type: RECT, name: "Brick1", x: 120, y: 100, w: 60, h: 20, fill: "#3498DB", tags: ["brick"]
- type: RECT, name: "Brick2", x: 200, y: 100, w: 60, h: 20, fill: "#3498DB", tags: ["brick"]
- type: RECT, name: "Brick3", x: 280, y: 100, w: 60, h: 20, fill: "#3498DB", tags: ["brick"]
modules:
- node: "Platform", module: "physics", config: { bodyType: "static" }
- node: "Ball", module: "physics", config: { bodyType: "dynamic", restitution: 1 }
- node: "Brick1", module: "physics", config: { bodyType: "static" }
- node: "Brick2", module: "physics", config: { bodyType: "static" }
- node: "Brick3", module: "physics", config: { bodyType: "static" }
formulas:
- node: "Platform", prop: "x", value: "mouse.x"
events:
- node: "Ball", event: "collide", code: "if (event.target.is('brick')) { event.target.destroy() }"
tools_visible: [select, play]
ui_visible: [properties, formulas]Contact normal and point
The event.normal vector points from the colliding surface outward. Use it for:
- Reflecting projectiles
- Spawning particles at the contact point
- Applying forces in the collision direction
// Bounce effect — apply impulse along contact normal
this.applyImpulse(event.normal.x * 50, event.normal.y * 50)The event.point gives the exact world-space position where contact occurred — useful for spawning visual effects.