User Interface
Build interactive UI elements like buttons, text, and progress bars.
Global Theme
js
// Override any theme value globally — all elements inherit
game.ui.theme.set({
primaryColor: "#e63946",
fontFamily: "Press Start 2P, monospace",
fontSize: 12,
borderRadius: 4,
backgroundColor: "#0a0a1a",
});
// Reset to built-in defaults
game.ui.theme.reset();
UIPanel — container / background box
js
import { UIPanel } from "kernelplay-js"; // Assuming UIPanel is exported from main library
const panel = game.ui.add(new UIPanel({
anchor: "center",
offset: { x: 0, y: 0 },
width: 300,
height: 200,
zIndex: 0,
// per-element style overrides
style: {
surfaceColor: "#1a1a2e",
borderColor: "#e63946",
borderWidth: 2,
borderRadius: 12,
},
}));
// hide / show
panel.visible = false;
panel.visible = true;
UIText — label
js
import { UIText } from "kernelplay-js"; // Assuming UIText is exported from main library
const label = game.ui.add(new UIText({
text: "Score: 0",
anchor: "topLeft",
offset: { x: 20, y: 20 },
style: {
textColor: "#ffffff",
fontSize: 18,
fontWeight: "bold",
},
}));
// update text every frame
label.text = `Score: ${this.score}`;
UIButton — clickable button
js
import { UIButton } from "kernelplay-js"; // Assuming UIButton is exported from main library
const btn = game.ui.add(new UIButton({
label: "Play",
anchor: "center",
offset: { x: 0, y: 0 },
width: 160,
height: 48,
zIndex: 1,
style: {
primaryColor: "#4a90e2",
hoverColor: "#5aa0f2",
pressColor: "#3a80d2",
fontSize: 16,
fontWeight: "bold",
},
}));
btn.onClick = () => {
console.log("Play clicked!");
game.sceneManager.startScene("Game");
};
// disable button
btn.disabled = true;
// re-enable
btn.disabled = false;
UIImage — sprite / icon
js
import { UIImage } from "kernelplay-js"; // Assuming UIImage is exported from main library
const icon = game.ui.add(new UIImage({
src: "./assets/health_icon.png",
anchor: "topLeft",
offset: { x: 10, y: 10 },
width: 32,
height: 32,
}));
UIProgressBar — health bar / loading bar
js
import { UIProgressBar } from "kernelplay-js"; // Assuming UIProgressBar is exported from main library
const healthBar = game.ui.add(new UIProgressBar({
value: 1.0, // 1.0 = full
direction: "left", // fills left → right
anchor: "topLeft",
offset: { x: 20, y: 20 },
width: 200,
height: 20,
showText: false,
style: {
progressTrackColor: "#333350",
progressFillColor: "#e74c3c", // red health bar
borderRadius: 10,
},
}));
// update when player takes damage
healthBar.setValue(this.health / this.maxHealth);
// other directions
const chargeBar = game.ui.add(new UIProgressBar({
value: 0,
direction: "left", // "left" | "right" | "up" | "down"
anchor: "bottomCenter",
offset: { x: 0, y: 20 },
width: 120,
height: 12,
style: { progressFillColor: "#f39c12" },
}));
chargeBar.setValue(this.charge / this.maxCharge);
UICheckbox — toggle option
js
import { UICheckbox } from "kernelplay-js"; // Assuming UICheckbox is exported from main library
const sfxToggle = game.ui.add(new UICheckbox({
label: "Sound Effects",
checked: true,
anchor: "center",
offset: { x: 0, y: -20 },
width: 200,
height: 30,
}));
sfxToggle.onChange = (checked) => {
game.audio.setSFXVolume(checked ? 1 : 0);
};
UISlider — volume / sensitivity control
js
import { UISlider } from "kernelplay-js"; // Assuming UISlider is exported from main library
const volumeSlider = game.ui.add(new UISlider({
value: 0.8,
min: 0,
max: 1,
showValue: true,
anchor: "center",
offset: { x: 0, y: 40 },
width: 220,
height: 30,
}));
volumeSlider.onChange = (value) => {
game.audio.setMasterVolume(value);
};
UIInputField — text input
js
import { UIInputField } from "kernelplay-js"; // Assuming UIInputField is exported from main library
const nameField = game.ui.add(new UIInputField({
placeholder: "Enter your name...",
value: "",
maxLength: 20,
anchor: "center",
offset: { x: 0, y: 0 },
width: 260,
height: 42,
}));
nameField.onChange = (value) => console.log("Typing:", value);
nameField.onSubmit = (value) => {
console.log("Name submitted:", value);
savePlayerName(value);
};
// password field
const passField = game.ui.add(new UIInputField({
placeholder: "Password",
password: true,
anchor: "center",
offset: { x: 0, y: 60 },
width: 260,
height: 42,
}));
UIImageButton — three modes
js
// 1. Image background + label (menu button with art)
import { UIImageButton } from "kernelplay-js"; // Assuming UIImageButton is exported from main library
new UIImageButton({ src: "./assets/btn.png", label: "Play" })
// 2. Icon only — label: null
new UIImageButton({ src: "./assets/settings_icon.png", label: null })
// 3. Sprite sheet states — different region per state
new UIImageButton({
src: "./assets/btn_sheet.png",
states: {
normal: { x: 0, y: 0, w: 160, h: 60 },
hover: { x: 160, y: 0, w: 160, h: 60 },
press: { x: 320, y: 0, w: 160, h: 60 },
disabled: { x: 480, y: 0, w: 160, h: 60 },
}
})
UIBitmapText
js
import { UIBitmapText } from "kernelplay-js"; // Assuming UIBitmapText is exported from main library
const score = game.ui.add(new UIBitmapText({
src: "./assets/font.png",
text: "SCORE: 0",
charWidth: 8, // one char cell on sheet
charHeight: 8,
sheetCols: 16, // chars per row on sheet
charOffset: 32, // ASCII 32 = space = first char
scale: 3, // render 3x bigger
spacing: 1,
anchor: "topLeft",
offset: { x: 20, y: 20 },
tint: "#ffdd00", // optional color tint
}));
// update text
score.setText(`SCORE: ${this.score}`);
// change tint at runtime
score.setTint("#ff0000");
score.clearTint();
World Space UI — label above an enemy
js
import { UIText } from "kernelplay-js"; // Assuming UIText is exported from main library
// screenSpace: false → position is in world coords, moves with camera
const nameTag = game.ui.add(new UIText({
text: "Boss",
screenSpace: false,
offset: { x: enemy.transform.position.x, y: enemy.transform.position.y - 60 },
style: { textColor: "#e74c3c", fontSize: 12 },
}));
// update world position every frame in your script
update(dt) {
nameTag.offset.x = this.transform.position.x;
nameTag.offset.y = this.transform.position.y - 60;
}
UIRaycast — skip game input when UI is hit
js
// In your game's input handling — check UI first
import { Mouse, MouseButton } from "kernelplay-js";
update(dt) {
if (Mouse.wasPressed(MouseButton.Left)) {
// don't fire game raycast if UI consumed the click
if (game.ui.raycast.isUIAt(Mouse.x, Mouse.y)) return;
const hit = this.raycast(worldPos.x, worldPos.y);
if (hit) console.log("Hit:", hit.entity.name);
}
}
Find elements by name
js
// find by name set in constructor
const btn = game.ui.find("UIButton");
// update it
btn.label = "Restart";
btn.onClick = () => restartGame();
// remove it
game.ui.remove(btn);
// clear all UI
game.ui.clear();
Full HUD example — health + score + pause button
js
import { UIText, UIProgressBar, UIButton, UIPanel } from "kernelplay-js"; // Assuming these are exported from main library
class HUD {
constructor(game) {
this.ui = game.ui;
// health bar
this.healthBar = this.ui.add(new UIProgressBar({
anchor: "topLeft",
offset: { x: 20, y: 20 },
width: 200,
height: 18,
style: { progressFillColor: "#e74c3c" },
}));
// health label
this.ui.add(new UIText({
text: "HP",
anchor: "topLeft",
offset: { x: 20, y: 48 },
style: { fontSize: 11, textColor: "#aaaacc", textAlign: "left" },
}));
// score
this.scoreLabel = this.ui.add(new UIText({
text: "Score: 0",
anchor: "topRight",
offset: { x: 20, y: 20 },
style: { fontSize: 16, fontWeight: "bold", textAlign: "right" },
}));
// pause button
const pauseBtn = this.ui.add(new UIButton({
label: "⏸",
anchor: "topRight",
offset: { x: 20, y: 60 },
width: 40,
height: 40,
zIndex: 5,
}));
pauseBtn.onClick = () => game.paused = !game.paused;
}
update(player) {
this.healthBar.setValue(player.health / player.maxHealth);
this.scoreLabel.text = `Score: ${player.score}`;
}
}
Anchor reference
text
"topLeft" "topCenter" "topRight"
"middleLeft" "center" "middleRight"
"bottomLeft" "bottomCenter" "bottomRight"
offset: { x, y } —
pixel offset from that anchor point inward.
File structure
text
src/ui/
index.js ← single import for everything
UICanvas.js ← main manager, creates overlay canvas
UITheme.js ← global stylesheet
UIElement.js ← base class
UIRaycast.js ← separate input system
UIElements.js ← UIPanel, UIText, UIButton, UIImage,
UIProgressBar, UICheckbox, UISlider, UIInputField