boomka
Debug
Kaboom v3000.0 beta released! Checkout this article for more info. View v3000 doc / examples here.
Kaboom is a Javascript game programming library that helps you make games fast and fun.
// start the game
kaboom()

// load a default sprite
loadBean()

// add character to screen, from a list of components
const player = add([
    sprite("bean"),  // renders as a sprite
    pos(120, 80),    // position in world
    area(),          // has a collider
    body(),          // responds to physics and gravity
])

// jump when player presses "space" key
onKeyPress("space", () => {
    // .jump() is provided by the body() component
    player.jump()
})

Play with it yourself or check out the examples in the Playground!

Start
kaboom(options?: KaboomOpt)
Initialize kaboom context. The starting point of all kaboom games.
// Start kaboom with default options (will create a fullscreen canvas under <body>)
kaboom()

// Init with some options (check out #KaboomOpt for full options list)
kaboom({
    width: 320,
    height: 240,
    font: "sinko",
    canvas: document.querySelector("#mycanvas"),
    background: [ 0, 0, 255, ],
})

// All kaboom functions are imported to global after calling kaboom()
add()
onUpdate()
onKeyPress()
vec2()

// If you want to prevent kaboom from importing all functions to global and use a context handle for all kaboom functions
const k = kaboom({ global: false })

k.add(...)
k.onUpdate(...)
k.onKeyPress(...)
k.vec2(...)
Game Obj

Game Object is the basic unit of entity in a kaboom world. Everything is a game object, the player, a butterfly, a tree, or even a piece of text.

This section contains functions to add, remove, and access game objects. To actually make them do stuff, check out the Components section.

add(comps: CompList<T>) => GameObj<T>
Assemble a game object from a list of components, and add it to the game
returns
The added game object that contains all properties and methods each component offers.
const player = add([
    // List of components, each offers a set of functionalities
    sprite("mark"),
    pos(100, 200),
    area(),
    body(),
    health(8),
    doubleJump(),
    // Plain strings are tags, a quicker way to let us define behaviors for a group
    "player",
    "friendly",
    // Components are just plain objects, you can pass an object literal as a component.
    {
        dir: LEFT,
        dead: false,
        speed: 240,
    },
])

// .jump is provided by body()
player.jump()

// .moveTo is provided by pos()
player.moveTo(300, 200)

// .onUpdate() is on every game object, it registers an event that runs every frame
player.onUpdate(() => {
    // .move() is provided by pos()
    player.move(player.dir.scale(player.speed))
})

// .onCollide is provided by area()
player.onCollide("tree", () => {
    destroy(player)
})
get(tag?: Tag | Tag[]) => GameObj[]
Get a list of all game objs with certain tag.
// get a list of all game objs with tag "bomb"
const allBombs = get("bomb")

// without args returns all current objs in the game
const allObjs = get()
every(tag: Tag | Tag[], action: (obj: GameObj) => T)
Run callback on every game obj with certain tag.
// Destroy all game obj with tag "fruit"
every("fruit", destroy)
every(action: (obj: GameObj) => T)
Run callback on every game obj.
every((obj) => {})
revery(tag: Tag | Tag[], action: (obj: GameObj) => T)
Run callback on every game obj with certain tag in reverse order.
revery(action: (obj: GameObj) => T)
Run callback on every game obj in reverse order.
readd(obj: GameObj) => GameObj
Remove and re-add the game obj.
// mainly useful when you want to make something to draw on top
readd(froggy)
destroy(obj: GameObj)
Remove the game obj.
// every time froggy collides with anything with tag "fruit", remove it
froggy.onCollide("fruit", (fruit) => {
    destroy(fruit)
})
destroyAll(tag: Tag)
Remove all game objs with certain tag.
// destroy all objects with tag "bomb" when you click one
onClick("bomb", () => {
    destroyAll("bomb")
})
Components

Kaboom uses a flexible component system which values composition over inheritence. Each game object is composed from a list of components, each component gives the game object certain capabilities.

Use add() to assemble the components together into a Game Object and add them to the world.

const player = add([
    sprite("froggy"),
    pos(100, 200),
    area(),
    body(),
])

// .jump() is provided by body() component
player.jump()

// .moveTo() is provided by pos() component
player.moveTo(120, 80)

// .onCollide() is provided by the area() component
player.onCollide("enemy", (enemy) => {
    destroy(enemy)
    addExplosion()
})

To see what methods and properties a component offers, click on the type that the component function returns, e.g. PosComp, which will open a panel showing all the properties and methods it'd give the game object.

To learn more about how components work or how to make your own component, check out the component demo.

pos(x: number, y: number) => PosComp
Position
// This game object will draw a "froggy" sprite at (100, 200)
add([
    pos(100, 200),
    sprite("froggy"),
])
pos(xy: number) => PosComp
pos(p: Vec2) => PosComp
pos() => PosComp
scale(x: number, y: number) => ScaleComp
Scale.
scale(xy: number) => ScaleComp
scale(s: Vec2) => ScaleComp
scale() => ScaleComp
rotate(a: number) => RotateComp
Rotation (in degrees). (This doesn't work with the area() collider yet)
color(r: number, g: number, b: number) => ColorComp
Sets color (rgb 0-255).
// blue frog
add([
    sprite("froggy"),
    color(0, 0, 255)
])
color(c: Color) => ColorComp
color() => ColorComp
opacity(o?: number) => OpacityComp
Sets opacity (0.0 - 1.0).
sprite(spr: string | SpriteData, options?: SpriteCompOpt) => SpriteComp
Render as a sprite.
// minimal setup
add([
    sprite("froggy"),
])

// with options
const froggy = add([
    sprite("froggy", {
        // start with animation "idle"
        anim: "idle",
    }),
])

// play / stop an anim
froggy.play("jump")
froggy.stop()

// manually setting a frame
froggy.frame = 3
text(txt: string, options?: TextCompOpt) => TextComp
Render as text.
// a simple score counter
const score = add([
    text("Score: 0"),
    pos(24, 24),
    { value: 0 },
])

player.onCollide("coin", () => {
    score.value += 1
    score.text = "Score:" + score.value
})

// with options
add([
    pos(24, 24),
    text("ohhi", {
        size: 48, // 48 pixels tall
        width: 320, // it'll wrap to next line when width exceeds this value
        font: "sink", // there're 4 built-in fonts: "apl386", "apl386o", "sink", and "sinko"
    }),
])
rect(w: number, h: number) => RectComp
Render as a rectangle.
// i don't know, could be an obstacle or something
add([
    pos(80, 120),
    rect(20, 40),
    outline(4),
    area(),
])
circle(radius: number) => CircleComp
Render as a circle.
add([
    pos(80, 120),
    circle(16),
])
uvquad(w: number, h: number) => UVQuadComp
Render as a UV quad.
add([
    uvquad(width(), height()),
    shader("spiral"),
])
area() => AreaComp
Generates collider area from shape and enables collision detection.
// Automatically generate area information from the shape of render
const player = add([
    sprite("froggy"),
    area(),
])

// Die if player collides with another game obj with tag "tree"
player.onCollide("tree", () => {
    destroy(player)
    go("lose")
})

// Check for collision manually every frame instead of registering an event
player.onUpdate(() => {
    if (player.isColliding(bomb)) {
        score += 1
    }
})
area(options: AreaCompOpt) => AreaComp
Define collider area and enables collision detection.
add([
    sprite("flower"),
    // Scale to 0.6 of the generated area
    area({ scale: 0.6 }),
    // If we want the area scale to be calculated from the center
    origin("center"),
])

add([
    sprite("froggy"),
    // Define custom area with width and height
    area({ width: 20, height: 40. }),
])
origin(o: Origin | Vec2) => OriginComp
Origin point for render (default "topleft").
// set origin to "center" so it'll rotate from center
add([
    rect(40, 10),
    rotate(45),
    origin("center"),
])
layer(l: string) => LayerComp
Which layer this object belongs to.
z(z: number) => ZComp
Determines the draw order for objects on the same layer. Object will be drawn on top if z value is bigger.
outline(width?: number, color?: Color) => OutlineComp
Give obj an outline.
body(options?: BodyCompOpt) => BodyComp
Physical body that responds to gravity. Requires "area" and "pos" comp. This also makes the object "solid".
// froggy jumpy
const froggy = add([
    sprite("froggy"),
    // body() requires "pos" and "area" component
    pos(),
    area(),
    body(),
])

// when froggy is grounded, press space to jump
// check out #BodyComp for more methods
onKeyPress("space", () => {
    if (froggy.isGrounded()) {
        froggy.jump()
    }
})

// run something when froggy falls and hits a ground
froggy.onGround(() => {
    debug.log("oh no!")
})
solid() => SolidComp
Make other objects cannot move pass. Requires "area" comp.
add([
    sprite("rock"),
    pos(30, 120),
    area(),
    solid(),
])

// only do collision checking when a block is close to player for performance
onUpdate("block", (b) => {
    b.solid = b.pos.dist(player.pos) <= 64
})
move(direction: number | Vec2, speed: number) => MoveComp
Move towards a direction infinitely, and destroys when it leaves game view. Requires "pos" comp.
// enemy throwing feces at player
const projectile = add([
    sprite("feces"),
    pos(enemy.pos),
    area(),
    move(player.pos.angle(enemy.pos), 1200),
    cleanup(),
])
outview(opt?: OutviewCompOpt) => OutviewComp
Control the behavior of object when it goes out of view.
since
v2000.2
add([
    pos(1200, 80),
    outview({ hide: true, pause: true }),
])
cleanup(opt?: CleanupCompOpt) => CleanupComp
destroy() the object if it goes out of screen. Optionally specify the amount of time it has to be off-screen before removal.
// destroy when it leaves screen
const bullet = add([
    pos(80, 80),
    move(LEFT, 960),
    cleanup(),
])
cleanup(delay?: number) => CleanupComp
deprecated
v2000.2 Use cleanup() with optional CleanupCompOpt instead of single time argument.
follow(obj: GameObj | null, offset?: Vec2) => FollowComp
Follow another game obj's position.
shader(id: string) => ShaderComp
Custom shader.
timer(n?: number, action?: () => void) => TimerComp
Run certain action after some time.
fixed() => FixedComp
Make object unaffected by camera or parent object transforms, and render at last.
// this will be be fixed on top left and not affected by camera
const score = add([
    text(0),
    pos(12, 12),
    fixed(),
])
stay() => StayComp
Don't get destroyed on scene switch.
player.onCollide("bomb", () => {
    // spawn an explosion and switch scene, but don't destroy the explosion game obj on scene switch
    add([
        sprite("explosion", { anim: "burst", }),
        stay(),
        lifespan(1),
    ])
    go("lose", score)
})
health(hp: number) => HealthComp
Handles health related logic and events.
const player = add([
    health(3),
])

player.onCollide("bad", (bad) => {
    player.hurt(1)
    bad.hurt(1)
})
 
player.onCollide("apple", () => {
    player.heal(1)
})

player.on("hurt", () => {
    play("ouch")
})

// triggers when hp reaches 0
player.on("death", () => {
    destroy(player)
    go("lose")
})
lifespan(time: number, options?: LifespanCompOpt) => LifespanComp
Destroy the game obj after certain amount of time
// spawn an explosion, destroy after 1 seconds, start fading away after 0.5 second
add([
    sprite("explosion", { anim: "burst", }),
    lifespan(1, { fade: 0.5 }),
])
state(initialState: string, stateList?: string[]) => StateComp
Finite state machine.
since
v2000.1
const enemy = add([
    pos(80, 100),
    sprite("robot"),
    state("idle", ["idle", "attack", "move"]),
])

// this callback will run once when enters "attack" state
enemy.onStateEnter("attack", () => {
    // enter "idle" state when the attack animation ends
    enemy.play("attackAnim", {
        // any additional arguments will be passed into the onStateEnter() callback
        onEnd: () => enemy.enterState("idle", rand(1, 3)),
    })
    checkHit(enemy, player)
})

// this will run once when enters "idle" state
enemy.onStateEnter("idle", (time) => {
    enemy.play("idleAnim")
    wait(time, () => enemy.enterState("move"))
})

// this will run every frame when current state is "move"
enemy.onStateUpdate("move", () => {
    enemy.follow(player)
    if (enemy.pos.dist(player.pos) < 16) {
        enemy.enterState("attack")
    }
})
state(initialState: string, stateList: string[], transitions: Record<string, string | string[]>) => StateComp
state() with pre-defined transitions.
since
v2000.2
const enemy = add([
    pos(80, 100),
    sprite("robot"),
    state("idle", ["idle", "attack", "move"], {
        "idle": "attack",
        "attack": "move",
        "move": [ "idle", "attack" ],
    }),
])

// this callback will only run once when enter "attack" state from "idle"
enemy.onStateTransition("idle", "attack", () => {
    checkHit(enemy, player)
})
Events

Kaboom uses events extensively for a flat and declarative code style.

For example, it's most common for a game to have something run every frame which can be achieved by adding an onUpdate() event

// Make something always move to the right
onUpdate(() => {
    banana.move(320, 0)
})

Events are also used for input handlers.

onKeyPress("space", () => {
    player.jump()
})

Every function with the on prefix is an event register function that takes a callback function as the last argument, and should return a function that cancels the event listener.

Note that you should never nest one event handler function inside another or it might cause severe performance punishment.

on(event: string, tag: Tag, action: (obj: GameObj, args: ...) => void) => EventCanceller
Register an event on all game objs with certain tag.
// a custom event defined by body() comp
// every time an obj with tag "bomb" hits the floor, destroy it and addKaboom()
on("ground", "bomb", (bomb) => {
    destroy(bomb)
    addKaboom()
})
onUpdate(tag: Tag, action: (obj: GameObj) => void) => EventCanceller
Register an event that runs every frame (~60 times per second) for all game objs with certain tag.
since
v2000.1
// move every "tree" 120 pixels per second to the left, destroy it when it leaves screen
// there'll be nothing to run if there's no "tree" obj in the scene
onUpdate("tree", (tree) => {
    tree.move(-120, 0)
    if (tree.pos.x < 0) {
        destroy(tree)
    }
})
onUpdate(action: () => void) => EventCanceller
Register an event that runs every frame (~60 times per second).
since
v2000.1
// This will run every frame
onUpdate(() => {
    debug.log("ohhi")
})
onDraw(tag: Tag, action: (obj: GameObj) => void) => EventCanceller
Register an event that runs every frame (~60 times per second) for all game objs with certain tag (this is the same as onUpdate but all draw events are run after update events, drawXXX() functions only work in this phase).
since
v2000.1
onDraw(action: () => void) => EventCanceller
Register an event that runs every frame (~60 times per second) (this is the same as onUpdate but all draw events are run after update events, drawXXX() functions only work in this phase).
since
v2000.1
onDraw(() => {
    drawLine({
        p1: vec2(0),
        p2: mousePos(),
        color: rgb(0, 0, 255),
    })
})
onLoad(action: () => void)
Register an event that runs when all assets finished loading.
since
v2000.1
const froggy = add([
    sprite("froggy"),
])

// certain assets related data are only available when the game finishes loading
onLoad(() => {
    debug.log(froggy.width)
})
onCollide(t1: Tag, t2: Tag, action: (a: GameObj, b: GameObj, col?: Collision) => void) => EventCanceller
Register an event that runs when 2 game objs with certain tags collides (required to have area() component).
since
v2000.1
onCollide("sun", "earth", () => {
    addExplosion()
})
onClick(tag: Tag, action: (a: GameObj) => void) => EventCanceller
Register an event that runs when game objs with certain tags are clicked (required to have the area() component).
since
v2000.1
// click on any "chest" to open
onClick("chest", (chest) => chest.open())
onClick(action: () => void) => EventCanceller
Register an event that runs when users clicks.
since
v2000.1
// click on anywhere to go to "game" scene
onClick(() => go("game"))
onHover(tag: Tag, action: (a: GameObj) => void) => EventCanceller
Register an event that runs when game objs with certain tags are hovered (required to have area() component).
since
v2000.1
onKeyDown(k: Key | Key[], action: () => void) => EventCanceller
Register an event that runs every frame when a key is held down.
since
v2000.1
// move left by SPEED pixels per frame every frame when left arrow key is being held down
onKeyDown("left", () => {
    froggy.move(-SPEED, 0)
})
onKeyPress(k: Key | Key[], action: () => void) => EventCanceller
Register an event that runs when user presses certain key.
since
v2000.1
// .jump() once when "space" is just being pressed
onKeyPress("space", () => {
    froggy.jump()
})
onKeyPress(action: () => void) => EventCanceller
Register an event that runs when user presses any key.
since
v2000.1
// Call restart() when player presses any key
onKeyPress(() => {
    restart()
})
onKeyPressRepeat(k: Key | Key[], action: () => void) => EventCanceller
Register an event that runs when user presses certain key (also fires repeatedly when they key is being held down).
since
v2000.1
// delete last character when "backspace" is being pressed and held
onKeyPressRepeat("backspace", () => {
    input.text = input.text.substring(0, input.text.length - 1)
})
onKeyPressRepeat(action: () => void) => EventCanceller
onKeyRelease(k: Key | Key[], action: () => void) => EventCanceller
Register an event that runs when user releases certain key.
since
v2000.1
onKeyRelease(action: () => void) => EventCanceller
onCharInput(action: (ch: string) => void) => EventCanceller
Register an event that runs when user inputs text.
since
v2000.1
// type into input
onCharInput((ch) => {
    input.text += ch
})
onMouseDown(action: (pos: Vec2) => void) => EventCanceller
Register an event that runs every frame when a mouse button is being held down.
since
v2000.1
onMouseDown(button: MouseButton, action: (pos: Vec2) => void) => EventCanceller
onMousePress(action: (pos: Vec2) => void) => EventCanceller
Register an event that runs when user clicks mouse.
since
v2000.1
onMousePress(button: MouseButton, action: (pos: Vec2) => void) => EventCanceller
onMouseRelease(action: (pos: Vec2) => void) => EventCanceller
Register an event that runs when user releases mouse.
since
v2000.1
onMouseRelease(button: MouseButton, action: (pos: Vec2) => void) => EventCanceller
onMouseMove(action: (pos: Vec2) => void) => EventCanceller
Register an event that runs whenever user move the mouse.
since
v2000.1
onTouchStart(action: (id: TouchID, pos: Vec2) => void) => EventCanceller
Register an event that runs when a touch starts.
since
v2000.1
onTouchMove(action: (id: TouchID, pos: Vec2) => void) => EventCanceller
Register an event that runs whenever touch moves.
since
v2000.1
onTouchEnd(action: (id: TouchID, pos: Vec2) => void) => EventCanceller
Register an event that runs when a touch ends.
since
v2000.1
action: KaboomCtx["onUpdate"]
deprecated
v2000.1 Use onUpdate() instead
render: KaboomCtx["onDraw"]
deprecated
v2000.1 Use onDraw() instead
ready: KaboomCtx["onLoad"]
deprecated
v2000.1 Use onLoad() instead.
collides: KaboomCtx["onCollide"]
deprecated
v2000.1 Use onCollide() instead
clicks: KaboomCtx["onClick"]
deprecated
v2000.1 Use onClick() instead
hovers: KaboomCtx["onHover"]
deprecated
v2000.1 Use onHover() instead
keyDown: KaboomCtx["onKeyDown"]
deprecated
v2000.1 Use onKeyDown() instead.
keyPress: KaboomCtx["onKeyPress"]
deprecated
v2000.1 Use onKeyPress() instead.
keyPressRep: KaboomCtx["onKeyPressRepeat"]
deprecated
v2000.1 Use onKeyPressRepeat() instead.
keyRelease: KaboomCtx["onKeyRelease"]
deprecated
v2000.1 Use onKeyRelease() instead.
charInput: KaboomCtx["onCharInput"]
deprecated
v2000.1 Use onCharInput() instead.
mouseClick: KaboomCtx["onMousePress"]
deprecated
v2000.1 Use onClick() or onMousePress() instead.
mouseRelease: KaboomCtx["onMouseRelease"]
deprecated
v2000.1 Use onMouseRelease() instead.
mouseDown: KaboomCtx["onMouseDown"]
deprecated
v2000.1 Use onMouseDown() instead.
mouseMove: KaboomCtx["onMouseMove"]
deprecated
v2000.1 Use onMouseMove() instead.
touchStart: KaboomCtx["onTouchStart"]
deprecated
v2000.1 Use onTouchStart() instead.
touchMove: KaboomCtx["onTouchMove"]
deprecated
v2000.1 Use onTouchMove() instead.
touchEnd: KaboomCtx["onTouchEnd"]
deprecated
v2000.1 Use onTouchEnd() instead.
Assets

Every function with the load prefix is an async function that loads something into the asset manager, and should return a promise that resolves upon load complete.

loadRoot(path?: string) => string
Sets the root for all subsequent resource urls.
loadRoot("https://myassets.com/")
loadSprite("froggy", "sprites/froggy.png") // will resolve to "https://myassets.com/sprites/frogg.png"
loadSprite(id: string | null, src: SpriteLoadSrc, options?: SpriteLoadOpt) => Promise<SpriteData>
Load a sprite into asset manager, with name and resource url and optional config.
// due to browser policies you'll need a static file server to load local files
loadSprite("froggy", "froggy.png")
loadSprite("apple", "https://kaboomjs.com/sprites/apple.png")

// slice a spritesheet and add anims manually
loadSprite("froggy", "froggy.png", {
    sliceX: 4,
    sliceY: 1,
    anims: {
        run: {
            from: 0,
            to: 3,
        },
        jump: {
            from: 3,
            to: 3,
        },
    },
})
loadSpriteAtlas(src: SpriteLoadSrc, data: SpriteAtlasData) => Promise<Record<string, SpriteData>>
Load sprites from a sprite atlas.
// See #SpriteAtlasData type for format spec
loadSpriteAtlas("sprites/dungeon.png", {
    "hero": {
        x: 128,
        y: 68,
        width: 144,
        height: 28,
        sliceX: 9,
        anims: {
            idle: { from: 0, to: 3 },
            run: { from: 4, to: 7 },
            hit: 8,
        },
    },
})

const player = add([
    sprite("hero"),
])

player.play("run")
loadSpriteAtlas(src: SpriteLoadSrc, url: string) => Promise<Record<string, SpriteData>>
Load sprites from a sprite atlas with URL.
// Load from json file, see #SpriteAtlasData type for format spec
loadSpriteAtlas("sprites/dungeon.png", "sprites/dungeon.json")

const player = add([
    sprite("hero"),
])

player.play("run")
loadAseprite(name: string | null, imgSrc: SpriteLoadSrc, jsonSrc: string) => Promise<SpriteData>
Load a sprite with aseprite spritesheet json.
loadAseprite("car", "sprites/car.png", "sprites/car.json")
loadPedit(name: string, src: string) => Promise<SpriteData>
loadBean(name?: string) => Promise<SpriteData>
Load default sprite "bean".
loadBean()

// use it right away
add([
    sprite("bean"),
])
loadSound(id: string, src: string) => Promise<SoundData>
Load a sound into asset manager, with name and resource url.
loadSound("shoot", "horse.ogg")
loadSound("shoot", "https://kaboomjs.com/sounds/scream6.mp3")
loadFont(id: string, src: string, gridWidth: number, gridHeight: number, options?: FontLoadOpt) => Promise<FontData>
Load a bitmap font into asset manager, with name and resource url and infomation on the layout of the bitmap.
// load a bitmap font called "04b03", with bitmap "fonts/04b03.png"
// each character on bitmap has a size of (6, 8), and contains default ASCII_CHARS
loadFont("04b03", "fonts/04b03.png", 6, 8)

// load a font with custom characters
loadFont("cp437", "cp437.png", 6, 8, {chars: "☺☻♥♦♣♠"})
loadShader(name: string, vert?: string, frag?: string, isUrl?: boolean) => Promise<ShaderData>
Load a shader into asset manager with vertex and fragment code / file url.
// load only a fragment shader from URL
loadShader("outline", null, "/shaders/outline.glsl", true)

// default shaders and custom shader format
loadShader("outline",
    `vec4 vert(vec3 pos, vec2 uv, vec4 color) {
    // predefined functions to get the default value by kaboom
    return def_vert()
}`,
`vec4 frag(vec3 pos, vec2 uv, vec4 color, sampler2D tex) {
    // turn everything blue-ish
    return def_frag() * vec4(0, 0, 1, 1)
}`, false)
load(l: Promise<T>)
Add a new loader to wait for before starting the game.
load(new Promise((resolve, reject) => {
    // anything you want to do that stalls the game in loading state
    resolve("ok")
}))
Info
width() => number
Get the width of game.
height() => number
Get the height of game.
center() => Vec2
Get the center point of view.
// add froggy to the center of the screen
add([
    sprite("froggy"),
    pos(center()),
    // ...
])
dt() => number
Get the delta time since last frame.
// rotate froggy 100 deg per second
froggy.onUpdate(() => {
    froggy.angle += 100 * dt()
})
time() => number
Get the total time since beginning.
isFocused() => boolean
If the game canvas is currently focused.
since
v2000.1
Focus on the game canvas.
deprecated
v2000.2
isTouch() => boolean
Is currently on a touch screen device.
mousePos() => Vec2
Get current mouse position (without camera transform).
mouseWorldPos() => Vec2
Get current mouse position (after camera transform).
deprecated
v2000.2 Use toWorld(mousePos()) instead.
mouseDeltaPos() => Vec2
How much mouse moved last frame.
isKeyDown(k: Key) => boolean
If certain key is currently down.
since
v2000.1
// equivalent to the calling froggy.move() in an onKeyDown("left")
onUpdate(() => {
    if (isKeyDown("left")) {
        froggy.move(-SPEED, 0)
    }
})
isKeyPressed(k?: Key) => boolean
If certain key is just pressed last frame.
since
v2000.1
isKeyPressedRepeat(k?: Key) => boolean
If certain key is just pressed last frame (also fires repeatedly when the key is being held down).
since
v2000.1
isKeyReleased(k?: Key) => boolean
If certain key is just released last frame.
since
v2000.1
isMouseDown(button?: MouseButton) => boolean
If a mouse button is currently down.
since
v2000.1
isMousePressed(button?: MouseButton) => boolean
If a mouse button is just clicked last frame.
since
v2000.1
isMouseReleased(button?: MouseButton) => boolean
If a mouse button is just released last frame.
since
v2000.1
isMouseMoved() => boolean
If mouse moved last frame.
since
v2000.1
shake(intensity: number)
Camera shake.
// shake intensively when froggy collides with a "bomb"
froggy.onCollide("bomb", () => {
    shake(120)
})
camPos(pos?: Vec2) => Vec2
Get / set camera position.
// camera follows player
player.onUpdate(() => {
    camPos(player.pos)
})
camScale(scale?: Vec2) => Vec2
Get / set camera scale.
camRot(angle?: number) => number
Get / set camera rotation.
toScreen(p: Vec2) => Vec2
Transform a point from world position to screen position.
toWorld(p: Vec2) => Vec2
Transform a point from screen position to world position.
gravity(g: number) => number
Get / set gravity.
layers(list: string[], def?: string)
Define layers (the last one will be on top).
// defining 3 layers, "ui" will be drawn on top most, with default layer being "game"
layers([
    "bg",
    "game",
    "ui",
], "game")

// use layer() comp to define which layer an obj belongs to
add([
    text(score),
    layer("ui"),
    fixed(),
])

// without layer() comp it'll fall back to default layer, which is "game"
add([
    sprite("froggy"),
])
cursor(c?: Cursor) => Cursor
Get / set the cursor (css). Cursor will be reset to "default" every frame so use this in an per-frame action.
onHover("clickable", (c) => {
    cursor("pointer")
})
regCursor(c: string, draw: string | ((mpos: Vec2) => void))
Load a cursor from a sprite, or custom drawing function.
loadSprite("froggy", "sprites/froggy.png")

// use sprite as cursor
regCursor("default", "froggy")
regCursor("pointer", "apple")
fullscreen(f?: boolean)
Enter / exit fullscreen mode. (note: mouse position is not working in fullscreen mode at the moment)
// toggle fullscreen mode on "f"
onKeyPress("f", (c) => {
    fullscreen(!isFullscreen())
})
isFullscreen() => boolean
If currently in fullscreen mode.
keyIsDown: KaboomCtx["isKeyDown"]
deprecated
v2000.1 Use isKeyDown() instead.
keyIsPressed: KaboomCtx["isKeyPressed"]
deprecated
v2000.1 Use isKeyPressed() instead.
keyIsPressedRep: KaboomCtx["isKeyPressedRepeat"]
deprecated
v2000.1 Use isKeyPressedRepeat() instead.
keyIsReleased: KaboomCtx["isKeyReleased"]
deprecated
v2000.1 Use isKeyReleased() instead.
mouseIsDown: KaboomCtx["isMouseDown"]
deprecated
v2000.1 Use isMouseDown() instead.
mouseIsClicked: KaboomCtx["isMouseClicked"]
deprecated
v2000.1 Use isMouseClicked() instead.
mouseIsReleased: KaboomCtx["isMouseReleased"]
deprecated
v2000.1 Use isMouseReleased() instead.
mouseIsMoved: KaboomCtx["isMouseMoved"]
deprecated
v2000.1 Use isMouseMoved() instead.
focused() => boolean
deprecated
v2000.1 Use isFocused() instead.
Timer
wait(n: number, action?: () => void) => Promise<void>
Run the callback after n seconds.
// 3 seconds until explosion! Runnn!
wait(3, () => {
    explode()
})
loop(t: number, action: () => void) => EventCanceller
Run the callback every n seconds.
// spawn a butterfly at random position every 1 second
loop(1, () => {
    add([
        sprite("butterfly"),
        pos(rand(vec2(width(), height()))),
        area(),
        "friend",
    ])
})
Audio
play(id: string, options?: AudioPlayOpt) => AudioPlay
Play a piece of audio.
returns
A control handle.
// play a one off sound
play("wooosh")

// play a looping soundtrack (check out AudioPlayOpt for more options)
const music = play("OverworldlyFoe", {
    volume: 0.8,
    loop: true
})

// using the handle to control (check out AudioPlay for more controls / info)
music.pause()
music.play()
burp(options?: AudioPlayOpt) => AudioPlay
Yep.
volume(v?: number) => number
Sets global volume.
// makes everything quieter
volume(0.5)
audioCtx: AudioContext
Get the underlying browser AudioContext.
Math
rand() => number
Get a random number between 0 - 1.
rand(n: T) => T
Get a random value between 0 and the given value.
// a random number between 0 - 8
rand(8)

// a random point on screen
rand(vec2(width(), height()))

// a random color
rand(rgb(255, 255, 255))
rand(a: T, b: T) => T
Get a random value between the given bound.
rand(50, 100)
rand(vec2(20), vec2(100))

// spawn something on the right side of the screen but with random y value within screen height
add([
    pos(width(), rand(0, height())),
])
randi() => number
rand() but floored to integer.
randi(0, 3) // will give either 0, 1, or 2
randSeed(seed?: number) => number
Get / set the random number generator seed.
randSeed(Date.now())
vec2(x: number, y: number) => Vec2
Create a 2d vector.
// { x: 0, y: 0 }
vec2()

// { x: 10, y: 10 }
vec2(10)

// { x: 100, y: 80 }
vec2(100, 80)

// move to 150 degrees direction with by length 10
player.pos = pos.add(Vec2.fromAngle(150).scale(10))
vec2(p: Vec2) => Vec2
vec2(xy: number) => Vec2
vec2() => Vec2
rgb(r: number, g: number, b: number) => Color
RGB color (0 - 255).
// update the color of the sky to light blue
sky.color = rgb(0, 128, 255)
hsl2rgb(hue: number, saturation: number, lightness: number) => Color
Convert HSL color (all values in 0.0 - 1.0 range) to RGB color.
since
v2000.1
// animate rainbow color
onUpdate("rainbow", (obj) => {
    obj.color = hsl2rgb(wave(0, 1, time()), 0.6, 0.6)
})
quad(x: number, y: number, w: number, h: number) => Quad
Rectangle area (0.0 - 1.0).
choose(lst: T[]) => T
Choose a random item from a list.
// decide the best fruit randomly
const bestFruit = choose(["apple", "banana", "pear", "watermelon"])
chance(p: number) => boolean
rand(1) <= p
// every frame all objs with tag "unlucky" have 50% chance die
onUpdate("unlucky", (o) => {
    if (chance(0.5)) {
        destroy(o)
    }
})
lerp(from: number, to: number, t: number) => number
Linear interpolation.
map(v: number, l1: number, h1: number, l2: number, h2: number) => number
Map a value from one range to another range.
mapc(v: number, l1: number, h1: number, l2: number, h2: number) => number
Map a value from one range to another range, and clamp to the dest range.
dir(deg: number) => Vec2
deprecated
v2000.2 Use Vec2.fromAngle instead.
wave(lo: number, hi: number, t: number, func?: (x: number) => number) => number
Interpolate between 2 values (Optionally takes a custom periodic function, which default to Math.sin).
// bounce color between 2 values as time goes on
onUpdate("colorful", (c) => {
    c.color.r = wave(0, 255, time())
    c.color.g = wave(0, 255, time() + 1)
    c.color.b = wave(0, 255, time() + 2)
})
deg2rad(deg: number) => number
Convert degrees to radians.
rad2deg(rad: number) => number
Convert radians to degrees.
rng(seed: number) => RNG
Make a new random number generator.
testLineLine(l1: Line, l2: Line) => Vec2 | null
Check if 2 lines intersects, if yes returns the intersection point.
testRectRect(r1: Rect, r2: Rect) => boolean
Check if 2 rectangle overlaps.
testRectLine(r: Rect, l: Line) => boolean
Check if a line and a rectangle overlaps.
testRectPoint(r: Rect, pt: Vec2) => boolean
Check if a point is inside a rectangle.
Scene
scene(id: SceneID, def: SceneDef)
Define a scene.
go(id: SceneID, args: ...)
Go to a scene, passing all rest args to scene callback.
Level
addLevel(map: string[], options: LevelOpt) => Level
Construct a level based on symbols.
addLevel([
    "                          $",
    "                          $",
    "           $$         =   $",
    "  %      ====         =   $",
    "                      =    ",
    "       ^^      = >    =   &",
    "===========================",
], {
    // define the size of each block
    width: 32,
    height: 32,
    // define what each symbol means, by a function returning a component list (what will be passed to add())
    "=": () => [
        sprite("floor"),
        area(),
        solid(),
    ],
    "$": () => [
        sprite("coin"),
        area(),
        pos(0, -9),
    ],
    "^": () => [
        sprite("spike"),
        area(),
        "danger",
    ],
})
Data
getData(key: string, def?: T) => T
Get data from local storage, if not present can set to a default value.
setData(key: string, data: any)
Set data from local storage.
Draw

Kaboom exposes all of the drawing interfaces it uses in the render components like sprite(), and you can use these drawing functions to build your own richer render components.

Also note that you have to put drawXXX() functions inside an onDraw() event or the draw() hook in component definitions which runs every frame (after the update events), or it'll be immediately cleared next frame and won't persist.

onDraw(() => {

    drawSprite({
        sprite: "froggy",
        pos: vec2(120, 160),
        angle: 90,
    })

    drawLine({
        p1: vec2(0),
        p2: mousePos(),
        width: 4,
        color: rgb(0, 0, 255),
    })

})

There's also the option to use Kaboom purely as a rendering library. Check out the draw demo.

drawSprite(options: DrawSpriteOpt)
Draw a sprite.
drawSprite({
    sprite: "froggy",
    pos: vec2(100, 200),
    frame: 3,
})
drawText(options: DrawTextOpt)
Draw a piece of text.
drawText({
    text: "oh hi",
    size: 48,
    font: "sink",
    width: 120,
    pos: vec2(100, 200),
    color: rgb(0, 0, 255),
})
drawRect(options: DrawRectOpt)
Draw a rectangle.
drawRect({
    width: 120,
    height: 240,
    pos: vec2(20, 20),
    color: YELLOW,
    outline: { color: BLACK, width: 4 },
})
drawLine(options: DrawLineOpt)
Draw a line.
drawLine({
    p1: vec2(0),
    p2: mousePos(),
    width: 4,
    color: rgb(0, 0, 255),
})
drawLines(options: DrawLinesOpt)
Draw lines.
drawLines({
    pts: [ vec2(0), vec2(0, height()), mousePos() ],
    width: 4,
    pos: vec2(100, 200),
    color: rgb(0, 0, 255),
})
drawTriangle(options: DrawTriangleOpt)
Draw a triangle.
drawTriangle({
    p1: vec2(0),
    p2: vec2(0, height()),
    p3: mousePos(),
    pos: vec2(100, 200),
    color: rgb(0, 0, 255),
})
drawCircle(options: DrawCircleOpt)
Draw a circle.
drawCircle({
    pos: vec2(100, 200),
    radius: 120,
    color: rgb(255, 255, 0),
})
drawEllipse(options: DrawEllipseOpt)
Draw an ellipse.
drawEllipse({
    pos: vec2(100, 200),
    radiusX: 120,
    radiusY: 120,
    color: rgb(255, 255, 0),
})
drawPolygon(options: DrawPolygonOpt)
Draw a convex polygon from a list of vertices.
drawPolygon({
    pts: [
        vec2(-12),
        vec2(0, 16),
        vec2(12, 4),
        vec2(0, -2),
        vec2(-8),
    ],
    pos: vec2(100, 200),
    color: rgb(0, 0, 255),
})
drawUVQuad(options: DrawUVQuadOpt)
Draw a rectangle with UV data.
drawFormattedText(text: FormattedText)
Draw a piece of formatted text from formatText().
since
v2000.2
// text background
const txt = formatText({
    text: "oh hi",
})

drawRect({
    width: txt.width,
    height: txt.height,
})

drawFormattedText(txt)
Push current transform matrix to the transform stack.
pushTransform()

// these transforms will affect every render until popTransform()
pushTranslate(120, 200)
pushRotate(time() * 120)
pushScale(6)

drawSprite("froggy")
drawCircle(vec2(0), 120)

// restore the transformation stack to when last pushed
popTransform()
Pop the topmost transform matrix from the transform stack.
pushTranslate(x: number, y: number)
Translate all subsequent draws.
pushTranslate(100, 100)

// this will be drawn at (120, 120)
drawText({
    text: "oh hi",
    pos: vec2(20, 20),
})
pushTranslate(p: Vec2)
pushScale(x: number, y: number)
Scale all subsequent draws.
pushScale(s: number)
pushScale(s: Vec2)
pushRotate(angle: number)
Rotate all subsequent draws.
formatText(options: DrawTextOpt) => FormattedText
Format a piece of text without drawing (for getting dimensions, etc).
since
v2000.2
// text background
const txt = formatText({
    text: "oh hi",
})

drawRect({
    width: txt.width,
    height: txt.height,
})

drawFormattedText(txt)
Debug

By default kaboom starts in debug mode, which enables key bindings that calls out various debug utilities:

  • f1 to toggle inspect mode
  • f5 to take screenshot
  • f6 to toggle recording
  • f7 to slow down
  • f8 to pause / resume
  • f9 to speed up
  • f10 to skip frame

Some of these can be also controlled with stuff under the debug object.

If you want to turn debug mode off when releasing you game, set debug option to false in kaboom()

debug: Debug
// pause the whole game
debug.paused = true

// enter inspect mode
debug.inspect = true
Misc
plug(plugin: KaboomPlugin<T>)
Import a plugin.
screenshot() => string
Take a screenshot and get the dataurl of the image.
returns
The dataURL of the image.
record(frameRate?: number) => Recording
Start recording the canvas into a video. If framerate is not specified, a new frame will be captured each time the canvas changes.
returns
A control handle.
since
v2000.1
ASCII_CHARS: string
All chars in ASCII.
CP437_CHARS: string
All chars in CP437.
LEFT: Vec2
Left directional vector vec2(-1, 0).
UP: Vec2
Up directional vector vec2(0, -1).
DOWN: Vec2
Down directional vector vec2(0, 1).
RED: Color
GREEN: Color
BLUE: Color
YELLOW: Color
MAGENTA: Color
CYAN: Color
WHITE: Color
BLACK: Color
canvas: HTMLCanvasElement
The canvas DOM kaboom is currently using.
type
Tag
string
type
Expand
Expand<UnionToIntersection<Defined<T>>>
Omit<MergeObj<T>, unknown>
Array<T | Tag>
type
Key
"f1" | "f2" | "f3" | "f4" | "f5" | "f6" | "f7" | "f8" | "f9" | "f10" | "f11" | "f12" | "`" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "0" | "-" | "=" | "q" | "w" | "e" | "r" | "t" | "y" | "u" | "i" | "o" | "p" | "[" | "]" | "\" | "a" | "s" | "d" | "f" | "g" | "h" | "j" | "k" | "l" | "" | "'" | "z" | "x" | "c" | "v" | "b" | "n" | "m" | "," | "." | "/" | "backspace" | "enter" | "tab" | "space" | " " | "left" | "right" | "up" | "down"
"left" | "right" | "middle" | "back" | "forward"
Record<Tag, string | null>
Kaboom configurations.
width?: number
Width of game.
height?: number
Height of game.
scale?: number
Pixel scale / size.
stretch?: boolean
If stretch canvas to container when width and height is specified
letterbox?: boolean
When stretching if keep aspect ratio and leave black bars on remaining spaces. (note: not working properly at the moment.)
debug?: boolean
If register debug buttons (default true)
font?: string
Default font (defaults to "apl386o", with "apl386", "sink", "sinko" as other built-in options).
crisp?: boolean
Disable antialias and enable sharp pixel display.
canvas?: HTMLCanvasElement
The canvas DOM element to use. If empty will create one.
root?: HTMLElement
The container DOM element to insert the canvas if created. Defaults to document.body.
background?: number[]
Background color. E.g. [ 0, 0, 255 ] for solid blue background.
inspectColor?: number[]
The color to draw collider boxes etc.
texFilter?: TexFilter
Default texture filter.
logMax?: number
How many log messages can there be on one screen.
touchToMouse?: boolean
If translate touch events as mouse clicks (default true).
global?: boolean
If import all kaboom functions to global (default true).
plugins?: KaboomPlugin<any>[]
List of plugins to import.
burp?: boolean
Enter burp mode.
(k: KaboomCtx) => T
Base interface of all game objects.
_id: number | null
Internal GameObj ID.
hidden: boolean
If draw the game obj (run "draw" event or not).
paused: boolean
If update the game obj (run "update" event or not).
exists() => boolean
If game obj exists in scene.
add(comps: CompList<T>) => GameObj<T>
Add a child.
since
v2000.2.0
readd(obj: GameObj) => GameObj
Remove and re-add the game obj.
since
v2000.2.0
remove(obj: GameObj)
Remove a child.
since
v2000.2.0
removeAll(tag: Tag)
Remove all children with a certain tag.
since
v2000.2.0
get(tag?: Tag | Tag[]) => GameObj[]
Get a list of all game objs with certain tag.
since
v2000.2.0
every(action: (obj: GameObj) => T)
Iterate through children.
since
v2000.2.0
every(tag: Tag | Tag[], action: (obj: GameObj) => T)
Iterate through children.
since
v2000.2.0
revery(action: (obj: GameObj) => T)
Iterate through children, in reverse.
since
v2000.2.0
revery(tag: Tag | Tag[], action: (obj: GameObj) => T)
Iterate through children, in reverse.
since
v2000.2.0
children: GameObj[]
Get all children game objects.
since
v2000.2.0
update()
Update this game object and all children game objects.
since
v2000.2.0
draw()
Draw this game object and all children game objects.
since
v2000.2.0
is(tag: Tag | Tag[]) => boolean
If there's certain tag(s) on the game obj.
use(comp: Comp | Tag)
Add a component or tag.
unuse(comp: Tag)
Remove a tag or a component with its id.
on(ev: string, action: () => void) => EventCanceller
Register an event.
trigger(ev: string, args: ...)
Trigger an event.
destroy()
Remove the game obj from scene.
c(id: Tag) => Comp
Get state for a specific comp.
inspect() => GameObjInspect
Gather debug info of all comps.
onUpdate(action: () => void) => EventCanceller
Register an event that runs every frame as long as the game obj exists.
since
v2000.1
onDraw(action: () => void) => EventCanceller
Register an event that runs every frame as long as the game obj exists (this is the same as `onUpdate()`, but all draw events are run after all update events).
since
v2000.1
onDestroy(action: () => void) => EventCanceller
Register an event that runs when the game obj is destroyed.
since
v2000.1
action: GameObjRaw["onUpdate"]
Register an event that runs every frame as long as the game obj exists (alias to onUpdate).
deprecated
v2000.1 Use onUpdate() instead.
GameObjRaw&MergeComps<T>
string
(args: ...) => void
number
() => void
Screen recording control handle.
pause()
Pause the recording.
resume()
Resumes the recording.
download(filename?: string)
Stops the recording and downloads the file as mp4. Trying to resume later will lead to error.
number |
from: number
The starting frame.
to: number
The end frame.
loop?: boolean
If this anim should be played in loop.
pingpong?: boolean
When looping should it move back instead of go to start frame again.
speed?: number
This anim's speed in frames per second.
Sprite animation configuration when playing.
loop?: boolean
If this anim should be played in loop.
pingpong?: boolean
When looping should it move back instead of go to start frame again.
speed?: number
This anim's speed in frames per second.
onEnd?: () => void
Runs when this animation ends.
Record<string, SpriteAnim>
Sprite loading configuration.
sliceX?: number
sliceY?: number
anims?: SpriteAnims
filter?: TexFilter
wrap?: TexWrap
Record<string, SpriteAtlasEntry>
A sprite in a sprite atlas.
x: number
X position of the top left corner.
y: number
Y position of the top left corner.
width: number
Sprite area width.
height: number
Sprite area height.
sliceX?: number
If the defined area contains multiple sprites, how many frames are in the area hozizontally.
sliceY?: number
If the defined area contains multiple sprites, how many frames are in the area vertically.
anims?: SpriteAnims
Animation configuration.
string | GfxTexData
tex: GfxTexture
frames: Quad[]
anims: SpriteAnims
filter?: TexFilter
wrap?: TexWrap
chars?: string
filter?: TexFilter
wrap?: TexWrap
buf: AudioBuffer
GfxFont
GfxShader
Audio play configurations.
loop?: boolean
If audio should be played again from start when its ended.
volume?: number
Volume of audio. 1.0 means full volume, 0.5 means half volume.
speed?: number
Playback speed. 1.0 means normal playback speed, 2.0 means twice as fast.
detune?: number
Detune the sound. Every 100 means a semitone.
// play a random note in the octave
play("noteC", {
    detune: randi(0, 12) * 100,
})
seek?: number
The start time, in seconds.
play(seek?: number)
Play the sound. Optionally pass in the time where it starts.
stop()
Stop the sound.
pause()
Pause the sound.
isPaused() => boolean
If the sound is paused.
since
v2000.1
isStopped() => boolean
If the sound is stopped or ended.
since
v2000.1
speed(s?: number) => number
Change the playback speed of the sound. 1.0 means normal playback speed, 2.0 means twice as fast.
detune(d?: number) => number
Detune the sound. Every 100 means a semitone.
// tune down a semitone
music.detune(-100)

// tune up an octave
music.detune(1200)
volume(v?: number) => number
Change the volume of the sound. 1.0 means full volume, 0.5 means half volume.
time() => number
The current playing time.
duration() => number
The total duration.
loop()
Set audio to play in loop.
unloop()
Set audio to not play in loop.
paused() => boolean
deprecated
v2000.1 Use isPaused() instead.
stopped() => boolean
deprecated
v2000.1 Use isStopped() instead.
bind()
unbind()
send(uniform: Uniform)
width: number
height: number
bind()
unbind()
HTMLImageElement | HTMLCanvasElement | ImageData | ImageBitmap
tex: GfxTexture
map: Record<string, Vec2>
qw: number
The quad width of each character.
qh: number
type
Vertex
pos: Vec3
uv: Vec2
color: Color
opacity: number
"nearest" | "linear"
"repeat" | "clampToEdge"
Common render properties.
pos?: Vec2
scale?: Vec2 | number
angle?: number
color?: Color
opacity?: number
fixed?: boolean
shader?: GfxShader
uniform?: Uniform
RenderProps&
sprite: string | SpriteData
The sprite name in the asset manager, or the raw sprite data.
frame?: number
If the sprite is loaded with multiple frames, or sliced, use the frame option to specify which frame to draw.
width?: number
Width of sprite. If `height` is not specified it'll stretch with aspect ratio. If `tiled` is set to true it'll tiled to the specified width horizontally.
height?: number
Height of sprite. If `width` is not specified it'll stretch with aspect ratio. If `tiled` is set to true it'll tiled to the specified width vertically.
tiled?: boolean
When set to true, `width` and `height` will not scale the sprite but instead render multiple tiled copies of them until the specified width and height. Useful for background texture pattern etc.
flipX?: boolean
If flip the texture horizontally.
flipY?: boolean
If flip the texture vertically.
quad?: Quad
The sub-area to render from the texture, by default it'll render the whole `quad(0, 0, 1, 1)`
origin?: Origin | Vec2
The origin point, or the pivot point. Default to "topleft".
RenderProps&
width: number
Width of the UV quad.
height: number
Height of the UV quad.
flipX?: boolean
If flip the texture horizontally.
flipY?: boolean
If flip the texture vertically.
tex?: GfxTexture
The texture to sample for this quad.
quad?: Quad
The texture sampling area.
origin?: Origin | Vec2
The origin point, or the pivot point. Default to "topleft".
RenderProps&
width: number
Width of the rectangle.
height: number
Height of the rectangle.
outline?: Outline
If draw an outline around the shape.
fill?: boolean
If fill the shape with color (set this to false if you only want an outline).
radius?: number
The radius of each corner.
origin?: Origin | Vec2
The origin point, or the pivot point. Default to "topleft".
Omit<RenderProps, "angle" | "scale">&
p1: Vec2
Starting point of the line.
p2: Vec2
Ending point of the line.
width?: number
The width, or thickness of the line,
Omit<RenderProps, "angle" | "scale">&
pts: Vec2[]
The points that should be connected with a line.
width?: number
The width, or thickness of the lines,
radius?: number
The radius of each corner.
RenderProps&
p1: Vec2
First point of triangle.
p2: Vec2
Second point of triangle.
p3: Vec2
Third point of triangle.
outline?: Outline
If draw an outline around the shape.
fill?: boolean
If fill the shape with color (set this to false if you only want an outline).
radius?: number
The radius of each corner.
Omit<RenderProps, "angle">&
radius: number
Radius of the circle.
start?: number
Starting angle.
outline?: Outline
If draw an outline around the shape.
fill?: boolean
If fill the shape with color (set this to false if you only want an outline).
resolution?: number
Multipliyer for the number of polygon segments.
origin?: Origin | Vec2
The origin point, or the pivot point. Default to "topleft".
RenderProps&
radiusX: number
The horizontal radius.
radiusY: number
The vertical radius.
start?: number
Starting angle.
outline?: Outline
If draw an outline around the shape.
fill?: boolean
If fill the shape with color (set this to false if you only want an outline).
resolution?: number
Multipliyer for the number of polygon segments.
origin?: Origin | Vec2
The origin point, or the pivot point. Default to "topleft".
RenderProps&
pts: Vec2[]
The points that make up the polygon
outline?: Outline
If draw an outline around the shape.
fill?: boolean
If fill the shape with color (set this to false if you only want an outline).
indices?: number[]
Manual triangulation.
offset?: Vec2
The center point of transformation in relation to the position.
radius?: number
The radius of each corner.
width?: number
The width, or thinkness of the line.
color?: Color
The color of the line.
RenderProps&
text: string
The text to render.
font?: string | FontData
The name of font to use.
size?: number
The size of text (the height of each character).
width?: number
The maximum width. Will wrap around if exceed.
lineSpacing?: number
The gap between each line.
since
v2000.2
letterSpacing?: number
The gap between each character.
since
v2000.2
origin?: Origin | Vec2
The origin point, or the pivot point. Default to "topleft".
transform?: CharTransform | CharTransformFunc
Transform the pos, scale, rotation or color for each character based on the index or char.
since
v2000.1
styles?: Record<string, CharTransform | CharTransformFunc>
Stylesheet for styled chunks, in the syntax of "this is a [styled].stylename word".
since
v2000.2
Formatted text with info on how and where to render each character.
width: number
height: number
chars: FormattedChar[]
One formated character.
tex: GfxTexture
quad: Quad
ch: string
pos: Vec2
scale: Vec2
angle: number
color: Color
fixed: boolean
opacity: number
uniform: Uniform
(idx: number, ch: string) => CharTransform
Describes how to transform each character.
pos?: Vec2
scale?: Vec2 | number
angle?: number
color?: Color
opacity?: number
type
Cursor
string | "auto" | "default" | "none" | "context-menu" | "help" | "pointer" | "progress" | "wait" | "cell" | "crosshair" | "text" | "vertical-text" | "alias" | "copy" | "move" | "no-drop" | "not-allowed" | "grab" | "grabbing" | "all-scroll" | "col-resize" | "row-resize" | "n-resize" | "e-resize" | "s-resize" | "w-resize" | "ne-resize" | "nw-resize" | "se-resize" | "sw-resize" | "ew-resize" | "ns-resize" | "nesw-resize" | "nwse-resize" | "zoom-int" | "zoom-out"
type
Origin
"topleft" | "top" | "topright" | "left" | "center" | "right" | "botleft" | "bot" | "botright"
type
Vec2
x: number
y: number
LEFT: Vec2
RIGHT: Vec2
UP: Vec2
DOWN: Vec2
fromAngle(deg: number) => Vec2
clone() => Vec2
add(p: Vec2) => Vec2
Returns the addition with another vector.
add(x: number, y: number) => Vec2
sub(p: Vec2) => Vec2
Returns the subtraction with another vector.
sub(x: number, y: number) => Vec2
scale(p: Vec2) => Vec2
Scale by another vector, or a single number.
scale(s: number) => Vec2
scale(sx: number, sy: number) => Vec2
dot(p: Vec2) => number
Get the dot product with another vector.
dist(p: Vec2) => number
Get distance between another vector.
len() => number
unit() => Vec2
Get the unit vector (length of 1).
normal() => Vec2
Get the perpendicular vector.
angle(p: Vec2) => number
Get the angle between another vector
lerp(p: Vec2, t: number) => Vec2
Linear interpolate to a destination vector
toFixed(n: number) => Vec2
To n precision floating point.
eq(p: Vec2) => boolean
str() => string
deprecated
v2000.2 Use toString() instead.
type
Vec3
x: number
y: number
z: number
xy() => Vec2
type
Vec4
x: number
y: number
z: number
w: number
type
Mat4
m: number[]
translate(p: Vec2) => Mat4
translate(p: Vec2) => Mat4
scale(s: Vec2) => Mat4
scale(s: Vec2) => Mat4
rotateX(a: number) => Mat4
rotateX(a: number) => Mat4
rotateY(a: number) => Mat4
rotateY(a: number) => Mat4
rotateZ(a: number) => Mat4
rotateZ(a: number) => Mat4
clone() => Mat4
mult(other: Mat4) => Mat4
multVec4(p: Vec4) => Vec4
multVec3(p: Vec3) => Vec3
multVec2(p: Vec2) => Vec2
invert() => Mat4
type
Color
0-255 RGBA color.
r: number
Red (0-255).
g: number
Green (0-255).
b: number
Blue (0-255).
fromArray(arr: number[]) => Color
RED: Color
GREEN: Color
BLUE: Color
YELLOW: Color
MAGENTA: Color
CYAN: Color
WHITE: Color
BLACK: Color
clone() => Color
lighten(n: number) => Color
Lighten the color (adds RGB by n).
darken(n: number) => Color
Darkens the color (subtracts RGB by n).
invert() => Color
mult(other: Color) => Color
eq(c: Color) => boolean
str() => string
deprecated
v2000.2 Use toString() instead.
type
Quad
x: number
y: number
w: number
h: number
scale(q: Quad) => Quad
clone() => Quad
eq(q: Quad) => boolean
number | Vec2 | Color
type
RNG
seed: number
gen() => number
gen(n: T) => T
gen(a: T, b: T) => T
type
Rect
p1: Vec2
p2: Vec2
type
Line
p1: Vec2
p2: Vec2
type
Circle
center: Vec2
radius: number
type
Point
Vec2
type
Comp
id?: Tag
Component ID (if left out won't be treated as a comp).
require?: Tag[]
What other comps this comp depends on.
add?: () => void
Event that runs when host game obj is added to scene.
load?: () => void
Event that runs when host game obj is added to scene and game is loaded.
update?: () => void
Event that runs every frame.
draw?: () => void
Event that runs every frame.
destroy?: () => void
Event that runs when obj is removed from scene.
inspect?: () => string
Debug info for inspect mode.
number
pos: Vec2
Object's current world position.
move(xVel: number, yVel: number)
Move how many pixels per second. If object is 'solid', it won't move into other 'solid' objects.
move(vel: Vec2)
moveBy(dx: number, dy: number)
Move how many pixels, without multiplying dt, but still checking for 'solid'.
moveBy(d: Vec2)
moveTo(dest: Vec2, speed?: number)
Move to a spot with a speed (pixels per second), teleports if speed is not given.
moveTo(x: number, y: number, speed?: number)
screenPos() => Vec2
Get position on screen after camera transform.
scale: Vec2 | number
scaleTo(s: number)
scaleTo(s: Vec2)
scaleTo(sx: number, sy: number)
angle: number
Angle in degrees.
color: Color
opacity: number
origin: Origin | Vec2
Origin point for render.
layer: string
Which layer this game obj belongs to.
type
ZComp
z: number
Defines the z-index of this game obj
follow:
obj: GameObj
offset: Vec2
hide?: boolean
If hide object when out of view.
pause?: boolean
If pause object when out of view.
destroy?: boolean
If destroy object when out of view.
offset?: number | Vec2
The screen bound offset.
delay?: number
If it needs to stay out of view for a period of time before proceed to action.
onExitView?: () => void
Register an event that runs when object goes out of view.
onEnterView?: () => void
Register an event that runs when object enters view.
isOutOfView() => boolean
If object is currently out of view.
onExitView(action: () => void) => EventCanceller
Register an event that runs when object goes out of view.
onEnterView(action: () => void) => EventCanceller
Register an event that runs when object enters view.
offset?: number | Vec2
The screen bound offset.
delay?: number
If it needs to stay out of view for a period of time before proceed to destroy.
onCleanup?: () => void
Register an event that runs when object gets cleaned up.
Collision resolution data.
target: GameObj
The game object that we collided into.
displacement: Vec2
The displacement it'll need to separate us from the target.
isTop() => boolean
If the collision happened (roughly) on the top side of us.
isBottom() => boolean
If the collision happened (roughly) on the bottom side of us.
isLeft() => boolean
If the collision happened (roughly) on the left side of us.
isRight() => boolean
If the collision happened (roughly) on the right side of us.
shape?: Shape
The shape of the area.
offset?: Vec2
Position of area relative to position of the object.
width?: number
Width of area.
height?: number
Height of area.
scale?: number | Vec2
Area scale.
cursor?: Cursor
Cursor on hover.
area: AreaCompOpt
Collider area info.
isClicked() => boolean
If was just clicked on last frame.
isHovering() => boolean
If is being hovered on.
isColliding(o: GameObj) => boolean
If is currently colliding with another game obj.
isTouching(o: GameObj) => boolean
If is currently touching another game obj.
onClick(f: () => void)
Register an event runs when clicked.
since
v2000.1
onHover(onHover: () => void, onNotHover?: () => void)
Register an event runs every frame when hovered.
since
v2000.1
onCollide(tag: Tag, f: (obj: GameObj, col?: Collision) => void)
Register an event runs when collide with another game obj with certain tag.
since
v2000.1
hasPoint(p: Vec2) => boolean
If has a certain point inside collider.
pushOut(obj: GameObj)
Push out from another solid game obj if currently overlapping.
pushOutAll()
Push out from all other solid game objs if currently overlapping.
worldArea() => Area
Get the geometry data for the collider in world coordinate space.
screenArea() => Area
Get the geometry data for the collider in screen coordinate space.
collides: AreaComp["onCollide"]
deprecated
v2000.1 Use onCollide() instead.
clicks: AreaComp["onClick"]
deprecated
v2000.1 Use onClick() instead.
hovers: AreaComp["onHover"]
deprecated
v2000.1 Use onHover() instead.
frame?: number
If the sprite is loaded with multiple frames, or sliced, use the frame option to specify which frame to draw.
tiled?: boolean
If provided width and height, don't stretch but instead render tiled.
width?: number
Stretch sprite to a certain width.
height?: number
Stretch sprite to a certain height.
anim?: string
Play an animation on start.
animSpeed?: number
Animation speed scale multiplier.
flipX?: boolean
Flip texture horizontally.
flipY?: boolean
Flip texture vertically.
quad?: Quad
The rectangular sub-area of the texture to render, default to full texture `quad(0, 0, 1, 1)`.
width: number
Width for sprite.
height: number
Height for sprite.
frame: number
Current frame.
quad: Quad
The rectangular area of the texture to render.
play(anim: string, options?: SpriteAnimPlayOpt)
Play a piece of anim.
stop()
Stop current anim.
numFrames() => number
Get total number of frames.
curAnim() => string
Get current anim name.
animSpeed: number
Frame animation speed scale multiplier.
flipX(b: boolean)
Flip texture horizontally.
flipY(b: boolean)
Flip texture vertically.
onAnimStart(name: string, action: () => void) => EventCanceller
Register an event that runs when an animation is played.
onAnimEnd(name: string, action: () => void) => EventCanceller
Register an event that runs when an animation is ended.
text: string
The text to render.
textSize: number
The text size.
font: string | FontData
The font to use.
width: number
Width of text.
height: number
Height of text.
lineSpacing: number
The gap between each line.
since
v2000.2
letterSpacing: number
The gap between each character.
since
v2000.2
transform: CharTransform | CharTransformFunc
Transform the pos, scale, rotation or color for each character based on the index or char.
since
v2000.1
styles: Record<string, CharTransform | CharTransformFunc>
Stylesheet for styled chunks, in the syntax of "this is a [styled].stylename word".
since
v2000.2
size?: number
Height of text.
font?: string | FontData
The font to use.
width?: number
Wrap text to a certain width.
lineSpacing?: number
The gap between each line.
since
v2000.2
letterSpacing?: number
The gap between each character.
since
v2000.2
transform?: CharTransform | CharTransformFunc
Transform the pos, scale, rotation or color for each character based on the index or char.
since
v2000.1
styles?: Record<string, CharTransform | CharTransformFunc>
Stylesheet for styled chunks, in the syntax of "this is a [styled].stylename word".
since
v2000.2
radius?: number
Radius of the rectangle corners.
width: number
Width of rectangle.
height: number
Height of rectangle.
radius?: number
The radius of each corner.
radius: number
Radius of circle.
width: number
Width of rect.
height: number
Height of height.
type
Area
unknown | unknown | unknown | unknown | unknown
type
Shape
"rect" | "line" | "point" | "circle" | "polygon"
outline: Outline
type
Debug
paused: boolean
Pause the whole game.
inspect: boolean
Draw bounding boxes of all objects with `area()` component, hover to inspect their states.
timeScale: number
Global time scale.
showLog: boolean
Show the debug log or not.
fps() => number
Current frames per second.
objCount() => number
Number of all existing game objects.
drawCalls() => number
Number of draw calls made last frame.
stepFrame()
Step to the next frame. Useful with pausing.
clearLog()
Clear the debug log.
log(msg: string)
Log some text to on screen debug log.
error(msg: string)
Log an error message to on screen debug log.
curRecording: Recording | null
The recording handle if currently in recording mode.
since
v2000.1
Vec2 | Vec3 | Color | Mat4
Record<string, UniformValue>
uniform: Uniform
shader: string
solid: boolean
If should collide with other solid objects.
jumpForce: number
Initial speed in pixels per second for jump().
weight: number
Gravity multiplier.
curPlatform() => GameObj | null
Current platform landing on.
isGrounded() => boolean
If currently landing on a platform.
since
v2000.1
isFalling() => boolean
If currently falling.
since
v2000.1
jump(force?: number)
Upward thrust.
doubleJump(f?: number)
Performs double jump (the initial jump only happens if player is grounded).
onGround(action: () => void) => EventCanceller
Register an event that runs when the object is grounded.
since
v2000.1
onFall(action: () => void) => EventCanceller
Register an event that runs when the object starts falling.
since
v2000.1
onHeadbutt(action: () => void) => EventCanceller
Register an event that runs when the object bumps into something on the head.
since
v2000.1
onDoubleJump(action: () => void) => EventCanceller
Register an event that runs when the object performs the second jump when double jumping.
since
v2000.1
grounded() => boolean
deprecated
v2000.1 Use isGrounded() instead.
falling() => boolean
deprecated
v2000.1 Use isFalling() instead.
jumpForce?: number
Initial speed in pixels per second for jump().
maxVel?: number
Maximum velocity when falling.
weight?: number
Gravity multiplier.
solid?: boolean
If should not move through other solid objects.
type
Timer
time: number
Time left.
action: () => void
The action to take when timer is up
finished: boolean
paused: boolean
tick(dt: number) => boolean
reset(time: number)
wait(n: number, action: () => void) => EventCanceller
Run the callback after n seconds.
solid: boolean
If should stop other solid objects from moving through.
fixed: boolean
If the obj is unaffected by camera
stay: boolean
If the obj should not be destroyed on scene switch.
hurt(n?: number)
Decrease HP by n (defaults to 1).
heal(n?: number)
Increase HP by n (defaults to 1).
hp() => number
Current health points.
setHP(hp: number)
Set current health points.
onHurt(action: () => void) => EventCanceller
Register an event that runs when hurt() is called upon the object.
since
v2000.1
onHeal(action: () => void) => EventCanceller
Register an event that runs when heal() is called upon the object.
since
v2000.1
onDeath(action: () => void) => EventCanceller
Register an event that runs when object's HP is equal or below 0.
since
v2000.1
fade?: number
Fade out duration (default 0 which is no fade out).
state: string
Current state.
enterState: (state: string, args: ...) => void
Enter a state, trigger onStateLeave for previous state and onStateEnter for the new State state.
onStateTransition(from: string, to: string, action: () => void) => unknown
Register event that runs once when a specific state transition happens. Accepts arguments passed from `enterState(name, ...args)`.
since
v2000.2
onStateEnter: (state: string, action: (args: ...) => void) => void
Register event that runs once when enters a specific state. Accepts arguments passed from `enterState(name, ...args)`.
onStateLeave: (state: string, action: () => void) => void
Register an event that runs once when leaves a specific state.
onStateUpdate: (state: string, action: () => void) => void
Register an event that runs every frame when in a specific state.
onStateDraw: (state: string, action: () => void) => void
Register an event that runs every frame when in a specific state.
width: number
Width of each block.
height: number
Height of each block.
pos?: Vec2
Position of the first block.
any?: (s: string, pos: Vec2) => CompList<any> | unknown
Called when encountered an undefined symbol.
type
Level
getPos(p: Vec2) => Vec2
getPos(x: number, y: number) => Vec2
spawn(sym: string, p: Vec2) => GameObj
spawn(sym: string, x: number, y: number) => GameObj
width() => number
height() => number
gridWidth() => number
gridHeight() => number
offset() => Vec2
destroy() => unknown
type
Kaboom
destroy()
Remove kaboom.