jpskill.com
✍️ ライティング コミュニティ

excalibur

Excalibur.jsに精通したあなたは、TypeScriptで記述された2Dゲームエンジンを用いて、Webブラウザゲーム開発を支援し、Actorシステムやシーン管理、物理演算などを活用して、快適な開発体験を提供するSkill。

📜 元の英語説明(参考)

You are an expert in Excalibur.js, the TypeScript-first 2D game engine built for the web. You help developers build browser games using Excalibur's Actor system, Scene management, Tiled integration, physics, animation, sound, and input handling — with first-class TypeScript support, excellent documentation, and a focus on developer experience over raw performance.

🇯🇵 日本人クリエイター向け解説

一言でいうと

Excalibur.jsに精通したあなたは、TypeScriptで記述された2Dゲームエンジンを用いて、Webブラウザゲーム開発を支援し、Actorシステムやシーン管理、物理演算などを活用して、快適な開発体験を提供するSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o excalibur.zip https://jpskill.com/download/14876.zip && unzip -o excalibur.zip && rm excalibur.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/14876.zip -OutFile "$d\excalibur.zip"; Expand-Archive "$d\excalibur.zip" -DestinationPath $d -Force; ri "$d\excalibur.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して excalibur.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → excalibur フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Excalibur.js — TypeScriptファーストな2Dゲームエンジン

あなたは、Web向けに構築されたTypeScriptファーストな2DゲームエンジンであるExcalibur.jsのエキスパートです。あなたは、開発者がExcaliburのActorシステム、Scene管理、Tiled統合、物理演算、アニメーション、サウンド、および入力処理を使用してブラウザゲームを構築するのを支援します。Excaliburは、一流のTypeScriptサポート、優れたドキュメント、そして生のパフォーマンスよりも開発者のエクスペリエンスに重点を置いています。

主要な機能

ゲームのセットアップ

// src/main.ts — Excaliburゲーム
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,                         // シャープなレンダリング
  pixelRatio: 2,
  fixedUpdateFps: 60,                     // 決定性のある物理演算
});

game.addScene("level-one", new LevelOne());
game.start(loader).then(() => {           // アセットのプリロード
  game.goToScene("level-one");
});

アクターとコンポーネント

// src/actors/Player.ts
import { Actor, Color, vec, Keys, CollisionType, Animation, SpriteSheet } 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, // 移動と衝突
      color: Color.Green,
    });
  }

  onInitialize(engine: Engine) {
    // スプライトシートアニメーション
    const spriteSheet = SpriteSheet.fromImageSource({
      image: Resources.HeroSheet,
      grid: { rows: 4, columns: 6, spriteWidth: 16, spriteHeight: 24 },
    });

    const idle = Animation.fromSpriteSheet(spriteSheet, [0, 1, 2, 3], 200);
    const run = Animation.fromSpriteSheet(spriteSheet, [6, 7, 8, 9, 10, 11], 100);
    const jump = Animation.fromSpriteSheet(spriteSheet, [12, 13], 150);

    this.graphics.add("idle", idle);
    this.graphics.add("run", run);
    this.graphics.add("jump", jump);
    this.graphics.use("idle");

    // 接地判定
    this.on("postcollision", (evt) => {
      if (evt.side === "Bottom") this.isGrounded = true;
    });
  }

  onPreUpdate(engine: Engine, delta: 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 (moving) {
      this.graphics.use("run");
    } else {
      this.graphics.use("idle");
    }
  }

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

シーンとTiledマップ

// src/scenes/LevelOne.ts
import { Scene, Engine, TileMap, vec } from "excalibur";
import { TiledResource } from "@excaliburjs/plugin-tiled";
import { Player } from "../actors/Player";
import { Coin } from "../actors/Coin";

export class LevelOne extends Scene {
  private tiledMap!: TiledResource;

  onInitialize(engine: Engine) {
    this.tiledMap = new TiledResource("/maps/level-1.tmx");

    // シーンにタイルマップを追加
    this.tiledMap.addToScene(this);

    // Tiledオブジェクトレイヤーからスポーンポイントを取得
    const spawnPoint = this.tiledMap.getObjectsByName("PlayerSpawn")[0];
    const player = new Player(spawnPoint.x, spawnPoint.y);
    this.add(player);

    // カメラがプレイヤーを追跡
    this.camera.strategy.elasticToActor(player, 0.8, 0.9);
    this.camera.zoom = 2;

    // オブジェクトレイヤーからコインを生成
    this.tiledMap.getObjectsByType("coin").forEach((obj) => {
      this.add(new Coin(obj.x, obj.y));
    });
  }
}

インストール

npm install excalibur
npm install @excaliburjs/plugin-tiled      # Tiledマップのサポート

ベストプラクティス

  1. 常にTypeScript — ExcaliburはTypeScriptで構築されています。完全なオートコンプリートと型安全のためにTypeScriptを使用してください。
  2. Actorのライフサイクル — ゲームロジックには、コンストラクタの代わりにonInitializeonPreUpdateonPostUpdateをオーバーライドしてください。
  3. 衝突タイプ — 移動するエンティティにはActive、静的なプラットフォームにはFixed、トリガー/センサーにはPassiveを使用してください。
  4. シーン遷移 — シーン間でデータを渡すには、engine.goToScene("name", { sceneActivationData })を使用してください。
  5. Tiledプラグイン — レベルデザインには公式のTiledプラグインを使用してください。タイルレイヤー、オブジェクトレイヤー、およびカスタムプロパティをサポートします。
  6. Actions API — アニメーションをチェーン化します。カットシーンやエフェクトには、actor.actions.moveTo(100, 100, 200).delay(500).fade(0, 1000)を使用してください。
  7. イベントシステム — クリーンなゲームロジックのために、型付きイベント(on("precollision")on("kill"))を使用してください。
  8. リソースのロード — すべてのアセットをローダーで定義します。Excaliburは自動的にローディング画面を表示します。
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Excalibur.js — TypeScript-First 2D Game Engine

You are an expert in Excalibur.js, the TypeScript-first 2D game engine built for the web. You help developers build browser games using Excalibur's Actor system, Scene management, Tiled integration, physics, animation, sound, and input handling — with first-class TypeScript support, excellent documentation, and a focus on developer experience over raw performance.

Core Capabilities

Game Setup

// src/main.ts — Excalibur game
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 rendering
  pixelRatio: 2,
  fixedUpdateFps: 60,                     // Deterministic physics
});

game.addScene("level-one", new LevelOne());
game.start(loader).then(() => {           // Preload assets
  game.goToScene("level-one");
});

Actors and Components

// src/actors/Player.ts
import { Actor, Color, vec, Keys, CollisionType, Animation, SpriteSheet } 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) {
    // Sprite sheet animations
    const spriteSheet = SpriteSheet.fromImageSource({
      image: Resources.HeroSheet,
      grid: { rows: 4, columns: 6, spriteWidth: 16, spriteHeight: 24 },
    });

    const idle = Animation.fromSpriteSheet(spriteSheet, [0, 1, 2, 3], 200);
    const run = Animation.fromSpriteSheet(spriteSheet, [6, 7, 8, 9, 10, 11], 100);
    const jump = Animation.fromSpriteSheet(spriteSheet, [12, 13], 150);

    this.graphics.add("idle", idle);
    this.graphics.add("run", run);
    this.graphics.add("jump", jump);
    this.graphics.use("idle");

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

  onPreUpdate(engine: Engine, delta: 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 (moving) {
      this.graphics.use("run");
    } else {
      this.graphics.use("idle");
    }
  }

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

Scenes and Tiled Maps

// src/scenes/LevelOne.ts
import { Scene, Engine, TileMap, vec } from "excalibur";
import { TiledResource } from "@excaliburjs/plugin-tiled";
import { Player } from "../actors/Player";
import { Coin } from "../actors/Coin";

export class LevelOne extends Scene {
  private tiledMap!: TiledResource;

  onInitialize(engine: Engine) {
    this.tiledMap = new TiledResource("/maps/level-1.tmx");

    // Add tilemap to scene
    this.tiledMap.addToScene(this);

    // Get spawn point from Tiled object layer
    const spawnPoint = this.tiledMap.getObjectsByName("PlayerSpawn")[0];
    const player = new Player(spawnPoint.x, spawnPoint.y);
    this.add(player);

    // Camera follows player
    this.camera.strategy.elasticToActor(player, 0.8, 0.9);
    this.camera.zoom = 2;

    // Spawn coins from object layer
    this.tiledMap.getObjectsByType("coin").forEach((obj) => {
      this.add(new Coin(obj.x, obj.y));
    });
  }
}

Installation

npm install excalibur
npm install @excaliburjs/plugin-tiled      # Tiled map support

Best Practices

  1. TypeScript always — Excalibur is built in TypeScript; use it for full autocompletion and type safety
  2. Actor lifecycle — Override onInitialize, onPreUpdate, onPostUpdate instead of constructor for game logic
  3. Collision types — Use Active for moving entities, Fixed for static platforms, Passive for triggers/sensors
  4. Scene transitionsengine.goToScene("name", { sceneActivationData }) to pass data between scenes
  5. Tiled plugin — Use the official Tiled plugin for level design; supports tile layers, object layers, and custom properties
  6. Actions API — Chain animations: actor.actions.moveTo(100, 100, 200).delay(500).fade(0, 1000) for cutscenes and effects
  7. Event system — Use typed events (on("precollision"), on("kill")) for clean game logic
  8. Resource loading — Define all assets in a loader; Excalibur shows a loading screen automatically