kaplay<TPlugins, TButtons, TButtonsName>(options?: KaboomOpt<TPlugins, TButtons>)

Initialize KAPLAY context. The starting point of all KAPLAY games.

// Start KAPLAY with default options (will create a fullscreen canvas under <body>)
kaplay()

// Init with some options
kaplay({
    width: 320,
    height: 240,
    font: "sans-serif",
    canvas: document.querySelector("#mycanvas"),
    background: [ 0, 0, 255, ],
})

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

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

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

quit(): void

End everything.

KaboomOpt<TPlugin, TButtonDef>:

KAPLAY 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.

debug?: boolean

If register debug buttons (default true)

debugKey?: Key

Key that toggles debug mode

font?: string

Default font (defaults to "monospace").

pixelDensity?: number

Device pixel scale (defaults to window.devicePixelRatio, high pixel density will hurt performance).

since v3000.0

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[] | string

Background color. E.g. [ 0, 0, 255 ] for solid blue background, or [ 0, 0, 0, 0 ] for transparent background. Accepts RGB value array or string hex codes.

texFilter?: TexFilter

Default texture filter.

logMax?: number

How many log messages can there be on one screen (default 8).

logTime?: number

How many seconds log messages stay on screen (default 4).

since v3000.1

hashGridSize?: number

Size of the spatial hash grid for collision detection (default 64).

since v3000.0

touchToMouse?: boolean

If translate touch events as mouse clicks (default true).

loadingScreen?: boolean

If KAPLAY should render a default loading screen when assets are not fully ready (default true).

since v3000.0

backgroundAudio?: boolean

If pause audio when tab is not active (default false).

since v3000.0

gamepads?: Record<string, GamepadDef>

Custom gamepad definitions (see gamepad.json for reference of the format).

since v3000.0

buttons?: TButtonDef

Defined buttons for input binding.

since v30010

maxFPS?: number

Limit framerate to an amount per second.

since v3000.0

focus?: boolean

If focus on the canvas on start (default true).

since v3001.0

global?: boolean

If import all KAPLAY functions to global (default true).

plugins?: TPlugin

List of plugins to import.

burp?: boolean

Enter burp mode.

loadRoot(path?: string): string

Sets the root for all subsequent resource urls.

loadRoot("https://myassets.com/")
loadSprite("bean", "sprites/bean.png") // will resolve to "https://myassets.com/sprites/bean.png"

loadSprite(name: string | null, src: LoadSpriteSrc | LoadSpriteSrc[], options?: LoadSpriteOpt): Asset<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("bean", "bean.png")
loadSprite("apple", "https://kaboomjs.com/sprites/apple.png")

// slice a spritesheet and add anims manually
loadSprite("bean", "bean.png", {
    sliceX: 4,
    sliceY: 1,
    anims: {
        run: {
            from: 0,
            to: 3,
        },
        jump: {
            from: 3,
            to: 3,
        },
    },
})

loadSpriteAtlas(src: LoadSpriteSrc, data: SpriteAtlasData): Asset<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: LoadSpriteSrc, url: string): Asset<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: LoadSpriteSrc, jsonSrc: string | AsepriteData): Asset<SpriteData>

Load a sprite with aseprite spritesheet json (should use "array" in the export options).

loadAseprite("car", "sprites/car.png", "sprites/car.json")

loadPedit(name: string | null, src: string): Asset<SpriteData>

loadBean(name?: string): Asset<SpriteData>

Load default sprite "bean".

loadBean()

// use it right away
add([
    sprite("bean"),
])

loadJSON(name: string | null, url: string): Asset<any>

Load custom JSON data from url.

since v3000.0

loadSound(name: string | null, src: string | ArrayBuffer): Asset<SoundData>

Load a sound into asset manager, with name and resource url.

loadSound("shoot", "/sounds/horse.ogg")
loadSound("shoot", "/sounds/squeeze.mp3")
loadSound("shoot", "/sounds/shoot.wav")

loadMusic(name: string | null, url: string): void

Like loadSound(), but the audio is streamed and won't block loading. Use this for big audio files like background music.

loadMusic("shoot", "/music/bossfight.mp3")

loadFont(name: string, src: string | BinaryData, opt?: LoadFontOpt): Asset<FontData>

Load a font (any format supported by the browser, e.g. ttf, otf, woff).

since v3000.0

// load a font from a .ttf file
loadFont("frogblock", "fonts/frogblock.ttf")

loadBitmapFont(name: string | null, src: string, gridWidth: number, gridHeight: number, options?: LoadBitmapFontOpt): Asset<BitmapFontData>

Load a bitmap font into asset manager, with name and resource url and infomation on the layout of the bitmap.

since v3000.0

// 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
loadBitmapFont("04b03", "fonts/04b03.png", 6, 8)

// load a font with custom characters
loadBitmapFont("myfont", "myfont.png", 6, 8, { chars: "☺☻♥♦♣♠" })

loadShader(name: string | null, vert?: string, frag?: string): Asset<ShaderData>

Load a shader with vertex and fragment code.

// default shaders and custom shader format
loadShader("outline",
`vec4 vert(vec2 pos, vec2 uv, vec4 color) {
    // predefined functions to get the default value by KAPLAY
    return def_vert();
}`,
`vec4 frag(vec2 pos, vec2 uv, vec4 color, sampler2D tex) {
    // turn everything blue-ish
    return def_frag() * vec4(0, 0, 1, 1);
}`, false)

loadShaderURL(name: string | null, vert?: string, frag?: string): Asset<ShaderData>

Load a shader with vertex and fragment code file url.

since v3000.0

// load only a fragment shader from URL
loadShader("outline", null, "/shaders/outline.glsl", true)

load<T>(l: Promise<T>): Asset<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")
}))

loadProgress(): number

Get the global asset loading progress (0.0 - 1.0).

since v3000.0

getSprite(name: string): Asset<SpriteData> | void

Get SpriteData from name.

since v3000.0

getSound(name: string): Asset<SoundData> | void

Get SoundData from name.

since v3000.0

getFont(name: string): Asset<FontData> | void

Get FontData from name.

since v3000.0

getBitmapFont(name: string): Asset<BitmapFontData> | void

Get BitmapFontData from name.

since v3000.0

getShader(name: string): Asset<ShaderData> | void

Get ShaderData from name.

since v3000.0

getAsset(name: string): Asset<any> | void

Get custom data from name.

since v3000.0

SpriteData:

tex: Texture$1

width: number

since v3001.0

height: number

since v3001.0

from(src: LoadSpriteSrc, opt?: LoadSpriteOpt): Promise<SpriteData>

fromImage(data: ImageSource, opt?: LoadSpriteOpt): SpriteData

fromURL(url: string, opt?: LoadSpriteOpt): Promise<SpriteData>

add<T>(comps?: CompList<T> | GameObj<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),
    // 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)
})

make<T>(comps?: CompList<T>): GameObj<T>

Create a game object like add(), but not adding to the scene.

since v3000.1

const label = make([
    text("oh hi"),
])

add([
    rect(label.width, label.height),
    color(0, 0, 255),
    children(label),
])

readd(obj: GameObj): void

Remove and re-add the game obj, without triggering add / destroy events.

// Common way to use this is to have one sprite overlap another sprite, and use readd() to have the bottom sprite on top of the other.

// Create two sprites.
const greenBean = add([
    sprite("bean"),
    pos(200,140),
    color(255, 255, 255),
    area(),
]);

// This bean will overlap the green bean.
const purpleBean = add([
    sprite("bean"),
    pos(230,140),
    color(255, 0, 255),
    area(),
]);

// Example 1: simply call readd() on the target you want on top.
readd(greenBean);

// Example 2: using onClick() or other functions with readd().
// If you comment out the first example, and use this readd() with a function like onClick(), you
can keep switching which sprite is above the other ( click on edge of face ).

purpleBean.onClick(() => {
    readd(greenBean)
});

greenBean.onClick(() => {
    readd(purpleBean)
});

get(tag: Tag | Tag[], opts?: GetOpt): 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")

// To get all objects use "*"
const allObjs = get("*")

// Recursively get all children and descendents
const allObjs = get("*", { recursive: true })

destroy(obj: GameObj): void

Remove the game obj.

// every time bean collides with anything with tag "fruit", remove it
bean.onCollide("fruit", (fruit) => {
    destroy(fruit)
})

destroyAll(tag: Tag): void

Remove all game objs with certain tag.

// destroy all objects with tag "bomb" when you click one
onClick("bomb", () => {
    destroyAll("bomb")
})

GameObjRaw:

Base interface of all game objects.

add<T>(comps?: CompList<T> | GameObj<T>): GameObj<T>

Add a child.

since v3000.0

readd<T>(obj: GameObj<T>): GameObj<T>

Remove and re-add the game obj, without triggering add / destroy events.

remove(obj: GameObj): void

Remove a child.

since v3000.0

removeAll(tag: Tag): void

Remove all children with a certain tag.

since v3000.0

removeAll(): void

Remove all children.

since v3000.0

get(tag: Tag | Tag[], opts?: GetOpt): GameObj[]

Get a list of all game objs with certain tag.

since v3000.0

query(opt: QueryOpt): GameObj[]

Get a list of all game objs with certain properties.

since v3001.0

children: GameObj[]

Get all children game objects.

since v3000.0

tags: string[]

Get the tags of a game object.

since v3001.0

update(): void

Update this game object and all children game objects.

since v3000.0

draw(): void

Draw this game object and all children game objects.

since v3000.0

drawInspect(): void

Draw debug info in inspect mode

since v3000.0

is(tag: Tag | Tag[]): boolean

If there's certain tag(s) on the game obj.

use(comp: Comp | Tag): void

Add a component or tag.

unuse(comp: Tag): void

Remove a tag or a component with its id.

on(event: string, action: (args: any) => void): EventController

Register an event.

trigger(event: string, args: any): void

Trigger an event.

destroy(): void

Remove the game obj from scene.

c(id: Tag): Comp | undefined

Get state for a specific comp.

inspect(): GameObjInspect

Gather debug info of all comps.

onAdd(action: () => void): EventController

Register an event that runs when the game obj is added to the scene.

onUpdate(action: () => void): EventController

Register an event that runs every frame as long as the game obj exists.

since v2000.1

onDraw(action: () => void): EventController

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): EventController

Register an event that runs when the game obj is destroyed.

since v2000.1

exists(): boolean

If game obj is attached to the scene graph.

isAncestorOf(obj: GameObj): boolean

Check if is an ancestor (recursive parent) of another game object

since v3000.0

transform: Mat4$1

Calculated transform matrix of a game object.

since v3000.0

hidden: boolean

If draw the game obj (run "draw" event or not).

paused: boolean

If update the game obj (run "update" event or not).

id: GameObjID | null

A unique number ID for each game object.

canvas: FrameBuffer | null

The canvas to draw this game object on

since v3001.0

GameObj<T>: GameObjRaw & MergeComps<T>

The basic unit of object in KAPLAY. The player, a butterfly, a tree, or even a piece of text.

pos(x: number, y: number): PosComp

Set the position of a Game Object.

// This game object will draw a "bean" sprite at (100, 200)
add([
    pos(100, 200),
    sprite("bean"),
])

pos(xy: number): PosComp

pos(p: Vec2): PosComp

pos(): PosComp

scale(x: number, y: number): ScaleComp

Set the scale of a Game Object.

// scale uniformly with one value
add([
    sprite("bean"),
	   scale(3),
])
// scale with x & y values. In this case, scales more horizontally.
add([
    sprite("bean"),
	   scale(3, 1),
])
 // scale with vec2(x,y).
bean.scale = vec2(2,4)

scale(xy: number): ScaleComp

scale(s: Vec2): ScaleComp

rotate(a: number): RotateComp

Rotates a Game Object (in degrees).

color(r: number, g: number, b: number): ColorComp

Sets the color of a Game Object (rgb 0-255).

// blue frog
add([
    sprite("bean"),
    color(0, 0, 255)
])

color(c: Color$1): ColorComp

color(rgb: TupleType): ColorComp

color(c: string): ColorComp

opacity(o?: number): OpacityComp

Sets the opacity of a Game Object (0.0 - 1.0).

sprite(spr: string | SpriteData, options?: SpriteCompOpt): SpriteComp

Attach and render a sprite to a Game Object.

// minimal setup
add([
    sprite("bean"),
])

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

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

// manually setting a frame
bean.frame = 3

text(txt: string, options?: TextCompOpt): TextComp

Attach and render a text to a Game Object.

// 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: "sans-serif", // specify any font you loaded or browser built-in
    }),
])

polygon(pts: Vec2[], opt?: PolygonCompOpt): PolygonComp

Attach and render a polygon to a Game Object.

since v3001.0

// Make a square the hard way
add([
    pos(80, 120),
    polygon([vec2(0,0), vec2(50,0), vec2(50,50), vec2(0,50)]),
    outline(4),
    area(),
])

rect(w: number, h: number, opt?: RectCompOpt): RectComp

Attach and render a rectangle to a Game Object.

const obstacle = add([
    pos(80, 120),
    rect(20, 40),
    outline(4),
    area(),
])

circle(radius: number): CircleComp

Attach and render a circle to a Game Object.

add([
    pos(80, 120),
    circle(16),
])

uvquad(w: number, h: number): UVQuadComp

Attach and render a UV quad to a Game Object.

add([
    uvquad(width(), height()),
    shader("spiral"),
])

area(): AreaComp

Attach a collider area from shape and enables collision detection in a Game Object.

// Automatically generate area information from the shape of render
const player = add([
    sprite("bean"),
    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

anchor(o: Anchor | Vec2): AnchorComp

Anchor point for render (default "topleft").

// set anchor to "center" so it'll rotate from center
add([
    rect(40, 10),
    rotate(45),
    anchor("center"),
])

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.

layer(name: string): LayerComp

Determines the layer for objects. Object will be drawn on top if the layer index is higher.

outline(width?: number, color?: Color$1): 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".

// bean jumpy
const bean = add([
    sprite("bean"),
    // body() requires "pos" and "area" component
    pos(),
    area(),
    body(),
])

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

// run something when bean falls and hits a ground
bean.onGround(() => {
    debug.log("oh no!")
})

doubleJump(numJumps?: number): DoubleJumpComp

Enables double jump. Requires "body" component.

since v3000.0

move(direction: number | Vec2, speed: number): EmptyComp

Move towards a direction infinitely, and destroys when it leaves game view. Requires "pos" component.

// enemy throwing feces at player
const projectile = add([
    sprite("feces"),
    pos(enemy.pos),
    area(),
    move(player.pos.angle(enemy.pos), 1200),
    offscreen({ destroy: true }),
])

offscreen(opt?: OffScreenCompOpt): OffScreenComp

Control the behavior of object when it goes out of view.

since v2000.2

add([
    pos(player.pos),
    sprite("bullet"),
    offscreen({ destroy: true }),
    "projectile",
])

follow(obj: GameObj | null, offset?: Vec2): FollowComp

Follow another game obj's position.

shader(id: string, uniform?: Uniform | () => Uniform): ShaderComp

Custom shader.

timer(): TimerComp

Enable timer related functions like wait(), loop(), tween() on the game object.

const obj = add([
    timer(),
])

obj.wait(2, () => { ... })
obj.loop(0.5, () => { ... })
obj.tween(obj.pos, mousePos(), 0.5, (p) => obj.pos = p, easings.easeOutElastic)

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(scenesToStay?: string[]): 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, maxHP?: 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): EmptyComp

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 }),
])

named(name: string): NamedComp

Names an object.

since v3001.0

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)
})

fadeIn(time: number): Comp

Fade object in. Uses opacity for finding what to fade into and to set opacity during fade animation.

since v3000.0

deprecated since v3001.0

mask(maskType?: Mask): MaskComp

Mask all children object render.

since v3001.0

tile(opt: TileCompOpt): TileComp

A tile on a tile map.

since v3000.0

agent(opt?: AgentCompOpt): AgentComp

An agent which can finds it way on a tilemap.

since v3000.0

CompList<T>: Array<T | Tag>

A component list.

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.

update?(): void

Event that runs every frame.

draw?(): void

Event that runs every frame after update.

destroy?(): void

Event that runs when obj is removed from scene.

inspect?(): string | void

Debug info for inspect mode.

drawInspect?(): void

Draw debug info in inspect mode

since v3000.0

EmptyComp:

id: string

&
Comp

A component without own properties.

Collision:

Collision resolution data.

source: GameObj

The first game object in the collision.

target: GameObj

The second game object in the collision.

displacement: Vec2

The displacement source game object have to make to avoid the collision.

resolved: boolean

If the collision is resolved.

preventResolution(): void

Prevent collision resolution if not yet resolved.

since v3000.0

hasOverlap(): void

If the 2 objects have any overlap, or they're just touching edges.

since v3000.0

reverse(): Collision

Get a new collision with reversed source and target relationship.

isTop(): boolean

If the collision happened (roughly) on the top side.

isBottom(): boolean

If the collision happened (roughly) on the bottom side.

isLeft(): boolean

If the collision happened (roughly) on the left side.

isRight(): boolean

If the collision happened (roughly) on the right side.

LevelComp:

spawn(sym: string, p: Vec2): GameObj | null

Spawn a tile from a symbol defined previously.

spawn(sym: string, x: number, y: number): GameObj | null

spawn<T>(obj: CompList<T>, p: Vec2): GameObj<T>

Spawn a tile from a component list.

spawn<T>(sym: CompList<T>, x: number, y: number): GameObj<T>

levelWidth(): number

Total width of level in pixels.

levelHeight(): number

Total height of level in pixels.

getAt(tilePos: Vec2): GameObj[]

Get all game objects that's currently inside a given tile.

raycast(origin: Vec2, direction: Vec2): RaycastResult

Raycast all game objects on the given path.

tile2Pos(tilePos: Vec2): Vec2

Convert tile position to pixel position.

pos2Tile(pos: Vec2): Vec2

Convert pixel position to tile position.

getTilePath(from: Vec2, to: Vec2, opts?: PathFindOpt): Vec2[] | null

Find the path to navigate from one tile to another tile.

returns A list of traverse points in tile positions.

getPath(from: Vec2, to: Vec2, opts?: PathFindOpt): Vec2[] | null

Find the path to navigate from one tile to another tile.

returns A list of traverse points in pixel positions.

OpacityComp:

The opacity() component.

opacity: number

Opacity of the current object.

fadeIn(time?: number, easeFunc?: EaseFunc): TweenController

Fade in at the start.

fadeOut(time?: number, easeFunc?: EaseFunc): TweenController

Fade out at the start.

PolygonComp:

The polygon() component.

since v3001.0

pts: Vec2[]

Points in the polygon.

radius?: number | number[]

The radius of each corner.

colors?: Color[]

The color of each vertex.

uv?: Vec2[]

The uv of each vertex.

since v3001.0

tex?: Texture

The texture used when uv coordinates are present.

since v3001.0

RectCompOpt:

Options for the rect() component.

radius?: number

Radius of the rectangle corners.

fill?: boolean

If fill the rectangle (useful if you only want to render outline with outline() component).

SpriteComp:

The sprite() component.

sprite: string

Name of the sprite.

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): void

Play a piece of anim.

stop(): void

Stop current anim.

numFrames(): number

Get total number of frames.

getCurAnim(): SpriteCurAnim

Get the current animation data.

since v3001.0

curAnim(): string

Get current anim name.

deprecated Use `getCurrentAnim().name` instead.

animSpeed: number

Speed multiplier for all animations (for the actual fps for an anim use .play("anim", { speed: 10 })).

flipX: boolean

Flip texture horizontally.

flipY: boolean

Flip texture vertically.

onAnimStart(action: (anim: string) => void): EventController

Register an event that runs when an animation is played.

onAnimEnd(action: (anim: string) => void): EventController

Register an event that runs when an animation is ended.

SpriteCompOpt:

Options for the sprite() component.

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

Speed multiplier for all animations (for the actual fps for an anim use .play("anim", { speed: 10 })).

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)`.

fill?: boolean

If fill the sprite (useful if you only want to render outline with outline() component).

TextComp:

The text() component.

text: string

The text to render.

font: string | BitmapFontData

The font to use.

width: number

Width of text.

height: number

Height of text.

align: TextAlign

Text alignment ("left", "center" or "right", default "left").

since v3000.0

lineSpacing: number

The gap between each line.

since v2000.2

letterSpacing: number

The gap between each character.

since v2000.2

textTransform: CharTransform | CharTransformFunc

Transform the pos, scale, rotation or color for each character based on the index or char.

since v2000.1

textStyles: Record<string, CharTransform | CharTransformFunc>

Stylesheet for styled chunks, in the syntax of "this is a [style]text[/style] word".

since v2000.2

TextCompOpt:

Options for the text() component.

size?: number

Height of text.

font?: string | BitmapFontData

The font to use.

width?: number

Wrap text to a certain width.

align?: TextAlign

Text alignment ("left", "center" or "right", default "left").

since v3000.0

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 [style]text[/style] word".

since v2000.2

AgentComp:

The agent() component.

TileCompOpt:

isObstacle?: boolean

If the tile is an obstacle in pathfinding.

cost?: number

How much a tile is cost to traverse in pathfinding (default 0).

edges?: Edge[]

If the tile has hard edges that cannot pass in pathfinding.

offset?: Vec2

Position offset when setting `tilePos`.

Options for the tile() component.

HealthComp:

The health() component.

hurt(n?: number): void

Decrease HP by n (defaults to 1).

heal(n?: number): void

Increase HP by n (defaults to 1).

hp(): number

Current health points.

setHP(hp: number): void

Set current health points.

maxHP(): number | null

Max amount of HP.

setMaxHP(hp: number): void

Set max amount of HP.

onHurt(action: (amount?: number) => void): EventController

Register an event that runs when hurt() is called upon the object.

since v2000.1

onHeal(action: (amount?: number) => void): EventController

Register an event that runs when heal() is called upon the object.

since v2000.1

onDeath(action: () => void): EventController

Register an event that runs when object's HP is equal or below 0.

since v2000.1

StateComp:

The state() component.

state: string

Current state.

enterState(state: string, args: any): void

Enter a state, trigger onStateEnd for previous state and onStateEnter for the new State state.

onStateTransition(from: string, to: string, action: () => void): EventController

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: any) => void): EventController

Register event that runs once when enters a specific state. Accepts arguments passed from `enterState(name, ...args)`.

onStateEnd(state: string, action: () => void): EventController

Register an event that runs once when leaves a specific state.

onStateUpdate(state: string, action: () => void): EventController

Register an event that runs every frame when in a specific state.

onStateDraw(state: string, action: () => void): EventController

Register an event that runs every frame when in a specific state.

StayComp:

The stay() component.

stay: boolean

If the obj should not be destroyed on scene switch.

scenesToStay: string[]

Array of scenes that the obj will stay on.

TimerComp:

The timer() component.

wait(time: number, action?: () => void): TimerController

Run the callback after n seconds.

loop(time: number, action: () => void): EventController

Run the callback every n seconds.

since v3000.0

tween<V>(from: V, to: V, duration: number, setValue: (value: V) => void, easeFunc?: (t: number) => number): TweenController

Tweeeeen! Note that this doesn't specifically mean tweening on this object's property, this just registers the timer on this object, so the tween will cancel with the object gets destroyed, or paused when obj.paused is true.

since v3000.0

AreaComp:

The area() component.

area:

shape: Shape | null

If we use a custom shape over render shape.

scale: Vec2

Area scale.

cursor: Cursor | null

Cursor on hover.

Collider area info.

collisionIgnore: Tag[]

If this object should ignore collisions against certain other objects.

since v3000.0

isClicked(): boolean

If was just clicked on last frame.

checkCollision(other: GameObj<AreaComp>): Collision | null

Check collision with another game obj.

since v3000.0

getCollisions(): Collision[]

Get all collisions currently happening.

since v3000.0

isColliding(o: GameObj<AreaComp>): boolean

If is currently colliding with another game obj.

isOverlapping(o: GameObj<AreaComp>): boolean

If is currently overlapping with another game obj (like isColliding, but will return false if the objects are just touching edges).

onClick(f: () => void, btn?: MouseButton): void

Register an event runs when clicked.

since v2000.1

onHover(action: () => void): EventController

Register an event runs once when hovered.

since v3000.0

onHoverUpdate(action: () => void): EventController

Register an event runs every frame when hovered.

since v3000.0

onHoverEnd(action: () => void): EventController

Register an event runs once when unhovered.

since v3000.0

onCollide(tag: Tag, f: (obj: GameObj, col?: Collision) => void): void

Register an event runs once when collide with another game obj with certain tag.

since v2001.0

onCollide(f: (obj: GameObj, col?: Collision) => void): void

Register an event runs once when collide with another game obj.

since v2000.1

onCollideUpdate(tag: Tag, f: (obj: GameObj, col?: Collision) => void): EventController

Register an event runs every frame when collide with another game obj with certain tag.

since v3000.0

onCollideUpdate(f: (obj: GameObj, col?: Collision) => void): EventController

Register an event runs every frame when collide with another game obj.

since v3000.0

onCollideEnd(tag: Tag, f: (obj: GameObj) => void): EventController

Register an event runs once when stopped colliding with another game obj with certain tag.

since v3000.0

onCollideEnd(f: (obj: GameObj) => void): void

Register an event runs once when stopped colliding with another game obj.

since v3000.0

hasPoint(p: Vec2): boolean

If has a certain point inside collider.

resolveCollision(obj: GameObj): void

Push out from another solid game obj if currently overlapping.

localArea(): Shape

Get the geometry data for the collider in local coordinate space.

since v3000.0

worldArea(): Polygon

Get the geometry data for the collider in world coordinate space.

screenArea(): Polygon

Get the geometry data for the collider in screen coordinate space.

BodyComp:

The body() component.

vel: Vec2

Object current velocity.

since v3001.0

drag: number

How much velocity decays (velocity *= (1 - drag) every frame).

since v3001.0

isStatic: boolean

If object is static, won't move, and all non static objects won't move past it.

jumpForce: number

Initial speed in pixels per second for jump().

mass?: number

Mass of the body, decides how much a non-static body should move when resolves with another non-static body. (default 1).

since v3000.0

stickToPlatform?: boolean

If object should move with moving platform (default true).

since v3000.0

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

isJumping(): boolean

If currently rising.

since v3000.0

jump(force?: number): void

Upward thrust.

onPhysicsResolve(action: (col: Collision) => void): EventController

Register an event that runs when a collision is resolved.

since v3000.0

onBeforePhysicsResolve(action: (col: Collision) => void): EventController

Register an event that runs before a collision would be resolved.

since v3000.0

onGround(action: () => void): EventController

Register an event that runs when the object is grounded.

since v2000.1

onFall(action: () => void): EventController

Register an event that runs when the object starts falling.

since v2000.1

onFallOff(action: () => void): EventController

Register an event that runs when the object falls off platform.

since v3000.0

onHeadbutt(action: () => void): EventController

Register an event that runs when the object bumps into something on the head.

since v2000.1

BodyCompOpt:

Options for the body() component.

drag?: number

How much velocity decays (velocity *= (1 - drag) every frame).

since v3001.0

jumpForce?: number

Initial speed in pixels per second for jump().

isStatic?: boolean

If object is static, won't move, and all non static objects won't move past it.

since v3000.0

stickToPlatform?: boolean

If object should move with moving platform (default true).

since v3000.0

mass?: number

Mass of the body, decides how much a non-static body should move when resolves with another non-static body. (default 1).

since v3000.0

DoubleJumpComp:

The doubleJump() component.

numJumps: number

Number of jumps allowed.

doubleJump(force?: number): void

Performs double jump (the initial jump only happens if player is grounded).

onDoubleJump(action: () => void): EventController

Register an event that runs when the object performs the second jump when double jumping.

LayerComp:

The layer() component.

layer(): string

Get the name of the current layer the object is assigned to.

layer(name: string):

Set the name of the layer the object should be assigned to.

OffScreenComp:

The offscreen() component.

isOffScreen(): boolean

If object is currently out of view.

onExitScreen(action: () => void): EventController

Register an event that runs when object goes out of view.

onEnterScreen(action: () => void): EventController

Register an event that runs when object enters view.

OffScreenCompOpt:

Options for offscreen() component.

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.

distance?: number

The distance when out of view is triggered (default 200).

since v3000.0

PosComp:

The pos() component.

pos: Vec2

Object's current world position.

move(xVel: number, yVel: number): void

Move how many pixels per second. If object is 'solid', it won't move into other 'solid' objects.

move(vel: Vec2): void

moveBy(dx: number, dy: number): void

Move how many pixels, without multiplying dt, but still checking for 'solid'.

moveTo(dest: Vec2, speed?: number): void

Move to a spot with a speed (pixels per second), teleports if speed is not given.

moveTo(x: number, y: number, speed?: number): void

screenPos(): Vec2

Get the position of the object on the screen.

worldPos(): Vec2

Get the position of the object relative to the root.

toScreen(this: GameObj<PosComp | FixedComp>, p: Vec2): any

Transform a local point (relative to this) to a screen point (relative to the camera)

toWorld(this: GameObj<PosComp>, p: Vec2): any

Transform a local point (relative to this) to a world point (relative to the root)

since v3001.0

fromScreen(this: GameObj<PosComp | FixedComp>, p: Vec2): any

Transform a screen point (relative to the camera) to a local point (relative to this)

since v3001.0

fromWorld(this: GameObj<PosComp>, p: Vec2): any

Transform a world point (relative to the root) to a local point (relative to this)

since v3001.0

toOther(this: GameObj<PosComp>, other: GameObj<PosComp>, p: Vec2): any

Transform a point relative to this to a point relative to other

since v3001.0

fromOther(this: GameObj<PosComp>, other: GameObj<PosComp>, p: Vec2): any

Transform a point relative to other to a point relative to this

since v3001.0

RotateComp:

The rotate() component.

angle: number

Angle in degrees.

rotateBy(angle: number): void

Rotate in degrees.

rotateTo(s: number): void

Rotate to a degree (like directly assign to .angle)

since v3000.0

ZComp:

The z() component.

z: number

Defines the z-index of this game obj

getSceneName(): string

/** Gets the name of the current scene.

since v3001.0

scene(id: SceneName, def: SceneDef): void

Define a scene.

go(id: SceneName, args: any): void

Go to a scene, passing all rest args to scene callback.

layers(layernames: string[], defaultLayer: string): void

Define the layer names. Should be called before any objects are made.

onGamepadConnect(action: (gamepad: KGamePad) => void): void

Register an event that runs when a gamepad is connected.

since v3000.0

onGamepadDisconnect(action: (gamepad: KGamePad) => void): void

Register an event that runs when a gamepad is disconnected.

since v3000.0

onClick(tag: Tag, action: (a: GameObj) => void): EventController

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): EventController

Register an event that runs when users clicks.

// click on anywhere to go to "game" scene
onClick(() => go("game"))

since v2000.1

onKeyDown(key: Key | Key[], action: (key: Key) => void): EventController

Register an event that runs every frame when a key is held down.

// move left by SPEED pixels per frame every frame when left arrow key is being held down
onKeyDown("left", () => {
    bean.move(-SPEED, 0)
})

since v2000.1

onKeyDown(action: (key: Key) => void): EventController

Register an event that runs every frame when any key is held down.

since v2000.1

onKeyPress(key: Key | Key[], action: (key: Key) => void): EventController

Register an event that runs when user presses certain keys.

// .jump() once when "space" is just being pressed
onKeyPress("space", () => {
    bean.jump()
});

onKeyPress(["up", "space"], () => {
    bean.jump()
});

since v2000.1

onKeyPress(action: (key: Key) => void): EventController

Register an event that runs when user presses any key.

// Call restart() when player presses any key
onKeyPress((key) => {
    debug.log(`key pressed ${key}`)
    restart()
})

since v3001.0

onKeyPressRepeat(k: Key | Key[], action: (k: Key) => void): EventController

Register an event that runs when user presses certain kesy (also fires repeatedly when the keys are being held down).

// delete last character when "backspace" is being pressed and held
onKeyPressRepeat("backspace", () => {
    input.text = input.text.substring(0, input.text.length - 1)
})

since v3000.1

onKeyRelease(k: Key | Key[], action: (k: Key) => void): EventController

Register an event that runs when user release certain keys.

since v2000.1

onCharInput(action: (ch: string) => void): EventController

Register an event that runs when user inputs text.

since v2000.1

// type into input
onCharInput((ch) => {
    input.text += ch
})

onMouseDown(button: MouseButton | MouseButton[], action: (m: MouseButton) => void): EventController

Register an event that runs every frame when certain mouse buttons are being held down.

since v3001.0

onMouseDown(action: (m: MouseButton) => void): EventController

onMousePress(action: (m: MouseButton) => void): EventController

Register an event that runs when user clicks mouse.

since v3001.0

onMousePress(button: MouseButton | MouseButton[], action: (m: MouseButton) => void): EventController

onMouseRelease(action: (m: MouseButton) => void): EventController

Register an event that runs when user releases mouse.

since v3001.0

onMouseRelease(button: MouseButton | MouseButton[], action: (m: MouseButton) => void): EventController

onMouseMove(action: (pos: Vec2, delta: Vec2) => void): EventController

Register an event that runs whenever user move the mouse.

since v2000.1

onTouchStart(action: (pos: Vec2, t: Touch) => void): EventController

Register an event that runs when a touch starts.

since v2000.1

onTouchMove(action: (pos: Vec2, t: Touch) => void): EventController

Register an event that runs whenever touch moves.

since v2000.1

onTouchEnd(action: (pos: Vec2, t: Touch) => void): EventController

Register an event that runs when a touch ends.

since v2000.1

onScroll(action: (delta: Vec2) => void): EventController

Register an event that runs when mouse wheel scrolled.

since v3000.0

onGamepadButtonDown(btn: GamepadButton$1 | GamepadButton$1[], action: (btn: GamepadButton$1) => void): EventController

Register an event that runs every frame when certain gamepad buttons are held down.

since v3001.0

onGamepadButtonDown(action: (btn: GamepadButton$1) => void): EventController

Register an event that runs every frame when any gamepad buttons are held down.

since v3001.0

onGamepadButtonPress(btn: GamepadButton$1 | GamepadButton$1[], action: (btn: GamepadButton$1) => void): EventController

Register an event that runs when user presses certain gamepad button.

since v3001.0

onGamepadButtonPress(action: (btn: GamepadButton$1) => void): EventController

Register an event that runs when user presses any gamepad button.

since v3001.0

onGamepadButtonRelease(btn: GamepadButton$1 | GamepadButton$1[], action: (btn: GamepadButton$1) => void): EventController

Register an event that runs when user releases certain gamepad button

since v3001.0

onGamepadButtonRelease(action: (btn: GamepadButton$1) => void): EventController

Register an event that runs when user releases any gamepad button.

since v3000.0

onGamepadStick(stick: GamepadStick, action: (value: Vec2) => void): EventController

Register an event that runs when the gamepad axis exists.

since v3000.0

onButtonPress(btn: TButton | TButton[], action: (btn: TButton) => void): EventController

Register an event that runs when user press a defined button (like "jump") on any input (keyboard, gamepad).

since v3001.0

onButtonRelease(btn: TButton | TButton[], action: (btn: TButton) => void): EventController

Register an event that runs when user release a defined button (like "jump") on any input (keyboard, gamepad).

since v3001.0

onButtonDown(btn: TButton | TButton[], action: (btn: TButton) => void): EventController

Register an event that runs when user press a defined button (like "jump") on any input (keyboard, gamepad).

since v3001.0

onButtonDown(action: (btn: TButton) => void): EventController

isTouchscreen(): boolean

Is currently on a touch screen device.

since v3000.0

mousePos(): Vec2

Get current mouse position (without camera transform).

isKeyDown(k?: Key | Key[]): boolean

If certain keys are currently down.

// equivalent to the calling bean.move() in an onKeyDown("left")
onUpdate(() => {
    if (isKeyDown("left")) {
        bean.move(-SPEED, 0)
    }
})

since v3001.0

isKeyPressed(k?: Key | Key[]): boolean

If certain keys are just pressed last frame.

since v3001.0

isKeyPressedRepeat(k?: Key | Key[]): boolean

If certain keys are just pressed last frame (also fires repeatedly when the keys are being held down).

since v3001.0

isKeyReleased(k?: Key | Key[]): boolean

If certain keys are just released last frame.

since v3001.0

isMouseDown(button?: MouseButton | MouseButton[]): boolean

If mouse buttons are currently down.

since v3001.0

isMousePressed(button?: MouseButton | MouseButton[]): boolean

If mouse buttons are just clicked last frame.

since v3001.0

isMouseReleased(button?: MouseButton | MouseButton[]): boolean

If mouse buttons are just released last frame.

since v3001.0

isMouseMoved(): boolean

If mouse moved last frame.

since v2000.1

isGamepadButtonPressed(btn?: GamepadButton$1 | GamepadButton$1[]): boolean

If certain gamepad buttons are just pressed last frame

since v3000.0

isGamepadButtonDown(btn?: GamepadButton$1 | GamepadButton$1): boolean

If certain gamepad buttons are currently held down.

since v3000.0

isGamepadButtonReleased(btn?: GamepadButton$1 | GamepadButton$1[]): boolean

If certain gamepad buttons are just released last frame.

since v3000.0

isButtonPressed(button: TButton | TButton[]): boolean

If certain binded buttons are just pressed last frame on any input (keyboard, gamepad).

since v3001.0

isButtonDown(button: TButton | TButton[]): boolean

If certain binded buttons are currently held down on any input (keyboard, gamepad).

since v3001.0

isButtonReleased(button: TButton | TButton[]): boolean

If certain binded buttons are just released last frame on any input (keyboard, gamepad).

since v3001.0

getButton(button: TypeOperator): ButtonBinding

Get a input binding from a button name.

since v3001.0

setButton(button: string, def: ButtonBinding): void

Set a input binding for a button name.

since v3001.0

getGamepadStick(stick: GamepadStick): Vec2

Get stick axis values from a gamepad.

since v3001.0

charInputted(): string[]

List of characters inputted since last frame.

since v3000.0

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 | , | . | / | escape | backspace | enter | tab | control | alt | meta | space | | left | right | up | down | shift

A key.

MouseButton: left | right | middle | back | forward

A mouse button.

GamepadButton$1: north | east | south | west | ltrigger | rtrigger | lshoulder | rshoulder | select | start | lstick | rstick | dpad-up | dpad-right | dpad-down | dpad-left | home | capture

A gamepad button.

EventController:

A controller for all events in KAPLAY.

// Create a new event
const logHi = onUpdate(() => {
   debug.log("hi");
});

// Pause the event
logHi.paused = true;

// Cancel the event
logHi.cancel();

paused: boolean

If the event is paused

cancel(): void

Cancel the event

join(events: EventController[]): EventController

on(event: string, tag: Tag, action: (obj: GameObj, args: any) => void): EventController

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(bomb.pos)
})

// a custom event can be defined manually
// by passing a name and a callback function
on("talk", (message, posX, posY) => {
    add([
     text(message),
     pos(posX, posY - 100)
    ])
})
onKeyPress("space", () => {
   // the trigger method on game objs can be used to trigger a custom event
   npc.trigger("talk", "Hello World!", npc.pos.x, npc.pos.y)
})

onUpdate(tag: Tag, action: (obj: GameObj) => void): EventController

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): EventController

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): EventController

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): EventController

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),
    })
})

onAdd(tag: Tag, action: (obj: GameObj) => void): EventController

onAdd(action: (obj: GameObj) => void): EventController

onDestroy(tag: Tag, action: (obj: GameObj) => void): EventController

onDestroy(action: (obj: GameObj) => void): EventController

onLoad(action: () => void): void

Register an event that runs when all assets finished loading.

since v2000.1

const bean = add([
    sprite("bean"),
])

// certain assets related data are only available when the game finishes loading
onLoad(() => {
    debug.log(bean.width)
})

onLoading(action: (progress: number) => void): void

Register an event that runs every frame when assets are initially loading. Can be used to draw a custom loading screen.

since v3000.0

onError(action: (err: Error) => void): void

Register a custom error handler. Can be used to draw a custom error screen.

since v3000.0

onResize(action: () => void): void

Register an event that runs when the canvas resizes.

since v3000.0

onCleanup(action: () => void): void

Cleanup function to run when quit() is called.

since v3000.0

onCollide(t1: Tag, t2: Tag, action: (a: GameObj, b: GameObj, col?: Collision) => void): EventController

Register an event that runs once when 2 game objs with certain tags collides (required to have area() component).

since v2000.1

onCollide("sun", "earth", () => {
    addExplosion()
})

onCollideUpdate(t1: Tag, t2: Tag, action: (a: GameObj, b: GameObj, col?: Collision) => void): EventController

Register an event that runs every frame when 2 game objs with certain tags collides (required to have area() component).

since v3000.0

onCollideUpdate("sun", "earth", () => {
    runWorldEndTimer()
})

onCollideEnd(t1: Tag, t2: Tag, action: (a: GameObj, b: GameObj, col?: Collision) => void): EventController

Register an event that runs once frame when 2 game objs with certain tags stops colliding (required to have area() component).

since v3000.0

onCollideEnd("bean", "earth", () => {
    worldEnd()
})

onHover(tag: Tag, action: (a: GameObj) => void): EventController

Register an event that runs once when game objs with certain tags are hovered (required to have area() component).

since v3000.0

onHoverUpdate(tag: Tag, onHover: (a: GameObj) => void): EventController

Register an event that runs every frame when game objs with certain tags are hovered (required to have area() component).

since v3000.0

onHoverEnd(tag: Tag, action: (a: GameObj) => void): EventController

Register an event that runs once when game objs with certain tags are unhovered (required to have area() component).

since v3000.0

onHide(action: () => void): EventController

Register an event that runs when tab is hidden.

since v3001.0

onShow(action: () => void): EventController

Register an event that runs when tab is shown.

since v3001.0

onSceneLeave(action: (newScene?: string) => void): EventController

Register an event that runs when current scene ends.

since v3000.0

Event: TypeQuery

EventHandler for one single event.

since v3000.0

EventHandler<EventMap>:

on<Name>(name: Name, action: (args: EventMap[Name]) => void): EventController

onOnce<Name>(name: Name, action: (args: EventMap[Name]) => void): EventController

next<Name>(name: Name): Promise<UnknownKeyword>

trigger<Name>(name: Name, args: EventMap[Name]): void

remove<Name>(name: Name): void

EventController:

A controller for all events in KAPLAY.

// Create a new event
const logHi = onUpdate(() => {
   debug.log("hi");
});

// Pause the event
logHi.paused = true;

// Cancel the event
logHi.cancel();

paused: boolean

If the event is paused

cancel(): void

Cancel the event

join(events: EventController[]): EventController

width(): number

Get the width of game.

height(): number

Get the height of game.

center(): Vec2

Get the center point of view.

// add bean to the center of the screen
add([
    sprite("bean"),
    pos(center()),
    // ...
])

dt(): number

Get the delta time since last frame.

// rotate bean 100 deg per second
bean.onUpdate(() => {
    bean.angle += 100 * dt()
})

time(): number

Get the total time since beginning.

isFocused(): boolean

If the game canvas is currently focused.

since v2000.1

shake(intensity: number): void

Camera shake.

// shake intensively when bean collides with a "bomb"
bean.onCollide("bomb", () => {
    shake(120)
})

camPos(pos: Vec2): Vec2

Get / set camera position.

// camera follows player
player.onUpdate(() => {
    camPos(player.pos)
})

camPos(x: number, y: number): Vec2

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 (relative to the root) to screen position (relative to the screen).

since v3001.0

toWorld(p: Vec2): Vec2

Transform a point from screen position (relative to the screen) to world position (relative to the root).

setBackground(color: Color$1, alpha?: number): void

Set background color.

setBackground(r: number, g: number, b: number, alpha?: number): void

getGamepads(): KGamePad[]

Get connected gamepads.

since v3000.0

setCursor(style: Cursor): void

Set cursor style (check Cursor type for possible values). Cursor will be reset to "default" every frame so use this in an per-frame action.

since v3000.0

button.onHover((c) => {
    setCursor("pointer")
})

getCursor(): Cursor

Get current cursor style.

since v3000.0

setCursorLocked(locked: boolean): void

Lock / unlock cursor. Note that you cannot lock cursor within 1 second after user unlocking the cursor with the default unlock gesture (typically the esc key) due to browser policy.

since v3000.0

isCursorLocked(): boolean

Get if cursor is currently locked.

since v3000.0

setFullscreen(f?: boolean): void

Enter / exit fullscreen mode. (note: mouse position is not working in fullscreen mode at the moment)

// toggle fullscreen mode on "f"
onKeyPress("f", (c) => {
    setFullscreen(!isFullscreen())
})

VERSION: string

Current KAPLAY library version.

since v3000.0

wait(n: number, action?: () => void): TimerController

Run the callback after n seconds.

// 3 seconds until explosion! Runnn!
wait(3, () => {
    explode()
})

// wait() returns a PromiseLike that can be used with await
await wait(1)

loop(t: number, action: () => void): EventController

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",
    ])
})

TimerController:

paused: boolean

If the event handler is paused.

cancel(): void

Cancel the event handler.

onEnd(action: () => void): void

Register an event when finished.

then(action: () => void): TimerController

TweenController: TimerController &

finish(): void

Finish the tween now and cancel.

Event controller for tween.

Vec2:

A 2D vector.

x: number

The x coordinate

y: number

The y coordinate

fromAngle(deg: number): Vec2

Create a new Vec2 from an angle in degrees

UP: Vec2

clone(): Vec2

Clone the vector

add(args: Vec2Args): Vec2

Returns the addition with another vector.

sub(args: Vec2Args): Vec2

Returns the subtraction with another vector.

scale(args: Vec2Args): Vec2

Scale by another vector. or a single number

dist(args: Vec2Args): number

Get distance between another vector

sdist(args: Vec2Args): number

Get squared distance between another vector

len(): number

slen(): number

Get squared length of the vector

since v3000.0

unit(): Vec2

Get the unit vector (length of 1).

normal(): Vec2

Get the perpendicular vector.

reflect(normal: Vec2): Vec2

Get the reflection of a vector with a normal.

since v3000.0

project(on: Vec2): Vec2

Get the projection of a vector onto another vector.

since v3000.0

reject(on: Vec2): Vec2

Get the rejection of a vector onto another vector.

since v3000.0

dot(p2: Vec2): number

Get the dot product with another vector.

cross(p2: Vec2): number

Get the cross product with another vector.

since v3000.0

angle(args: Vec2Args): number

Get the angle of the vector in degrees.

angleBetween(args: Vec2Args): number

Get the angle between this vector and another vector.

since v3000.0

lerp(dest: Vec2, t: number): Vec2

Linear interpolate to a destination vector (for positions).

slerp(dest: Vec2, t: number): Vec2

Spherical linear interpolate to a destination vector (for rotations).

since v3000.0

isZero(): boolean

If the vector (x, y) is zero.

since v3000.0

toFixed(n: number): Vec2

To n precision floating point.

transform(m: Mat4): Vec2

Multiply by a Mat4.

since v3000.0

eq(other: Vec2): boolean

ShapeType: Vec2 | Circle | Line | Rect | Polygon | Ellipse

raycast(origin: Vec2, direction: Vec2, exclude?: string[]): RaycastResult

rand(): number

Get a random number between 0 - 1.

rand<T>(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<T>(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(n: number): number

rand() but floored to integer.

randi(10) // returns 0 to 9

randi(a: number, b: number): number

rand() but floored to integer.

randi(0, 3) // returns 0, 1, or 2

randi(): number

rand() but floored to integer.

randi() // returns either 0 or 1

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

rgb(r: number, g: number, b: number): Color$1

Create a color from RGB values (0 - 255).

// update the color of the sky to light blue
sky.color = rgb(0, 128, 255)

rgb(hex: string): Color$1

Create a color from hex string.

since v3001.0

sky.color = rgb("#ef6360")

rgb(): Color$1

Same as rgb(255, 255, 255).

hsl2rgb(hue: number, saturation: number, lightness: number): Color$1

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$1

Rectangle area (0.0 - 1.0).

choose<T>(lst: T[]): T

Choose a random item from a list.

// decide the best fruit randomly
const bestFruit = choose(["apple", "banana", "pear", "watermelon"])

chooseMultiple<T>(lst: T[], count: number): T[]

Choose multiple random items from a list.

since v3001.0

shuffle<T>(lst: T[]): T[]

Shuffle an array.

since v3001.0

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<V>(from: V, to: V, t: number): V

Linear interpolation.

tween<V>(from: V, to: V, duration: number, setValue: (value: V) => void, easeFunc?: (t: number) => number): TweenController

Tweeeeeeeening!

since v3000.0

// tween bean to mouse position
tween(bean.pos, mousePos(), 1, (p) => bean.pos = p, easings.easeOutBounce)

// tween() returns a then-able that can be used with await
await tween(bean.opacity, 1, 0.5, (val) => bean.opacity = val, easings.easeOutQuad)

easings: Record<EaseFuncs, EaseFunc>

A collection of easing functions for tweening.

since v3000.0

easingSteps(steps: number, position: StepPosition): any

Steps easing. Eases in discontinious steps.

since v3001.0

easingLinear(keys: Vec2[]): any

Linear easing with keyframes

since v3001.0

easingCubicBezier(p1: Vec2, p2: Vec2): any

Bezier easing. Both control points need x to be within 0 and 1.

since v3001.0

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.

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.

clamp(n: number, min: number, max: number): number

Return a value clamped to an inclusive range of min and max.

evaluateQuadratic(pt1: Vec2, pt2: Vec2, pt3: Vec2, t: number): Vec2

Evaluate the quadratic Bezier at the given t

evaluateQuadraticFirstDerivative(pt1: Vec2, pt2: Vec2, pt3: Vec2, t: number): Vec2

Evaluate the first derivative of a quadratic bezier at the given t

since v3001.0

evaluateQuadraticSecondDerivative(pt1: Vec2, pt2: Vec2, pt3: Vec2, t: number): Vec2

Evaluate the second derivative of a quadratic bezier at the given t

since v3001.0

evaluateBezier(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, t: number): Vec2

Evaluate the cubic Bezier at the given t

since v3001.0

evaluateBezierFirstDerivative(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, t: number): Vec2

Evaluate the first derivative of a cubic Bezier at the given t

evaluateBezierSecondDerivative(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, t: number): Vec2

Evaluate the second derivative of a cubic bezier at the given t

since v3001.0

evaluateCatmullRom(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, t: number): Vec2

Evaluate the Catmull-Rom spline at the given t

since v3001.0

evaluateCatmullRomFirstDerivative(pt1: Vec2, pt2: Vec2, pt3: Vec2, pt4: Vec2, t: number): Vec2

Evaluate the first derivative of a Catmull-Rom spline at the given t

since v3001.0

curveLengthApproximation(curve: (t: number) => Vec2, entries: number, detail: number): number

Returns a function. entries is the amount of entries in the LUT. detail is the sampling granularity of each segment recorded in the LUT. This new function either returns the length for a given t, or t for a given length, depending on the inverse parameter.

since v3001.0

normalizedCurve(curve: (t: number) => Vec2): Vec2

Returns a new curve which is normalized. This new curve has constant speed curve is any curve in t (non-constant between 0 and 1) returns a curve in s (constant between 0 and 1)

since v3001.0

testLinePoint(l: Line$1, pt: Vec2): boolean

Check if a line and a point intersect.

testLineLine(l1: Line$1, l2: Line$1): Vec2 | null

Check if 2 lines intersects, if yes returns the intersection point.

testLineCircle(l: Line$1, circle: Circle$1): boolean

Check if a line and a circle intersect.

testRectRect(r1: Rect$1, r2: Rect$1): boolean

Check if 2 rectangle overlaps.

testRectLine(r: Rect$1, l: Line$1): boolean

Check if a line and a rectangle overlaps.

testRectPoint(r: Rect$1, pt: Point): boolean

Check if a point is inside a rectangle.

testCirclePolygon(c: Circle$1, p: Polygon$1): boolean

Check if a circle and polygon intersect linewise.

Vec2:

A 2D vector.

x: number

The x coordinate

y: number

The y coordinate

fromAngle(deg: number): Vec2

Create a new Vec2 from an angle in degrees

UP: Vec2

clone(): Vec2

Clone the vector

add(args: Vec2Args): Vec2

Returns the addition with another vector.

sub(args: Vec2Args): Vec2

Returns the subtraction with another vector.

scale(args: Vec2Args): Vec2

Scale by another vector. or a single number

dist(args: Vec2Args): number

Get distance between another vector

sdist(args: Vec2Args): number

Get squared distance between another vector

len(): number

slen(): number

Get squared length of the vector

since v3000.0

unit(): Vec2

Get the unit vector (length of 1).

normal(): Vec2

Get the perpendicular vector.

reflect(normal: Vec2): Vec2

Get the reflection of a vector with a normal.

since v3000.0

project(on: Vec2): Vec2

Get the projection of a vector onto another vector.

since v3000.0

reject(on: Vec2): Vec2

Get the rejection of a vector onto another vector.

since v3000.0

dot(p2: Vec2): number

Get the dot product with another vector.

cross(p2: Vec2): number

Get the cross product with another vector.

since v3000.0

angle(args: Vec2Args): number

Get the angle of the vector in degrees.

angleBetween(args: Vec2Args): number

Get the angle between this vector and another vector.

since v3000.0

lerp(dest: Vec2, t: number): Vec2

Linear interpolate to a destination vector (for positions).

slerp(dest: Vec2, t: number): Vec2

Spherical linear interpolate to a destination vector (for rotations).

since v3000.0

isZero(): boolean

If the vector (x, y) is zero.

since v3000.0

toFixed(n: number): Vec2

To n precision floating point.

transform(m: Mat4): Vec2

Multiply by a Mat4.

since v3000.0

eq(other: Vec2): boolean

Quad:

x: number

y: number

w: number

h: number

scale(other: Quad): Quad

eq(other: Quad): boolean

Vec2Args: TupleType | TupleType | TupleType | TupleType | TupleType

Color$1:

0-255 RGBA color.

r: number

Red (0-255).

g: number

Green (0-255).

b: number

Blue (0-255).

fromHSL(h: number, s: number, l: number): Color$1

fromHex(hex: number | string): Color$1

Create color from hex string or literal.

since v3000.0

Color.fromHex(0xfcef8d)
Color.fromHex("#5ba675")
Color.fromHex("d46eb3")

lighten(n: number): Color$1

Lighten the color (adds RGB by n).

darken(n: number): Color$1

Darkens the color (subtracts RGB by n).

mult(other: Color$1): Color$1

lerp(dest: Color$1, t: number): Color$1

Linear interpolate to a destination color.

since v3000.0

eq(c: Color$1): boolean

toHSL(): TupleType

Convert color into HSL format.

since v3001.0

toHex(): string

Return the hex string of color.

since v3000.0

toArray(): Array<number>

Return the color converted to an array.

since v3001.0

Quad$1:

x: number

y: number

w: number

h: number

scale(q: Quad$1): Quad$1

eq(q: Quad$1): boolean

UniformValue: number | Vec2 | Color$1 | Mat4$1 | number[] | Vec2[] | Color$1[]

Uniform: Record<UniformKey, UniformValue>

Edge: left | right | top | bottom

EaseFuncs: linear | easeInSine | easeOutSine | easeInOutSine | easeInQuad | easeOutQuad | easeInOutQuad | easeInCubic | easeOutCubic | easeInOutCubic | easeInQuart | easeOutQuart | easeInOutQuart | easeInQuint | easeOutQuint | easeInOutQuint | easeInExpo | easeOutExpo | easeInOutExpo | easeInCirc | easeOutCirc | easeInOutCirc | easeInBack | easeOutBack | easeInOutBack | easeInElastic | easeOutElastic | easeInOutElastic | easeInBounce | easeOutBounce | easeInOutBounce

The list of easing functions available.

EaseFunc(t: number): number

A function that takes a time value and returns a new time value.

Quad:

x: number

y: number

w: number

h: number

scale(other: Quad): Quad

eq(other: Quad): boolean

GfxCtx: ReturnType<TypeQuery>

initGfx(gl: WebGLRenderingContext, opts?: ):

gl: WebGLRenderingContext

EventHandler<EventMap>:

on<Name>(name: Name, action: (args: EventMap[Name]) => void): EventController

onOnce<Name>(name: Name, action: (args: EventMap[Name]) => void): EventController

next<Name>(name: Name): Promise<UnknownKeyword>

trigger<Name>(name: Name, args: EventMap[Name]): void

remove<Name>(name: Name): void

AreaCompOpt:

Options for the area() component.

shape?: Shape

The shape of the area (currently only Rect and Polygon is supported).

add([
    sprite("butterfly"),
    pos(100, 200),
    // a triangle shape!
    area({ shape: new Polygon([vec2(0), vec2(100), vec2(-100, 100)]) }),
])

scale?: number | Vec2

Area scale.

cursor?: Cursor

Cursor on hover.

collisionIgnore?: Tag[]

If this object should ignore collisions against certain other objects.

since v3000.0

addKaboom(pos: Vec2, opt?: BoomOpt): GameObj

Add an explosion

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$1

Red color.

GREEN: Color$1

Green color.

BLUE: Color$1

Blue color.

YELLOW: Color$1

Yellow color.

CYAN: Color$1

Cyan color.

WHITE: Color$1

White color.

BLACK: Color$1

Black color.

canvas: HTMLCanvasElement

The canvas DOM KAPLAY is currently using.

MergeObj<T>: Expand<UnionToIntersection<Defined<T>>>

GamepadDef:

buttons: Record<string, GamepadButton$1>

sticks: Partial<Record<GamepadStick,

x: number

y: number

>
>

A gamepad definition.

ButtonsDef: Record<string, ButtonBinding>

A buttons definition.

KGamePad:

index: number

The order of the gamepad in the gamepad list.

isPressed(b: GamepadButton$1): boolean

If certain button is pressed.

isDown(b: GamepadButton$1): boolean

If certain button is held down.

isReleased(b: GamepadButton$1): boolean

If certain button is released.

getStick(stick: GamepadStick): Vec2

Get the value of a stick.

A KAPLAY's gamepad

StepPosition: jump-start | jump-end | jump-none | jump-both

GameObjInspect: Record<Tag, string | null>

Inspect info for a game object.

SpriteAnim: 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.

Frame-based animation configuration.

SpriteAnimPlayOpt:

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.

SpriteAnims: Record<string, SpriteAnim>

A dict of name <-> animation.

LoadSpriteOpt:

Sprite loading configuration.

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.

slice9?: NineSlice

9 slice sprite for proportional scaling.

since v3000.0

frames?: Quad$1[]

Individual frames.

since v3000.0

anims?: SpriteAnims

Animation configuration.

NineSlice:

left: number

The width of the 9-slice's left column.

right: number

The width of the 9-slice's right column.

top: number

The height of the 9-slice's top row.

bottom: number

The height of the 9-slice's bottom row.

SpriteAtlasEntry: LoadSpriteOpt &

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.

A sprite in a sprite atlas.

SpriteData:

tex: Texture$1

width: number

since v3001.0

height: number

since v3001.0

from(src: LoadSpriteSrc, opt?: LoadSpriteOpt): Promise<SpriteData>

fromImage(data: ImageSource, opt?: LoadSpriteOpt): SpriteData

fromURL(url: string, opt?: LoadSpriteOpt): Promise<SpriteData>

AudioPlayOpt:

Audio play configurations.

paused?: boolean

If audio should start out paused.

since v3000.0

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.

AudioPlay:

play(time?: number): void

Start playing audio.

since v3000.0

seek(time: number): void

Seek time.

since v3000.0

stop(): void

Stop the sound.

since v3001.0

paused: boolean

If the sound is paused.

since v2000.1

speed: number

Playback speed of the sound. 1.0 means normal playback speed, 2.0 means twice as fast.

detune: number

Detune the sound. Every 100 means a semitone.

// tune down a semitone
music.detune = -100

// tune up an octave
music.detune = 1200

volume: number

Volume of the sound. 1.0 means full volume, 0.5 means half volume.

loop: boolean

If the audio should start again when it ends.

time(): number

The current playing time (not accurate if speed is changed).

duration(): number

The total duration.

onEnd(action: () => void): EventController

Register an event that runs when audio ends.

since v3000.0

then(action: () => void): EventController

Texture$1:

ctx: GfxCtx$1

src: null | ImageSource

fromImage(ctx: GfxCtx$1, img: ImageSource, opt?: TextureOpt): Texture$1

update(img: ImageSource, x?: number, y?: number): any

free(): void

Frees up texture memory. Call this once the texture is no longer being used to avoid memory leaks.

TexFilter: nearest | linear

Texture scaling filter. "nearest" is mainly for sharp pixelated scaling, "linear" means linear interpolation.

DrawSpriteOpt: RenderProps &

sprite: string | SpriteData | Asset<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$1

The sub-area to render from the texture, by default it'll render the whole `quad(0, 0, 1, 1)`

anchor?: Anchor | Vec2

The anchor point, or the pivot point. Default to "topleft".

How the sprite should look like.

DrawUVQuadOpt: 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?: Texture$1

The texture to sample for this quad.

quad?: Quad$1

The texture sampling area.

anchor?: Anchor | Vec2

The anchor point, or the pivot point. Default to "topleft".

DrawRectOpt: RenderProps &

width: number

Width of the rectangle.

height: number

Height of the rectangle.

gradient?: TupleType

Use gradient instead of solid color.

since v3000.0

horizontal?: boolean

If the gradient should be horizontal.

since v3000.0

fill?: boolean

If fill the shape with color (set this to false if you only want an outline).

radius?: number | number[]

The radius of each corner.

anchor?: Anchor | Vec2

The anchor point, or the pivot point. Default to "topleft".

How the rectangle should look like.

DrawLineOpt: 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,

How the line should look like.

LineJoin: none | round | bevel | miter

DrawLinesOpt: 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 | number[]

The radius of each corner.

join?: LineJoin

Line join style (default "none").

cap?: LineCap

Line cap style (default "none").

miterLimit?: number

Maximum miter length, anything longer becomes bevel.

How the lines should look like.

DrawBezierOpt: DrawCurveOpt &

pt1: Vec2

The first point.

pt2: Vec2

The the first control point.

pt3: Vec2

The the second control point.

pt4: Vec2

The second point.

DrawTriangleOpt: RenderProps &

p1: Vec2

First point of triangle.

p2: Vec2

Second point of triangle.

p3: Vec2

Third point of triangle.

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.

How the triangle should look like.

DrawCircleOpt: Omit<RenderProps, angle> &

radius: number

Radius of the circle.

start?: number

Starting angle.

fill?: boolean

If fill the shape with color (set this to false if you only want an outline).

gradient?: TupleType

Use gradient instead of solid color.

since v3000.0

resolution?: number

Multiplier for circle vertices resolution (default 1)

anchor?: Anchor | Vec2

The anchor point, or the pivot point. Default to "topleft".

How the circle should look like.

DrawEllipseOpt: RenderProps &

radiusX: number

The horizontal radius.

radiusY: number

The vertical radius.

start?: number

Starting angle.

fill?: boolean

If fill the shape with color (set this to false if you only want an outline).

gradient?: TupleType

Use gradient instead of solid color.

since v3000.0

resolution?: number

Multiplier for circle vertices resolution (default 1)

anchor?: Anchor | Vec2

The anchor point, or the pivot point. Default to "topleft".

How the ellipse should look like.

DrawPolygonOpt: RenderProps &

pts: Vec2[]

The points that make up the polygon

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 | number[]

The radius of each corner.

colors?: Color$1[]

The color of each vertex.

since v3000.0

uv?: Vec2[]

The uv of each vertex.

since v3001.0

tex?: Texture$1

The texture if uv are supplied.

since v3001.0

triangulate?: boolean

Triangulate concave polygons.

since v3001.0

How the polygon should look like.

Outline:

width?: number

The width, or thinkness of the line.

color?: Color$1

The color of the line.

opacity?: number

Opacity (overrides fill opacity).

since v3001.0

join?: LineJoin

Line join.

since v3000.0

miterLimit?: number

Miter limit. If the length of the miter divided by the line width exceeds this limit, the style is converted to a bevel.

since v3001.0

cap?: LineCap

Line cap.

since v3001.0

CharTransformFunc(idx: number, ch: string): CharTransform

A function that returns a character transform config. Useful if you're generating dynamic styles.

Mask: intersect | subtract

play(src: string | SoundData | Asset<SoundData> | MusicData | Asset<MusicData>, 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.paused = true
music.speed = 1.2

burp(options?: AudioPlayOpt): AudioPlay

Yep. Plays a burp sound.

volume(v?: number): number

Sets global volume.

// makes everything quieter
volume(0.5)

audioCtx: AudioContext

Get the underlying browser AudioContext.

addLevel(map: string[], options: LevelOpt): GameObj

Construct a level based on symbols.

addLevel([
    "                          $",
    "                          $",
    "           $$         =   $",
    "  %      ====         =   $",
    "                      =    ",
    "       ^^      = >    =   &",
    "===========================",
], {
    // define the size of tile block
    tileWidth: 32,
    tileHeight: 32,
    // define what each symbol means, by a function returning a component list (what will be passed to add())
    tiles: {
        "=": () => [
            sprite("floor"),
            area(),
            solid(),
        ],
        "$": () => [
            sprite("coin"),
            area(),
            pos(0, -9),
        ],
        "^": () => [
            sprite("spike"),
            area(),
            "danger",
        ],
    }
})

getData<T>(key: string, def?: T): T

Get data from local storage, if not present can set to a default value.

setData(key: string, data: any): void

Set data from local storage.

screenshot(): string

Take a screenshot and get the dataurl of the image.

returns The dataURL of the image.

download(filename: string, dataurl: string): void

Trigger a file download from a url.

since v3000.0

downloadText(filename: string, text: string): void

Trigger a text file download.

since v3000.0

downloadJSON(filename: string, data: any): void

Trigger a json download from a .

since v3000.0

downloadBlob(filename: string, blob: Blob): void

Trigger a file download from a blob.

since v3000.0

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

Recording:

Screen recording control handle.

pause(): void

Pause the recording.

resume(): void

Resume the recording.

stop(): Promise<Blob>

Stop the recording and get the video data as mp4 Blob.

since v3000.0

download(filename?: string): void

Stop the recording and downloads the file as mp4. Trying to resume later will lead to error.

drawSprite(options: DrawSpriteOpt): void

Draw a sprite.

drawSprite({
    sprite: "bean",
    pos: vec2(100, 200),
    frame: 3,
})

drawText(options: DrawTextOpt): void

Draw a piece of text.

drawText({
    text: "oh hi",
    size: 48,
    font: "sans-serif",
    width: 120,
    pos: vec2(100, 200),
    color: rgb(0, 0, 255),
})

drawRect(options: DrawRectOpt): void

Draw a rectangle.

drawRect({
    width: 120,
    height: 240,
    pos: vec2(20, 20),
    color: YELLOW,
    outline: { color: BLACK, width: 4 },
})

drawLine(options: DrawLineOpt): void

Draw a line.

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

drawLines(options: DrawLinesOpt): void

Draw lines.

drawLines({
    pts: [ vec2(0), vec2(0, height()), mousePos() ],
    width: 4,
    pos: vec2(100, 200),
    color: rgb(0, 0, 255),
})

drawCurve(curve: (t: number) => Vec2, opt: DrawCurveOpt): void

Draw a curve.

drawCurve(t => evaluateBezier(a, b, c, d, t)
{
    width: 2,
    color: rgb(0, 0, 255),
})

drawBezier(opt: DrawBezierOpt): void

Draw a cubic Bezier curve.

drawBezier({
    pt1: vec2(100, 100),
    pt2: vec2(200, 100),
    pt3: vec2(200, 200),
    pt4: vec2(100, 200),
    width: 2,
    color: GREEN
})

drawTriangle(options: DrawTriangleOpt): void

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): void

Draw a circle.

drawCircle({
    pos: vec2(100, 200),
    radius: 120,
    color: rgb(255, 255, 0),
})

drawEllipse(options: DrawEllipseOpt): void

Draw an ellipse.

drawEllipse({
    pos: vec2(100, 200),
    radiusX: 120,
    radiusY: 120,
    color: rgb(255, 255, 0),
})

drawPolygon(options: DrawPolygonOpt): void

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): void

Draw a rectangle with UV data.

drawFormattedText(text: FormattedText): void

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)

drawMasked(content: () => void, mask: () => void): void

Whatever drawn in content will only be drawn if it's also drawn in mask (mask will not be rendered).

since v3000.0

drawSubtracted(content: () => void, mask: () => void): void

Subtract whatever drawn in content by whatever drawn in mask (mask will not be rendered).

since v3000.0

pushTransform(): void

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("bean")
drawCircle(vec2(0), 120)

// restore the transformation stack to when last pushed
popTransform()

popTransform(): void

Pop the topmost transform matrix from the transform stack.

pushTranslate(x: number, y: number): void

Translate all subsequent draws.

pushTranslate(100, 100)

// this will be drawn at (120, 120)
drawText({
    text: "oh hi",
    pos: vec2(20, 20),
})

pushScale(x: number, y: number): void

Scale all subsequent draws.

pushRotate(angle: number): void

Rotate all subsequent draws.

pushMatrix(mat: Mat4$1): void

Apply a transform matrix, ignore all prior transforms.

since v3000.0

usePostEffect(name: string, uniform?: Uniform | () => Uniform): void

Apply a post process effect from a shader name.

since v3000.0

loadShader("invert", null, `
vec4 frag(vec2 pos, vec2 uv, vec4 color, sampler2D tex) {
    vec4 c = def_frag();
    return vec4(1.0 - c.r, 1.0 - c.g, 1.0 - c.b, c.a);
}
`)

usePostEffect("invert")

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)

makeCanvas(w: number, h: number): Canvas

Create a canvas to draw stuff offscreen.

since v3001.0

TextAlign: center | left | right

How the text should be aligned.

DrawTextOpt: RenderProps &

text: string

The text to render.

font?: string | FontData | Asset<FontData> | BitmapFontData | Asset<BitmapFontData>

The name of font to use.

size?: number

The size of text (the height of each character).

align?: TextAlign

Text alignment (default "left")

since v3000.0

width?: number

The maximum width. Will wrap word around if exceed.

lineSpacing?: number

The gap between each line (only available for bitmap fonts).

since v2000.2

letterSpacing?: number

The gap between each character (only available for bitmap fonts).

since v2000.2

anchor?: Anchor | Vec2

The anchor 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 (only available for bitmap fonts).

since v2000.1

styles?: Record<string, CharTransform | CharTransformFunc>

Stylesheet for styled chunks, in the syntax of "this is a [stylename]styled[/stylename] word" (only available for bitmap fonts).

since v2000.2

How the text should look like.

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

Anchor: topleft | top | topright | left | center | right | botleft | bot | botright

Shape: Rect$1 | Line$1 | Point | Circle$1 | Ellipse$1 | Polygon$1

debug: Debug

The Debug interface for debugging stuff.

// pause the whole game
debug.paused = true

// enter inspect mode
debug.inspect = true

Debug:

paused: boolean

Pause the whole game.

inspect: boolean

Draw bounding boxes of all objects with `area()` component, hover to inspect their states.

showLog: boolean

Show the debug log or not.

fps(): number

Current frames per second.

numFrames(): number

Total number of frames elapsed.

since v3000.0

drawCalls(): number

Number of draw calls made last frame.

stepFrame(): void

Step to the next frame. Useful with pausing.

log(msg: string | ): void

Log some text to on screen debug log.

error(msg: string | ): void

Log an error message to on screen debug log.

curRecording: Recording | null

The recording handle if currently in recording mode.

since v2000.1

numObjects(): number

Get total number of objects.

since v3001.0

plug<T>(plugin: KaboomPlugin<T>): KaboomCtx & T

Import a plugin.

KaboomPlugin<T>(k: KaboomCtx): T | (args: any) => (k: KaboomCtx) => T

A plugin for KAPLAY.

// a plugin that adds a new function to KAPLAY
const myPlugin = (k) => ({
   myFunc: () => {
      k.debug.log("hello from my plugin")
  }
})

// use the plugin
kaplay({
  plugins: [ myPlugin ]
})

// now you can use the new function
myFunc()

GetOpt:

recursive?: boolean

Recursively get all children and their descendents.

liveUpdate?: boolean

Live update the returned list every time object is added / removed.

QueryOpt:

include?: string | string[]

All objects which include all or any of these tags, depending on includeOp.

includeOp?: and | or

Selects the operator to use. Defaults to and.

exclude?: string | string[]

All objects which do not have all or any of these tags, depending on excludeOp.

excludeOp?: and | or

Selects the operator to use. Defaults to and.

distance?: number

All objects which are near or far to the position of this, depending on distanceOp.

distanceOp?: near | far

Selects the operator to use. Defaults to near.

visible?: boolean

All objects visible from this standpoint.

hierarchy?: children | siblings | ancestors | descendants

All objects in the given group. Defaults to children.

LevelOpt:

pos?: Vec2

Position of the first block.

tiles:

Definition of each tile.

wildcardTile?(sym: string, pos: Vec2): CompList<any> | null | undefined

Called when encountered a symbol not defined in "tiles".

BoomOpt:

speed?: number

Animation speed.

comps?: CompList<any>

Additional components.

since v3000.0