The engine includes a lightweight and efficient 2D global physics system designed to handle gravity, movement, collisions, and ground detection. This system runs automatically every frame, affecting all objects that require it.
vx → Horizontal velocity (pixels/second).vy → Vertical velocity (pixels/second).gravity → Vertical acceleration applied every frame.onGround → Indicates whether the object is touching a solid surface.static → If true, the object does not move or respond to forces.
Gravity is applied cumulatively on the Y axis.
If an object has gravity = 800, its vertical velocity increases
by 800 pixels/second every second (free fall).
// Example: manually applying gravity
if (obj.gravity) {
obj.vy += obj.gravity * dt;
obj.y += obj.vy * dt;
}
static = true or trigger = true
are not affected by gravity.active = true).
Movement is calculated from velocity and delta time:
obj.x += obj.vx * dt;
obj.y += obj.vy * dt;
The collision system automatically corrects the object's position if a collision is detected, preventing overlaps or infinite falling.
Each object maintains a boolean property onGround that indicates
whether it is standing on a solid surface.
This value updates automatically after collision resolution.
if (obj.onGround) {
// The object is touching the ground
obj.vy = 0;
}
onGround = true and gravity > 0,
the engine prevents vertical speed from accumulating downward.
// Script: move_left_right.js
let speed = 200;
function Update(obj, dt) {
if (keys["ArrowLeft"]) obj.vx = -speed;
else if (keys["ArrowRight"]) obj.vx = speed;
else obj.vx = 0;
}
// Script: jump_player.js
let jumpForce = 400;
function Update(obj, dt) {
if (obj.onGround && keys["Space"]) {
obj.vy = -jumpForce;
obj.onGround = false;
}
}
// Script: projectile.js
function Start(obj) {
obj.vx = 600; // horizontal velocity
obj.vy = -200; // slight upward angle
obj.gravity = 900;
}
onGround).static = true for floors, walls, and fixed platforms.onGround = true and vy = 0.vy directly.vx and vy every frame.onGround state.