Token导航 LogoToken导航

Agent Skill · 前端设计

phaser-gamedev(移相器游戏开发)

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

phaser-gamedev 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为操作浏览器;许可证为 MIT,第三方扫描已通过,按安装量在前端设计类的 10,216 个 Skill 里排第 523。

总安装 20,280周安装 845GitHub Stars 35下载 6,760核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:phaser-gamedev(移相器游戏开发)
来源仓库:https://github.com/chongdashu/phaserjs-tinyswords
仓库路径:skills/phaser-gamedev
安装命令:
npx skills add https://github.com/chongdashu/phaserjs-tinyswords --skill phaser-gamedev
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/chongdashu/phaserjs-tinyswords --skill phaser-gamedev

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

使用 Phaser 3 基于场景的架构和物理系统构建快速、精美的 2D 浏览器游戏。

场景优先架构将游戏组织为不同的生命周期阶段(启动、菜单、游戏、暂停、GameOver),并在转换过程中提供清晰的状态管理 支持 Arcade 物理以实现速度和简单性,支持 Matter 物理以实现真实模拟,以及支持菜单和覆盖层的无物理场景 涵盖精灵、动画、图块地图(平铺集成)、输入处理(键盘、指针、拖动)以及带有进度跟踪的资源预加载 包括游戏对象、碰撞检测、对象池以及通过注册表和场景数据存储进行跨场景数据持久化的模式

来源仓库内路径:skills/phaser-gamedev

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/chongdashu/phaserjs-tinyswords --skill phaser-…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要操作浏览器,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

phaser-gamedev 怎么安装?

在终端执行 npx skills add https://github.com/chongdashu/phaserjs-tinyswords --skill phaser-gamedev。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

phaser-gamedev 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

phaser-gamedev 需要什么权限?

权限级别是操作浏览器。该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

phaser-gamedev 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

phaser-gamedev 用的人多吗?

公开数据是累计安装 20,280 次,近一周安装 845 次,下载 6,760 次,GitHub 35 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

phaser-gamedev 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
phaser-gamedev

移相器游戏开发 · 本页

20,28035操作浏览器MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Phaser Game Development

Build fast, polished 2D browser games using Phaser 3's scene-based architecture and physics systems.

Philosophy: Games as Living Systems

Games are not static UIs—they are dynamic systems where entities interact, state evolves, and player input drives everything. Before writing code, think architecturally.

Before building, ask:

  • What scenes does this game need? (Boot, Menu, Game, Pause, GameOver)
  • What entities exist and how do they interact?
  • What state must persist across scenes?
  • What physics model fits? (Arcade for speed, Matter for realism)
  • What input methods will players use?

Core principles:

  1. Scene-First Architecture: Structure games around scenes, not global state
  2. Composition Over Inheritance: Build entities from game objects and components
  3. Physics-Aware Design: Choose physics system before coding collisions
  4. Asset Pipeline Discipline: Preload everything, reference by key
  5. Frame-Rate Independence: Use delta time, not frame counting

Game Configuration

Every Phaser game starts with a configuration object.

Minimal Configuration

const config = {
  type: Phaser.AUTO,           // WebGL with Canvas fallback
  width: 800,
  height: 600,
  scene: [BootScene, GameScene]
};

const game = new Phaser.Game(config);

Full Configuration Pattern

const config = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  parent: 'game-container',    // DOM element ID
  backgroundColor: '#2d2d2d',

  scale: {
    mode: Phaser.Scale.FIT,
    autoCenter: Phaser.Scale.CENTER_BOTH
  },

  physics: {
    default: 'arcade',
    arcade: {
      gravity: { y: 300 },
      debug: false              // Enable during development
    }
  },

  scene: [BootScene, MenuScene, GameScene, GameOverScene]
};

Physics System Choice

SystemUse When
ArcadePlatformers, shooters, most 2D games. Fast, simple AABB collisions
MatterPhysics puzzles, ragdolls, realistic collisions. Slower, more accurate
NoneMenu scenes, visual novels, card games

Scene Architecture

Scenes are the fundamental organizational unit. Each scene has a lifecycle.

Scene Lifecycle Methods

class GameScene extends Phaser.Scene {
  constructor() {
    super('GameScene');        // Scene key for reference
  }

  init(data) {
    // Called first. Receive data from previous scene
    this.level = data.level || 1;
  }

  preload() {
    // Load assets. Runs before create()
    this.load.image('player', 'assets/player.png');
    this.load.spritesheet('enemy', 'assets/enemy.png', {
      frameWidth: 32, frameHeight: 32
    });
  }

  create() {
    // Set up game objects, physics, input
    this.player = this.physics.add.sprite(100, 100, 'player');
    this.cursors = this.input.keyboard.createCursorKeys();
  }

  update(time, delta) {
    // Game loop. Called every frame
    // delta = milliseconds since last frame
    this.player.x += this.speed * (delta / 1000);
  }
}

Scene Transitions

// Start a new scene (stops current)
this.scene.start('GameOverScene', { score: this.score });

// Launch scene in parallel (both run)
this.scene.launch('UIScene');

// Pause/resume scenes
this.scene.pause('GameScene');
this.scene.resume('GameScene');

// Stop a scene
this.scene.stop('UIScene');

Recommended Scene Structure

scenes/
├── BootScene.js      # Asset loading, progress bar
├── MenuScene.js      # Title screen, options
├── GameScene.js      # Main gameplay
├── UIScene.js        # HUD overlay (launched parallel)
├── PauseScene.js     # Pause menu overlay
└── GameOverScene.js  # End screen, restart option

Game Objects

Everything visible in Phaser is a Game Object.

Common Game Objects

// Images (static)
this.add.image(400, 300, 'background');

// Sprites (can animate, physics-enabled)
const player = this.add.sprite(100, 100, 'player');

// Text
const score = this.add.text(16, 16, 'Score: 0', {
  fontSize: '32px',
  fill: '#fff'
});

// Graphics (draw shapes)
const graphics = this.add.graphics();
graphics.fillStyle(0xff0000);
graphics.fillRect(100, 100, 50, 50);

// Containers (group objects)
const container = this.add.container(400, 300, [sprite1, sprite2]);

// Tilemaps
const map = this.make.tilemap({ key: 'level1' });

Sprite Creation Patterns

// Basic sprite
const sprite = this.add.sprite(x, y, 'textureKey');

// Sprite with physics body
const sprite = this.physics.add.sprite(x, y, 'textureKey');

// From spritesheet frame
const sprite = this.add.sprite(x, y, 'sheet', frameIndex);

// From atlas
const sprite = this.add.sprite(x, y, 'atlas', 'frameName');

Physics Systems

Arcade Physics (Recommended Default)

Fast, simple physics for most 2D games.

// Enable physics on sprite
this.physics.add.sprite(x, y, 'player');

// Or add physics to existing sprite
this.physics.add.existing(sprite);

// Configure body
sprite.body.setVelocity(200, 0);
sprite.body.setBounce(0.5);
sprite.body.setCollideWorldBounds(true);
sprite.body.setGravityY(300);

// Collision detection
this.physics.add.collider(player, platforms);
this.physics.add.overlap(player, coins, collectCoin, null, this);

function collectCoin(player, coin) {
  coin.disableBody(true, true);  // Remove from physics and hide
  this.score += 10;
}

Physics Groups

// Static group (platforms, walls)
const platforms = this.physics.add.staticGroup();
platforms.create(400, 568, 'ground').setScale(2).refreshBody();

// Dynamic group (enemies, bullets)
const enemies = this.physics.add.group({
  key: 'enemy',
  repeat: 5,
  setXY: { x: 100, y: 0, stepX: 70 }
});

enemies.children.iterate(enemy => {
  enemy.setBounce(Phaser.Math.FloatBetween(0.4, 0.8));
});

Matter Physics

For realistic physics simulations.

// Config
physics: {
  default: 'matter',
  matter: {
    gravity: { y: 1 },
    debug: true
  }
}

// Create bodies
const ball = this.matter.add.circle(400, 100, 25);
const box = this.matter.add.rectangle(400, 400, 100, 50, { isStatic: true });

// Sprite with Matter body
const player = this.matter.add.sprite(100, 100, 'player');
player.setFriction(0.005);
player.setBounce(0.9);

Input Handling

Keyboard Input

// Cursor keys
this.cursors = this.input.keyboard.createCursorKeys();

// In update()
if (this.cursors.left.isDown) {
  player.setVelocityX(-160);
} else if (this.cursors.right.isDown) {
  player.setVelocityX(160);
}

if (this.cursors.up.isDown && player.body.touching.down) {
  player.setVelocityY(-330);  // Jump
}

// Custom keys
this.spaceKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);

// Key events
this.input.keyboard.on('keydown-SPACE', () => {
  this.fire();
});

Pointer/Mouse Input

// Click/tap
this.input.on('pointerdown', (pointer) => {
  console.log(pointer.x, pointer.y);
});

// Make object interactive
sprite.setInteractive();
sprite.on('pointerdown', () => {
  sprite.setTint(0xff0000);
});
sprite.on('pointerup', () => {
  sprite.clearTint();
});

// Drag
this.input.setDraggable(sprite);
this.input.on('drag', (pointer, obj, dragX, dragY) => {
  obj.x = dragX;
  obj.y = dragY;
});

Animations

Creating Animations

// In create() - define once
this.anims.create({
  key: 'walk',
  frames: this.anims.generateFrameNumbers('player', { start: 0, end: 3 }),
  frameRate: 10,
  repeat: -1  // Loop forever
});

this.anims.create({
  key: 'jump',
  frames: [{ key: 'player', frame: 4 }],
  frameRate: 20
});

// From atlas
this.anims.create({
  key: 'explode',
  frames: this.anims.generateFrameNames('atlas', {
    prefix: 'explosion_',
    start: 1,
    end: 8,
    zeroPad: 2
  }),
  frameRate: 16,
  hideOnComplete: true
});

Playing Animations

// Play animation
sprite.anims.play('walk', true);  // true = ignore if already playing

// Play once
sprite.anims.play('jump');

// Stop
sprite.anims.stop();

// Animation events
sprite.on('animationcomplete', (anim, frame) => {
  if (anim.key === 'die') {
    sprite.destroy();
  }
});

Asset Loading

Preload Patterns

preload() {
  // Images
  this.load.image('sky', 'assets/sky.png');

  // Spritesheets
  this.load.spritesheet('player', 'assets/player.png', {
    frameWidth: 32,
    frameHeight: 48
  });

  // Atlases (TexturePacker)
  this.load.atlas('sprites', 'assets/sprites.png', 'assets/sprites.json');

  // Tilemaps
  this.load.tilemapTiledJSON('map', 'assets/level1.json');
  this.load.image('tiles', 'assets/tileset.png');

  // Audio
  this.load.audio('bgm', 'assets/music.mp3');
  this.load.audio('sfx', ['assets/sound.ogg', 'assets/sound.mp3']);

  // Progress tracking
  this.load.on('progress', (value) => {
    console.log(`Loading: ${Math.round(value * 100)}%`);
  });
}

Boot Scene Pattern

class BootScene extends Phaser.Scene {
  constructor() {
    super('BootScene');
  }

  preload() {
    // Loading bar
    const width = this.cameras.main.width;
    const height = this.cameras.main.height;

    const progressBar = this.add.graphics();
    const progressBox = this.add.graphics();
    progressBox.fillStyle(0x222222, 0.8);
    progressBox.fillRect(width/2 - 160, height/2 - 25, 320, 50);

    this.load.on('progress', (value) => {
      progressBar.clear();
      progressBar.fillStyle(0xffffff, 1);
      progressBar.fillRect(width/2 - 150, height/2 - 15, 300 * value, 30);
    });

    // Load all game assets here
    this.load.image('player', 'assets/player.png');
    // ... more assets
  }

  create() {
    this.scene.start('MenuScene');
  }
}

Tilemaps (Tiled Integration)

Loading and Creating

preload() {
  this.load.tilemapTiledJSON('map', 'assets/map.json');
  this.load.image('tiles', 'assets/tileset.png');
}

create() {
  const map = this.make.tilemap({ key: 'map' });
  const tileset = map.addTilesetImage('tileset-name-in-tiled', 'tiles');

  // Create layers (match names from Tiled)
  const backgroundLayer = map.createLayer('Background', tileset, 0, 0);
  const groundLayer = map.createLayer('Ground', tileset, 0, 0);

  // Enable collision on specific tiles
  groundLayer.setCollisionByProperty({ collides: true });
  // Or by tile index
  groundLayer.setCollisionBetween(1, 100);

  // Add collision with player
  this.physics.add.collider(this.player, groundLayer);
}

Object Layers

// Spawn points from Tiled object layer
const spawnPoint = map.findObject('Objects', obj => obj.name === 'spawn');
this.player = this.physics.add.sprite(spawnPoint.x, spawnPoint.y, 'player');

// Create objects from layer
const coins = map.createFromObjects('Objects', {
  name: 'coin',
  key: 'coin'
});
this.physics.world.enable(coins);

Project Structure

Recommended Organization

game/
├── src/
│   ├── scenes/
│   │   ├── BootScene.js
│   │   ├── MenuScene.js
│   │   ├── GameScene.js
│   │   └── UIScene.js
│   ├── gameObjects/
│   │   ├── Player.js
│   │   ├── Enemy.js
│   │   └── Collectible.js
│   ├── systems/
│   │   ├── InputManager.js
│   │   └── AudioManager.js
│   ├── config/
│   │   └── gameConfig.js
│   └── main.js
├── assets/
│   ├── images/
│   ├── audio/
│   ├── tilemaps/
│   └── fonts/
├── index.html
└── package.json

ES Module Setup

// main.js
import Phaser from 'phaser';
import BootScene from './scenes/BootScene';
import GameScene from './scenes/GameScene';
import { gameConfig } from './config/gameConfig';

const config = {
  ...gameConfig,
  scene: [BootScene, GameScene]
};

new Phaser.Game(config);

Anti-Patterns to Avoid

❌ Global State Soup: Storing game state on window or module globals Why bad: Untrackable bugs, scene transitions break state Better: Use scene data, registries, or dedicated state managers

❌ Loading in Create: Loading assets in create() instead of preload() Why bad: Assets may not be ready when referenced Better: Always load in preload(), use Boot scene for all assets

❌ Frame-Dependent Logic: Using frame count instead of delta time Why bad: Game speed varies with frame rate Better: this.speed * (delta / 1000) for consistent movement

❌ Physics Overkill: Using Matter for simple platformer collisions Why bad: Performance hit, unnecessary complexity Better: Arcade physics handles 90% of 2D game needs

❌ Monolithic Scenes: One giant scene with all game logic Why bad: Unmaintainable, hard to add features Better: Separate scenes for menus, gameplay, UI overlays

❌ Magic Numbers: Hardcoded values scattered in code Why bad: Impossible to balance, inconsistent Better: Config objects, constants files

❌ Ignoring Object Pooling: Creating/destroying objects every frame Why bad: Memory churn, garbage collection stutters Better: Use groups with setActive(false) / setVisible(false)

❌ Synchronous Asset Access: Assuming assets load instantly Why bad: Race conditions, undefined textures Better: Chain scene starts, use load events

❌ Assuming Spritesheet Frame Dimensions: Using guessed frame sizes without verifying Why bad: Wrong dimensions cause silent frame corruption; off-by-pixels compounds into broken visuals Better: Open asset file, measure frames, calculate with spacing/margin, verify math adds up

❌ Ignoring Spritesheet Spacing: Not specifying spacing for gapped spritesheets Why bad: Frames shift progressively; later frames read wrong pixel regions Better: Check source asset for gaps between frames; use spacing: N in loader config

❌ Hardcoding Nine-Slice Colors: Using single background color for all UI panel variants Why bad: Transparent frame edges reveal wrong color for different asset color schemes Better: Per-asset background color config; sample from center frame (frame 4)

❌ Nine-Slice with Padded Frames: Treating the full frame as the slice region when the art is centered/padded inside each tile Why bad: Edge tiles contribute interior fill, showing up as opaque “side bars” inside the panel Better: Trim tiles to their effective content bounds (alpha bbox) and composite/cache a texture; add ~1px overlap + disable smoothing to avoid seams

❌ Scaling Discontinuous UI Art: Stretching a cropped ribbon/banner row that contains internal transparent gaps Why bad: The transparent gutters get stretched, so the UI looks segmented or the fill disappears behind the frame. Better: Slice the asset into caps/center, stretch only the center, and stitch the pieces (with ~1px overlap + smoothing disabled) before rendering at pivot sizes.


Variation Guidance

IMPORTANT: Game implementations should vary based on:

  • Game Genre: Platformer physics differ from top-down shooter physics
  • Target Platform: Mobile needs touch input, desktop can use keyboard
  • Art Style: Pixel art uses nearest-neighbor scaling, HD art uses linear
  • Performance Needs: Many sprites → object pooling; few sprites → simple creation
  • Complexity: Simple games can inline; complex games need class hierarchies

Avoid converging on:

  • Always using 800x600 resolution
  • Always using Arcade physics
  • Always using the same scene structure
  • Copy-pasting boilerplate without adaptation

Quick Reference

Common Physics Properties

body.setVelocity(x, y)
body.setVelocityX(x)
body.setBounce(x, y)
body.setGravityY(y)
body.setCollideWorldBounds(true)
body.setImmovable(true)        // For static-like dynamic bodies
body.setDrag(x, y)
body.setMaxVelocity(x, y)

Useful Scene Properties

this.cameras.main              // Main camera
this.physics.world             // Physics world
this.input.keyboard            // Keyboard manager
this.sound                     // Audio manager
this.time                      // Time/clock manager
this.tweens                    // Tween manager
this.anims                     // Animation manager
this.registry                  // Cross-scene data store
this.data                      // Scene-specific data store

Essential Events

// Scene events
this.events.on('pause', callback)
this.events.on('resume', callback)
this.events.on('shutdown', callback)

// Physics events
this.physics.world.on('worldbounds', callback)

// Game object events
sprite.on('destroy', callback)
sprite.on('animationcomplete', callback)

See Also

  • references/arcade-physics.md - Deep dive into Arcade physics
  • references/tilemaps.md - Advanced tilemap techniques
  • references/performance.md - Optimization strategies
  • references/spritesheets-nineslice.md - Spritesheet loading (spacing/margin), nine-slice UI panels, asset inspection

Remember

Phaser gives you powerful primitives—scenes, sprites, physics, input—but architecture is your responsibility.

Think in systems: What scenes do you need? What entities exist? How do they interact? Answer these questions before writing code, and your game will be maintainable as it grows.

Claude is capable of building complete, polished Phaser games. These guidelines illuminate the path—they don't fence it.

平台分布

Claude Code

28.58%
按下载量换算1,932

OpenCode

21.32%
按下载量换算1,441

Codex

16.88%
按下载量换算1,141

Cursor

11.97%
按下载量换算809

Gemini CLI

7.92%
按下载量换算535

Antigravity

3.26%
按下载量换算220

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills