@tetsup/web2d
v0.0.17
Published
- Minimal setup: only a canvas and a game class required - High-performance rendering via Worker + SharedArrayBuffer - Simple, stateless rendering model for predictable behavior
Downloads
1,269
Readme
web2d - Lightweight 2D Game Runtime for the Web
- Minimal setup: only a canvas and a game class required
- High-performance rendering via Worker + SharedArrayBuffer
- Simple, stateless rendering model for predictable behavior
🌐 Languages
Install
pip install @tetsup/web2dUsage
import { GameApp } from '@tetsup/web2d';
const app = new GameApp(canvas, new TestGame(), {
maxObjects: 10,
rectSize: { width: 320, height: 240 },
keyAssignment,
assignPad,
});GameApp Constructor
new GameApp(
canvas: HTMLCanvasElement,
game: Game,
options?: {
maxObjects?: number;
rectSize?: { width: number; height: number };
keyAssignment?: any;
assignPad?: any;
}
)canvas→ Target<canvas>element for renderinggame→ Instance of a class implementing game logicoptions(optional)maxObjects→ Maximum number of renderable objectsrectSize→ Virtual screen size (internal resolution)keyAssignment→ Keyboard input mappingassignPad→ Gamepad input configuration
🎮 Game Class
You only need to implement the following two methods:
class MyGame {
async onInit(renderer) {}
async onTick(input, clock, renderer) {}
}onInit→ Called once at initializationonTick→ Called every frame
🎮 App Control
Start the application with:
app.start();You can also control the game using the following methods:
Methods
app.start(); // Start game loop and input handling
app.pause(); // Pause
app.advance(n); // Advance simulation by n milliseconds
app.destroy(); // Fully stop and release resourcesDetails
start()
- Starts the game loop and input handling
pause()
- Stops input handling
- Pauses the game loop
advance(delta)
- Advances the game state by
deltamilliseconds - Useful for debugging and deterministic simulation
- Advances the game state by
destroy()
- Stops all processes
- Terminates the Worker
- Should be called when disposing the app
🧩 Renderer API
The renderer is provided as an argument to lifecycle methods.
renderer.registerImage({ imageId, imageData });
renderer.render([{ pos, imageId }]);registerImage(image)
Registers an image for rendering.
renderer.registerImage({
imageId: 'player',
imageData: bitmap,
});imageId: string- Identifier for the image
imageData: ImageBitmap- Transferred to Worker (ownership moves)
⚠️ Notes:
ImageBitmapcannot be reused after transfer- Re-register with a new bitmap to update
render(imageObjects)
Submits objects to be rendered for the current frame.
renderer.render([
{
pos: { x: 100, y: 200 },
imageId: 'player',
},
]);pos: { x: number, y: number }- Position in pixels
imageId: string- Must be registered beforehand
⚠️ Notes:
- Rendering is stateless per frame
- All visible objects must be sent every frame
- Internally optimized using SharedArrayBuffer
🔗 Sample Code
Full example:
👉 https://github.com/tetsup/web2d/tree/main/test-game
