Przejdź do treści
Biblioteka skilli
Programowanie · Budowanie i kod

excalibur

/excalibur

Wspiera budowę gier przeglądarkowych w Excalibur.js: aktorzy, sceny, fizyka kolizji, animacje, dźwięk, wejście, mapy Tiled, sprite sheety i kamery.

Repozytorium
skills ↗
Licencja
Apache-2.0
Ostatnia zmiana repozytorium
25.10.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
2
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
2
Przestarzałość

Brak sygnałów. Repozytorium zmienione 25.10.2026, bez odwołań do wycofanych modeli i API.

Licencja

Apache-2.0, otwarta: można używać i zmieniać, z zachowaniem licencji i informacji o zmianach.

Co robi i kiedy

Wspiera budowę gier przeglądarkowych w Excalibur.js: aktorzy, sceny, fizyka kolizji, animacje, dźwięk, wejście, mapy Tiled, sprite sheety i kamery.

Oryginalny opis (EN)

Excalibur.js is a TypeScript-first 2D game engine for the browser with actors, scenes, collision physics, animation, sound, input and a Tiled map plugin. Use when the user wants to build or debug a browser game with Excalibur, load Tiled maps, animate sprite sheets, handle keyboard or pointer input, or manage scenes and cameras.

Jak działa

  1. Overview
  2. Instructions
  3. Examples
  4. Guidelines
Sekcje z nagłówków SKILL.md, w oryginale · 206 linii, 1 003 słów
Podgląd SKILL.md
---
name: excalibur
description: >-
  Excalibur.js is a TypeScript-first 2D game engine for the browser with actors, scenes, collision physics, animation, sound, input and a Tiled map plugin. Use when the user wants to build or debug a browser game with Excalibur, load Tiled maps, animate sprite sheets, handle keyboard or pointer input, or manage scenes and cameras.
license: Apache-2.0
compatibility: 'Node.js 22+ for tooling, any modern browser (WebGL), TypeScript 5+'
metadata:
  author: terminal-skills
  version: 1.1.0
  category: development
  repository: https://github.com/excaliburjs/Excalibur
  tags: "game-engine, typescript, 2d, browser-game, webgl"
---

# Excalibur.js — TypeScript-First 2D Game Engine

## Overview

Excalibur is a free, BSD-2-Clause 2D game engine written in TypeScript for browser games. It models a game as an `Engine` running `Scene`s that hold `Actor`s (entities with graphics, collision and actions) and offers a built-in loader, camera, collision and physics, animations, sound, input, and a separate Tiled plugin. This skill targets 0.32.x (`excalibur` and `@excaliburjs/plugin-tiled` 0.32.0 were the latest on npm when checked). The engine is pre-1.0 and breaks APIs between minor versions, so pin the version and read the changelog when upgrading; code written for 0.2x will not compile unchanged.

## Instructions

### Step 1: Install and scaffold

```bash
npm create vite@latest sky-runner -- --template vanilla-ts
cd sky-runner
npm install excalibur
npm install --save-exact @excaliburjs/plugin-tiled   # its peer range is excalibur ~0.32.0, keep both on the same minor
npm run dev
```

Put images and maps in `public/` (for example `public/images/hero.png`, `public/maps/level-1.tmx`) so `/images/hero.png` URLs resolve.

### Step 2: Resources and loader

Every asset, including a Tiled map, must be added to the `Loader` and loaded before use:

```typescript
// src/resources.ts
import { ImageSource, Loader } from "excalibur";
import { TiledResource } from "@excaliburjs/plugin-tiled";

export const Resources = {
  HeroSheet: new ImageSource("/images/hero.png"),
  LevelOne: new TiledResource("/maps/level-1.tmx"),
};

export const loader = new Loader(Object.values(Resources));
```

### Step 3: Engine setup

```typescript
// src/main.ts
import { Engine, DisplayMode, Color } from "excalibur";
import { LevelOne } from "./scenes/LevelOne";
import { loader } from "./resources";

const game = new Engine({
  width: 800,
  height: 600,
  displayMode: DisplayMode.FitScreen,
  backgroundColor: Color.fromHex("#1a1a2e"),
  pixelArt: true,          // crisp pixels, no smoothing
  pixelRatio: 2,
  fixedUpdateFps: 60,      // fixed-step updates for deterministic physics
});

game.addScene("level-one", new LevelOne());
game.start(loader).then(() => game.goToScene("level-one"));
```

### Step 4: Actors, animation and input

```typescript
// src/actors/Player.ts
import { Actor, Animation, CollisionType, Color, Engine, Keys, Side, SpriteSheet, vec } from "excalibur";
import { Resources } from "../resources";

export class Player extends Actor {
  private speed = 200;
  private jumpForce = -400;
  private health = 3;
  private isGrounded = false;

  constructor(x: number, y: number) {
    super({
      pos: vec(x, y),
      width: 16,
      height: 24,
      collisionType: CollisionType.Active,   // moves and collides
      color: Color.Green,
    });
  }

  onInitialize(engine: Engine) {
    const sheet = SpriteSheet.fromImageSource({
      image: Resources.HeroSheet,
      grid: { rows: 4, columns: 6, spriteWidth: 16, spriteHeight: 24 },
    });
    this.graphics.add("idle", Animation.fromSpriteSheet(sheet, [0, 1, 2, 3], 200));
    this.graphics.add("run", Animation.fromSpriteSheet(sheet, [6, 7, 8, 9, 10, 11], 100));
    this.graphics.add("jump", Animation.fromSpriteSheet(sheet, [12, 13], 150));
    this.graphics.use("idle");

    this.on("postcollision", (evt) => {
      if (evt.side === Side.Bottom) this.isGrounded = true;
    });
  }

  onPreUpdate(engine: Engine, elapsedMs: number) {
    const kb = engine.input.keyboard;
    let moving = false;
    if (kb.isHeld(Keys.ArrowLeft)) {
      this.vel.x = -this.speed;
      this.graphics.flipHorizontal = true;
      moving = true;
    } else if (kb.isHeld(Keys.ArrowRight)) {
      this.vel.x = this.speed;
      this.graphics.flipHorizontal = false;
      moving = true;
    } else {
      this.vel.x = 0;
    }

    if (kb.wasPressed(Keys.Space) && this.isGrounded) {
      this.vel.y = this.jumpForce;
      this.isGrounded = false;
      this.graphics.use("jump");
    } else if (this.isGrounded) {
      this.graphics.use(moving ? "run" : "idle");
    }
  }

  takeDamage(amount: number) {
    this.health -= amount;
    this.actions.blink(100, 100, 5);
    if (this.health <= 0) this.scene?.engine.goToScene("game-over");
  }
}
```

Since 0.31 update hooks and events receive `elapsedMs` (milliseconds), not `delta`, and collision events refer to colliders: reach the other entity with `evt.other.owner`.

### Step 5: Scenes, Tiled maps, camera

```typescript
// src/scenes/LevelOne.ts
import { Scene } from "excalibur";
import { Resources } from "../resources";
import { Player } from "../actors/Player";
import { Coin } from "../actors/Coin";

export class LevelOne extends Scene {
  onActivate() {
    const map = Resources.LevelOne;          // already loaded by the Loader
    map.addToScene(this);                    // tile layers, colliders, camera wiring

    const spawn = map.getObjectsByName("PlayerSpawn")[0];
    const player = new Player(spawn.x, spawn.y);
    this.add(player);

    map.getObjectsByClassName("coin").forEach((obj) => this.add(new Coin(obj.x, obj.y)));

    this.camera.strategy.elasticToActor(player, 0.8, 0.9);
    this.camera.zoom = 2;
  }
}
```

Tiled renamed an object's "type" to "class", so the plugin queries are `getObjectsByClassName`, `getObjectsByName` and `getObjectsByProperty`. Look up spawn points defensively: `getObjectsByName` returns an empty array if the name is wrong.

### Step 6: Collision and triggers

```typescript
// src/actors/Coin.ts
import { Actor, CollisionType, Color, vec } from "excalibur";
import { Player } from "./Player";

export class Coin extends Actor {
  constructor(x: number, y: number) {
    super({ pos: vec(x, y), width: 8, height: 8, collisionType: CollisionType.Passive, color: Color.Yellow });
  }
  onInitialize() {
    this.on("collisionstart", (evt) => {
      if (evt.other.owner instanceof Player) this.kill();
    });
  }
}
```

Collision types: `Active` (moves, collides), `Fixed` (static ground), `Passive` (reports overlaps, no physical response), `PreventCollision`.

## Examples

### Example 1: "Start a new platformer project and get a green square moving"

```bash
npm create vite@latest sky-runner -- --template vanilla-ts
cd sky-runner && npm install excalibur && npm run dev
```

Then add Step 3's `main.ts` and `Player` without the sprite sheet code. Result: Vite serves `http://localhost:5173`, the canvas fills the window, and a green 16x24 actor moves with the arrow keys.

### Example 2: "Load my Tiled level and make coins disappear when the hero touches them"

Add `LevelOne: new TiledResource("/maps/level-1.tmx")` to the loader, mark coin objects in Tiled with class `coin`, and use the `LevelOne` scene and `Coin` actor above. Result: the map renders, the camera follows the player, and each coin removes itself on contact. Type-check with `npx tsc --noEmit`; a missing asset shows up as a failed request in the browser console and the loader screen stays up.

## Guidelines

- Put game logic in `onInitialize`, `onPreUpdate` and `onPostUpdate`, not the constructor; the engine and scene are not available yet in the constructor.
- Load every asset through the `Loader`; calling `addToScene` on a Tiled map that has not been loaded fails.
- Keep `excalibur` and `@excaliburjs/plugin-tiled` on the same minor version; mismatches fail at install or runtime.
- Excalibur is pre-1.0: removed or changed APIs appear in each minor release (for example `Timer` takes only an options object, `Vector.normalize()` of a zero vector returns `(0,0)`). Search the CHANGELOG on GitHub before copying older tutorial code.
- Use `engine.goToScene("name", { sceneActivationData })` to pass data between scenes.
- Chain effects with the Actions API: `actor.actions.moveTo(vec(100, 100), 200).delay(500).fade(0, 1000)`.
- For heavy 3D, huge particle counts or a full editor workflow, a larger engine (Phaser, Godot web export) may fit better.
Pliki w paczce (2)
  • SKILL.md 8 KB
  • _scores.json 3 KB

Wersje

W bazie nie ma innych skilli o nazwie excalibur.

Migawka bazy z 28.10.2026 · wersja paczki eaf7963a5af1 (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100phaser
    Pomaga budować gry 2D w przeglądarce we frameworku Phaser: sceny, fizyka Arcade i Matter.js, animacje sprite'ów, mapy kafelkowe, tweeny, cząsteczki i obsługa wejścia.
  • 100kaboom
    Buduje dwuwymiarowe gry przeglądarkowe w JavaScript z Kaboom.js i jego następcą KAPLAY: system encji i komponentów, fizyka, animacje sprite'ów, sceny i poziomy z map ASCII.
  • 100phaser-engineer
    Pomaga budować gry w Phaser 3 z TypeScriptem: sceny, kod rozgrywki, wejście, fizyka Arcade, animacje, dźwięk, tweeny, ładowanie zasobów, zapisy gry i szkielet projektu z Vite.
  • 100game-engine
    Wspiera budowę silników i gier webowych w HTML5, Canvas, WebGL i JavaScript: pętle gry, fizyka, kolizje, sprite'y, sterowanie, dźwięk, multiplayer przez WebRTC i publikacja.
  • 100melonjs-tilemaps
    Obsługuje mapy Tiled w melonJS: ładowanie poziomów TMX i TSX, tworzenie encji z obiektów Tiled, kształty kolizji, mapy izometryczne i heksagonalne, warstwy obrazów oraz kompresowane mapy.
  • 100dragonruby
    Wspiera tworzenie gier 2D w DragonRuby: pętla gry, metoda tick, renderowanie sprite'ów, stan gry, kolizje, animacje i zarządzanie scenami.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.