@starlein/paperclip-plugin-company-wizard 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +748 -0
- package/dist/manifest.js +91 -0
- package/dist/manifest.js.map +7 -0
- package/dist/ui/index.css +1647 -0
- package/dist/ui/index.css.map +7 -0
- package/dist/ui/index.js +6738 -0
- package/dist/ui/index.js.map +7 -0
- package/dist/worker.js +8247 -0
- package/dist/worker.js.map +7 -0
- package/package.json +73 -0
- package/templates/ai-wizard/config-format.md +21 -0
- package/templates/ai-wizard/interview-system.md +67 -0
- package/templates/ai-wizard/messages.json +6 -0
- package/templates/ai-wizard/single-shot-system.md +42 -0
- package/templates/bootstrap-instructions.md +30 -0
- package/templates/modules/accessibility/agents/engineer/skills/accessibility-audit.fallback.md +18 -0
- package/templates/modules/accessibility/agents/ui-designer/skills/accessibility-audit.fallback.md +18 -0
- package/templates/modules/accessibility/module.meta.json +22 -0
- package/templates/modules/accessibility/skills/accessibility-audit.md +27 -0
- package/templates/modules/architecture-plan/agents/ceo/skills/architecture-plan.fallback.md +16 -0
- package/templates/modules/architecture-plan/agents/engineer/skills/design-system.fallback.md +17 -0
- package/templates/modules/architecture-plan/agents/ui-designer/skills/architecture-plan.md +19 -0
- package/templates/modules/architecture-plan/agents/ui-designer/skills/design-system.md +24 -0
- package/templates/modules/architecture-plan/docs/architecture-template.md +38 -0
- package/templates/modules/architecture-plan/docs/design-system-template.md +61 -0
- package/templates/modules/architecture-plan/module.meta.json +37 -0
- package/templates/modules/architecture-plan/skills/architecture-plan.md +23 -0
- package/templates/modules/auto-assign/README.md +23 -0
- package/templates/modules/auto-assign/agents/ceo/heartbeat-section.md +9 -0
- package/templates/modules/auto-assign/agents/ceo/skills/auto-assign.fallback.md +18 -0
- package/templates/modules/auto-assign/agents/product-owner/heartbeat-section.md +10 -0
- package/templates/modules/auto-assign/module.meta.json +27 -0
- package/templates/modules/auto-assign/skills/auto-assign.md +23 -0
- package/templates/modules/backlog/README.md +26 -0
- package/templates/modules/backlog/agents/ceo/heartbeat-section.md +10 -0
- package/templates/modules/backlog/agents/ceo/skills/backlog-health.fallback.md +20 -0
- package/templates/modules/backlog/agents/product-owner/heartbeat-section.md +15 -0
- package/templates/modules/backlog/docs/backlog-process.md +62 -0
- package/templates/modules/backlog/docs/backlog-template.md +53 -0
- package/templates/modules/backlog/module.meta.json +31 -0
- package/templates/modules/backlog/skills/backlog-health.md +47 -0
- package/templates/modules/brand-identity/agents/ceo/skills/brand-identity.fallback.md +19 -0
- package/templates/modules/brand-identity/agents/cmo/skills/brand-identity.fallback.md +19 -0
- package/templates/modules/brand-identity/docs/brand-identity-template.md +43 -0
- package/templates/modules/brand-identity/module.meta.json +22 -0
- package/templates/modules/brand-identity/skills/brand-identity.md +30 -0
- package/templates/modules/build-api/module.meta.json +118 -0
- package/templates/modules/build-api/skills/api-design.md +43 -0
- package/templates/modules/ci-cd/agents/devops/skills/ci-cd.md +28 -0
- package/templates/modules/ci-cd/agents/engineer/skills/ci-cd.fallback.md +18 -0
- package/templates/modules/ci-cd/docs/ci-cd-template.md +42 -0
- package/templates/modules/ci-cd/module.meta.json +105 -0
- package/templates/modules/ci-cd/skills/ci-cd.md +26 -0
- package/templates/modules/codebase-onboarding/agents/ceo/skills/codebase-audit.fallback.md +19 -0
- package/templates/modules/codebase-onboarding/module.meta.json +24 -0
- package/templates/modules/codebase-onboarding/skills/codebase-audit.md +45 -0
- package/templates/modules/competitive-intel/agents/ceo/skills/competitive-tracking.fallback.md +17 -0
- package/templates/modules/competitive-intel/agents/cmo/skills/competitive-tracking.fallback.md +17 -0
- package/templates/modules/competitive-intel/agents/customer-success/skills/competitive-tracking.md +25 -0
- package/templates/modules/competitive-intel/module.meta.json +23 -0
- package/templates/modules/competitive-intel/skills/competitive-tracking.md +27 -0
- package/templates/modules/dependency-management/agents/engineer/skills/dependency-audit.fallback.md +18 -0
- package/templates/modules/dependency-management/module.meta.json +25 -0
- package/templates/modules/dependency-management/skills/dependency-audit.md +43 -0
- package/templates/modules/documentation/agents/ceo/skills/project-docs.fallback.md +16 -0
- package/templates/modules/documentation/agents/engineer/skills/project-docs.fallback.md +16 -0
- package/templates/modules/documentation/module.meta.json +22 -0
- package/templates/modules/documentation/skills/project-docs.md +25 -0
- package/templates/modules/game-design/agents/ceo/skills/game-design.fallback.md +17 -0
- package/templates/modules/game-design/agents/game-designer/skills/game-design.md +51 -0
- package/templates/modules/game-design/docs/engine-phaser.md +310 -0
- package/templates/modules/game-design/docs/engine-pixijs.md +289 -0
- package/templates/modules/game-design/docs/engine-threejs.md +304 -0
- package/templates/modules/game-design/docs/gdd-template.md +72 -0
- package/templates/modules/game-design/module.meta.json +22 -0
- package/templates/modules/game-design/skills/game-design.md +41 -0
- package/templates/modules/github-repo/README.md +23 -0
- package/templates/modules/github-repo/agents/engineer/skills/git-workflow.md +23 -0
- package/templates/modules/github-repo/docs/git-workflow.md +50 -0
- package/templates/modules/github-repo/module.meta.json +12 -0
- package/templates/modules/hiring-review/agents/ceo/skills/hiring-review.fallback.md +17 -0
- package/templates/modules/hiring-review/module.meta.json +21 -0
- package/templates/modules/hiring-review/skills/hiring-review.md +24 -0
- package/templates/modules/launch-mvp/module.meta.json +86 -0
- package/templates/modules/market-analysis/agents/ceo/skills/market-analysis.fallback.md +17 -0
- package/templates/modules/market-analysis/agents/cmo/skills/market-analysis.fallback.md +19 -0
- package/templates/modules/market-analysis/agents/product-owner/skills/market-analysis.fallback.md +18 -0
- package/templates/modules/market-analysis/agents/ux-researcher/skills/market-analysis.md +23 -0
- package/templates/modules/market-analysis/docs/market-analysis-template.md +32 -0
- package/templates/modules/market-analysis/module.meta.json +23 -0
- package/templates/modules/market-analysis/skills/market-analysis.md +21 -0
- package/templates/modules/monitoring/agents/devops/skills/monitoring.md +23 -0
- package/templates/modules/monitoring/agents/engineer/skills/monitoring.fallback.md +18 -0
- package/templates/modules/monitoring/docs/monitoring-template.md +46 -0
- package/templates/modules/monitoring/module.meta.json +24 -0
- package/templates/modules/monitoring/skills/monitoring.md +20 -0
- package/templates/modules/pr-review/README.md +43 -0
- package/templates/modules/pr-review/agents/code-reviewer/skills/code-review.md +29 -0
- package/templates/modules/pr-review/agents/devops/skills/infra-review.md +29 -0
- package/templates/modules/pr-review/agents/engineer/skills/pr-workflow.md +24 -0
- package/templates/modules/pr-review/agents/product-owner/skills/product-review.md +27 -0
- package/templates/modules/pr-review/agents/qa/skills/qa-review.md +29 -0
- package/templates/modules/pr-review/agents/ui-designer/skills/design-review.md +29 -0
- package/templates/modules/pr-review/agents/ux-researcher/skills/ux-review.md +29 -0
- package/templates/modules/pr-review/docs/pr-conventions.md +78 -0
- package/templates/modules/pr-review/module.meta.json +24 -0
- package/templates/modules/release-management/agents/engineer/skills/release-process.fallback.md +18 -0
- package/templates/modules/release-management/module.meta.json +25 -0
- package/templates/modules/release-management/skills/release-process.md +45 -0
- package/templates/modules/security-audit/agents/devops/skills/security-review.fallback.md +17 -0
- package/templates/modules/security-audit/agents/devops/skills/threat-model.fallback.md +17 -0
- package/templates/modules/security-audit/agents/engineer/skills/security-review.fallback.md +17 -0
- package/templates/modules/security-audit/agents/engineer/skills/threat-model.fallback.md +17 -0
- package/templates/modules/security-audit/module.meta.json +36 -0
- package/templates/modules/security-audit/skills/security-review.md +25 -0
- package/templates/modules/security-audit/skills/threat-model.md +22 -0
- package/templates/modules/stall-detection/README.md +27 -0
- package/templates/modules/stall-detection/agents/ceo/heartbeat-section.md +12 -0
- package/templates/modules/stall-detection/agents/ceo/skills/stall-detection.md +21 -0
- package/templates/modules/stall-detection/module.meta.json +15 -0
- package/templates/modules/tech-stack/agents/ceo/skills/tech-stack.fallback.md +16 -0
- package/templates/modules/tech-stack/docs/tech-stack-template.md +28 -0
- package/templates/modules/tech-stack/module.meta.json +21 -0
- package/templates/modules/tech-stack/skills/tech-stack.md +25 -0
- package/templates/modules/triage/agents/ceo/skills/issue-triage.fallback.md +19 -0
- package/templates/modules/triage/module.meta.json +25 -0
- package/templates/modules/triage/skills/issue-triage.md +42 -0
- package/templates/modules/user-testing/agents/ceo/skills/user-testing.fallback.md +17 -0
- package/templates/modules/user-testing/agents/product-owner/skills/user-testing.fallback.md +17 -0
- package/templates/modules/user-testing/agents/qa/skills/user-testing.md +30 -0
- package/templates/modules/user-testing/agents/ux-researcher/skills/user-testing.fallback.md +18 -0
- package/templates/modules/user-testing/docs/user-testing-template.md +37 -0
- package/templates/modules/user-testing/module.meta.json +23 -0
- package/templates/modules/user-testing/skills/user-testing.md +27 -0
- package/templates/modules/vision-workshop/agents/ceo/skills/vision-workshop.md +23 -0
- package/templates/modules/vision-workshop/agents/ux-researcher/skills/vision-workshop.md +19 -0
- package/templates/modules/vision-workshop/docs/vision-template.md +28 -0
- package/templates/modules/vision-workshop/module.meta.json +12 -0
- package/templates/modules/website-relaunch/agents/ui-designer/skills/site-audit.md +65 -0
- package/templates/modules/website-relaunch/module.meta.json +168 -0
- package/templates/modules/website-relaunch/skills/design-ingestion.md +111 -0
- package/templates/modules/website-relaunch/skills/site-audit.md +54 -0
- package/templates/presets/build-api/preset.meta.json +16 -0
- package/templates/presets/build-game/preset.meta.json +150 -0
- package/templates/presets/content/preset.meta.json +20 -0
- package/templates/presets/fast/preset.meta.json +16 -0
- package/templates/presets/full/preset.meta.json +22 -0
- package/templates/presets/gtm/preset.meta.json +21 -0
- package/templates/presets/launch-mvp/preset.meta.json +17 -0
- package/templates/presets/launch-pack/preset.meta.json +25 -0
- package/templates/presets/quality/preset.meta.json +17 -0
- package/templates/presets/rad/preset.meta.json +19 -0
- package/templates/presets/repo-maintenance/preset.meta.json +104 -0
- package/templates/presets/research/preset.meta.json +13 -0
- package/templates/presets/secure/preset.meta.json +22 -0
- package/templates/presets/startup/preset.meta.json +19 -0
- package/templates/presets/website-relaunch/preset.meta.json +18 -0
- package/templates/roles/audio-designer/AGENTS.md +29 -0
- package/templates/roles/audio-designer/HEARTBEAT.md +37 -0
- package/templates/roles/audio-designer/SOUL.md +17 -0
- package/templates/roles/audio-designer/TOOLS.md +3 -0
- package/templates/roles/audio-designer/role.meta.json +14 -0
- package/templates/roles/ceo/AGENTS.md +28 -0
- package/templates/roles/ceo/HEARTBEAT.md +75 -0
- package/templates/roles/ceo/SOUL.md +33 -0
- package/templates/roles/ceo/TOOLS.md +3 -0
- package/templates/roles/ceo/role.meta.json +14 -0
- package/templates/roles/cfo/AGENTS.md +31 -0
- package/templates/roles/cfo/HEARTBEAT.md +37 -0
- package/templates/roles/cfo/SOUL.md +17 -0
- package/templates/roles/cfo/TOOLS.md +3 -0
- package/templates/roles/cfo/role.meta.json +17 -0
- package/templates/roles/cmo/AGENTS.md +31 -0
- package/templates/roles/cmo/HEARTBEAT.md +37 -0
- package/templates/roles/cmo/SOUL.md +17 -0
- package/templates/roles/cmo/TOOLS.md +3 -0
- package/templates/roles/cmo/role.meta.json +17 -0
- package/templates/roles/code-reviewer/AGENTS.md +42 -0
- package/templates/roles/code-reviewer/HEARTBEAT.md +33 -0
- package/templates/roles/code-reviewer/SOUL.md +18 -0
- package/templates/roles/code-reviewer/TOOLS.md +3 -0
- package/templates/roles/code-reviewer/role.meta.json +12 -0
- package/templates/roles/cto/AGENTS.md +30 -0
- package/templates/roles/cto/HEARTBEAT.md +45 -0
- package/templates/roles/cto/SOUL.md +25 -0
- package/templates/roles/cto/TOOLS.md +3 -0
- package/templates/roles/cto/role.meta.json +18 -0
- package/templates/roles/customer-success/AGENTS.md +42 -0
- package/templates/roles/customer-success/HEARTBEAT.md +33 -0
- package/templates/roles/customer-success/SOUL.md +17 -0
- package/templates/roles/customer-success/TOOLS.md +3 -0
- package/templates/roles/customer-success/role.meta.json +17 -0
- package/templates/roles/devops/AGENTS.md +31 -0
- package/templates/roles/devops/HEARTBEAT.md +42 -0
- package/templates/roles/devops/SOUL.md +17 -0
- package/templates/roles/devops/TOOLS.md +3 -0
- package/templates/roles/devops/role.meta.json +17 -0
- package/templates/roles/engineer/AGENTS.md +29 -0
- package/templates/roles/engineer/HEARTBEAT.md +39 -0
- package/templates/roles/engineer/SOUL.md +20 -0
- package/templates/roles/engineer/TOOLS.md +3 -0
- package/templates/roles/engineer/role.meta.json +13 -0
- package/templates/roles/game-artist/AGENTS.md +29 -0
- package/templates/roles/game-artist/HEARTBEAT.md +37 -0
- package/templates/roles/game-artist/SOUL.md +24 -0
- package/templates/roles/game-artist/TOOLS.md +3 -0
- package/templates/roles/game-artist/role.meta.json +14 -0
- package/templates/roles/game-designer/AGENTS.md +29 -0
- package/templates/roles/game-designer/HEARTBEAT.md +37 -0
- package/templates/roles/game-designer/SOUL.md +17 -0
- package/templates/roles/game-designer/TOOLS.md +3 -0
- package/templates/roles/game-designer/role.meta.json +14 -0
- package/templates/roles/level-designer/AGENTS.md +29 -0
- package/templates/roles/level-designer/HEARTBEAT.md +37 -0
- package/templates/roles/level-designer/SOUL.md +17 -0
- package/templates/roles/level-designer/TOOLS.md +3 -0
- package/templates/roles/level-designer/role.meta.json +13 -0
- package/templates/roles/product-owner/AGENTS.md +29 -0
- package/templates/roles/product-owner/HEARTBEAT.md +35 -0
- package/templates/roles/product-owner/SOUL.md +17 -0
- package/templates/roles/product-owner/TOOLS.md +3 -0
- package/templates/roles/product-owner/role.meta.json +14 -0
- package/templates/roles/qa/AGENTS.md +31 -0
- package/templates/roles/qa/HEARTBEAT.md +37 -0
- package/templates/roles/qa/SOUL.md +17 -0
- package/templates/roles/qa/TOOLS.md +3 -0
- package/templates/roles/qa/role.meta.json +17 -0
- package/templates/roles/security-engineer/AGENTS.md +42 -0
- package/templates/roles/security-engineer/HEARTBEAT.md +33 -0
- package/templates/roles/security-engineer/SOUL.md +17 -0
- package/templates/roles/security-engineer/TOOLS.md +3 -0
- package/templates/roles/security-engineer/role.meta.json +17 -0
- package/templates/roles/technical-writer/AGENTS.md +41 -0
- package/templates/roles/technical-writer/HEARTBEAT.md +32 -0
- package/templates/roles/technical-writer/SOUL.md +17 -0
- package/templates/roles/technical-writer/TOOLS.md +3 -0
- package/templates/roles/technical-writer/role.meta.json +16 -0
- package/templates/roles/ui-designer/AGENTS.md +29 -0
- package/templates/roles/ui-designer/HEARTBEAT.md +37 -0
- package/templates/roles/ui-designer/SOUL.md +17 -0
- package/templates/roles/ui-designer/TOOLS.md +3 -0
- package/templates/roles/ui-designer/role.meta.json +17 -0
- package/templates/roles/ux-researcher/AGENTS.md +29 -0
- package/templates/roles/ux-researcher/HEARTBEAT.md +37 -0
- package/templates/roles/ux-researcher/SOUL.md +17 -0
- package/templates/roles/ux-researcher/TOOLS.md +3 -0
- package/templates/roles/ux-researcher/role.meta.json +14 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# Engine Guide: Phaser
|
|
2
|
+
|
|
3
|
+
Phaser is a 2D HTML5 game framework. Use it for: platformers, top-down RPGs, puzzle games, arcade games, visual novels — anything 2D that runs in the browser.
|
|
4
|
+
|
|
5
|
+
## Project Setup
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm create @phaserjs/game@latest my-game
|
|
9
|
+
cd my-game && npm install
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Or manually:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm init -y && npm install phaser
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Minimal game entry:
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
import Phaser from 'phaser';
|
|
22
|
+
|
|
23
|
+
const config = {
|
|
24
|
+
type: Phaser.AUTO, // WebGL with Canvas fallback
|
|
25
|
+
width: 800,
|
|
26
|
+
height: 600,
|
|
27
|
+
physics: {
|
|
28
|
+
default: 'arcade',
|
|
29
|
+
arcade: { gravity: { y: 300 }, debug: false }
|
|
30
|
+
},
|
|
31
|
+
scene: { preload, create, update }
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const game = new Phaser.Game(config);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Core Architecture
|
|
38
|
+
|
|
39
|
+
### Scenes
|
|
40
|
+
|
|
41
|
+
Scenes are the fundamental organizational unit. Every screen (menu, gameplay, pause, game over) is a Scene.
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
class GameScene extends Phaser.Scene {
|
|
45
|
+
constructor() { super('GameScene'); }
|
|
46
|
+
|
|
47
|
+
preload() {
|
|
48
|
+
this.load.image('sky', 'assets/sky.png');
|
|
49
|
+
this.load.spritesheet('player', 'assets/player.png', {
|
|
50
|
+
frameWidth: 32, frameHeight: 48
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
create() {
|
|
55
|
+
this.add.image(400, 300, 'sky');
|
|
56
|
+
this.player = this.physics.add.sprite(100, 450, 'player');
|
|
57
|
+
this.player.setBounce(0.2);
|
|
58
|
+
this.player.setCollideWorldBounds(true);
|
|
59
|
+
this.cursors = this.input.keyboard.createCursorKeys();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
update() {
|
|
63
|
+
if (this.cursors.left.isDown) {
|
|
64
|
+
this.player.setVelocityX(-160);
|
|
65
|
+
this.player.anims.play('left', true);
|
|
66
|
+
} else if (this.cursors.right.isDown) {
|
|
67
|
+
this.player.setVelocityX(160);
|
|
68
|
+
this.player.anims.play('right', true);
|
|
69
|
+
} else {
|
|
70
|
+
this.player.setVelocityX(0);
|
|
71
|
+
this.player.anims.play('idle', true);
|
|
72
|
+
}
|
|
73
|
+
if (this.cursors.up.isDown && this.player.body.touching.down) {
|
|
74
|
+
this.player.setVelocityY(-330);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Scene transitions:
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
this.scene.start('GameOverScene', { score: this.score }); // switch scene
|
|
84
|
+
this.scene.launch('PauseScene'); // run in parallel (overlay)
|
|
85
|
+
this.scene.pause(); // pause this scene
|
|
86
|
+
this.scene.resume('GameScene'); // resume a paused scene
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Physics
|
|
90
|
+
|
|
91
|
+
**Arcade** — fast, AABB-only. Use for most 2D games.
|
|
92
|
+
|
|
93
|
+
```javascript
|
|
94
|
+
// Static group (platforms, walls)
|
|
95
|
+
const platforms = this.physics.add.staticGroup();
|
|
96
|
+
platforms.create(400, 568, 'ground').setScale(2).refreshBody();
|
|
97
|
+
|
|
98
|
+
// Dynamic sprites
|
|
99
|
+
const player = this.physics.add.sprite(100, 450, 'player');
|
|
100
|
+
player.setBounce(0.2);
|
|
101
|
+
player.setCollideWorldBounds(true);
|
|
102
|
+
|
|
103
|
+
// Collisions
|
|
104
|
+
this.physics.add.collider(player, platforms);
|
|
105
|
+
|
|
106
|
+
// Overlap (pickup items)
|
|
107
|
+
this.physics.add.overlap(player, stars, collectStar, null, this);
|
|
108
|
+
|
|
109
|
+
function collectStar(player, star) {
|
|
110
|
+
star.disableBody(true, true); // remove from physics + hide
|
|
111
|
+
score += 10;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Matter** — full rigid body physics with polygons, constraints, joints. Use when you need realistic physics (ragdolls, chains, complex shapes).
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
const config = {
|
|
119
|
+
physics: {
|
|
120
|
+
default: 'matter',
|
|
121
|
+
matter: { gravity: { y: 1 }, debug: true }
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// Matter body
|
|
126
|
+
const box = this.matter.add.image(400, 200, 'box');
|
|
127
|
+
box.setFriction(0.005);
|
|
128
|
+
box.setBounce(0.6);
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Animations
|
|
132
|
+
|
|
133
|
+
```javascript
|
|
134
|
+
this.anims.create({
|
|
135
|
+
key: 'walk',
|
|
136
|
+
frames: this.anims.generateFrameNumbers('player', { start: 0, end: 7 }),
|
|
137
|
+
frameRate: 10,
|
|
138
|
+
repeat: -1 // -1 = loop forever
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
this.anims.create({
|
|
142
|
+
key: 'idle',
|
|
143
|
+
frames: [{ key: 'player', frame: 4 }],
|
|
144
|
+
frameRate: 20
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
sprite.anims.play('walk', true); // true = ignore if already playing
|
|
148
|
+
sprite.on('animationcomplete', (anim) => { /* ... */ });
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Tilemaps
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
preload() {
|
|
155
|
+
this.load.tilemapTiledJSON('map', 'assets/map.json'); // Tiled editor export
|
|
156
|
+
this.load.image('tiles', 'assets/tileset.png');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
create() {
|
|
160
|
+
const map = this.make.tilemap({ key: 'map' });
|
|
161
|
+
const tileset = map.addTilesetImage('tileset-name', 'tiles');
|
|
162
|
+
const ground = map.createLayer('Ground', tileset);
|
|
163
|
+
const walls = map.createLayer('Walls', tileset);
|
|
164
|
+
|
|
165
|
+
walls.setCollisionByProperty({ collides: true });
|
|
166
|
+
this.physics.add.collider(this.player, walls);
|
|
167
|
+
|
|
168
|
+
// Object layer spawn points
|
|
169
|
+
const spawnPoint = map.findObject('Objects', obj => obj.name === 'Spawn');
|
|
170
|
+
this.player.setPosition(spawnPoint.x, spawnPoint.y);
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Input
|
|
175
|
+
|
|
176
|
+
```javascript
|
|
177
|
+
// Keyboard
|
|
178
|
+
const cursors = this.input.keyboard.createCursorKeys();
|
|
179
|
+
const wasd = this.input.keyboard.addKeys('W,A,S,D');
|
|
180
|
+
const space = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE);
|
|
181
|
+
|
|
182
|
+
// Pointer (mouse + touch)
|
|
183
|
+
this.input.on('pointerdown', (pointer) => {
|
|
184
|
+
console.log(pointer.x, pointer.y, pointer.button);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Gamepad
|
|
188
|
+
this.input.gamepad.on('connected', (pad) => { /* ... */ });
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Camera
|
|
192
|
+
|
|
193
|
+
```javascript
|
|
194
|
+
this.cameras.main.startFollow(this.player, true, 0.08, 0.08);
|
|
195
|
+
this.cameras.main.setZoom(2);
|
|
196
|
+
this.cameras.main.setBounds(0, 0, map.widthInPixels, map.heightInPixels);
|
|
197
|
+
this.cameras.main.fadeIn(500);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Audio
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
preload() {
|
|
204
|
+
this.load.audio('bgm', 'assets/music.ogg');
|
|
205
|
+
this.load.audio('jump', 'assets/jump.wav');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
create() {
|
|
209
|
+
this.bgm = this.sound.add('bgm', { loop: true, volume: 0.5 });
|
|
210
|
+
this.bgm.play();
|
|
211
|
+
|
|
212
|
+
this.jumpSfx = this.sound.add('jump');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Play on event
|
|
216
|
+
this.jumpSfx.play();
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Groups
|
|
220
|
+
|
|
221
|
+
```javascript
|
|
222
|
+
const enemies = this.physics.add.group({
|
|
223
|
+
key: 'enemy',
|
|
224
|
+
repeat: 5,
|
|
225
|
+
setXY: { x: 100, y: 0, stepX: 120 }
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
enemies.children.iterate((child) => {
|
|
229
|
+
child.setBounceY(Phaser.Math.FloatBetween(0.2, 0.4));
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Project Structure Convention
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
src/
|
|
237
|
+
├── scenes/
|
|
238
|
+
│ ├── BootScene.js # Asset loading
|
|
239
|
+
│ ├── MenuScene.js # Title screen
|
|
240
|
+
│ ├── GameScene.js # Main gameplay
|
|
241
|
+
│ └── GameOverScene.js # End screen
|
|
242
|
+
├── objects/
|
|
243
|
+
│ ├── Player.js # Player class extending Phaser.Physics.Arcade.Sprite
|
|
244
|
+
│ └── Enemy.js
|
|
245
|
+
├── config/
|
|
246
|
+
│ └── constants.js # Tuning parameters (speeds, gravity, scores)
|
|
247
|
+
└── main.js # Game config + scene registration
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## Tuning Parameters Pattern
|
|
251
|
+
|
|
252
|
+
Expose all balance values as importable constants — never hardcode in game logic:
|
|
253
|
+
|
|
254
|
+
```javascript
|
|
255
|
+
// config/constants.js
|
|
256
|
+
export const PLAYER = {
|
|
257
|
+
SPEED: 160,
|
|
258
|
+
JUMP_VELOCITY: -330,
|
|
259
|
+
BOUNCE: 0.2,
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export const ENEMIES = {
|
|
263
|
+
SPEED: 80,
|
|
264
|
+
SPAWN_INTERVAL: 3000,
|
|
265
|
+
};
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Common Patterns
|
|
269
|
+
|
|
270
|
+
### State machine for player/enemy states
|
|
271
|
+
|
|
272
|
+
```javascript
|
|
273
|
+
class Player extends Phaser.Physics.Arcade.Sprite {
|
|
274
|
+
constructor(scene, x, y) {
|
|
275
|
+
super(scene, x, y, 'player');
|
|
276
|
+
scene.add.existing(this);
|
|
277
|
+
scene.physics.add.existing(this);
|
|
278
|
+
this.state = 'idle';
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
update(cursors) {
|
|
282
|
+
switch (this.state) {
|
|
283
|
+
case 'idle': this.handleIdle(cursors); break;
|
|
284
|
+
case 'running': this.handleRunning(cursors); break;
|
|
285
|
+
case 'jumping': this.handleJumping(cursors); break;
|
|
286
|
+
case 'hurt': this.handleHurt(); break;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Scene data passing
|
|
293
|
+
|
|
294
|
+
```javascript
|
|
295
|
+
// From GameScene
|
|
296
|
+
this.scene.start('GameOverScene', { score: this.score, level: this.level });
|
|
297
|
+
|
|
298
|
+
// In GameOverScene
|
|
299
|
+
create(data) {
|
|
300
|
+
this.add.text(400, 300, `Score: ${data.score}`, { fontSize: '32px' });
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Performance Notes
|
|
305
|
+
|
|
306
|
+
- Phaser.AUTO picks WebGL when available, falls back to Canvas
|
|
307
|
+
- Use texture atlases (spritesheet packer) instead of individual images to reduce draw calls
|
|
308
|
+
- Object pooling: reuse sprites with `group.get()` instead of creating/destroying
|
|
309
|
+
- Minimize physics bodies — disable physics on off-screen objects
|
|
310
|
+
- Use `this.cameras.main.ignore(uiLayer)` to exclude UI from game camera transforms
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Engine Guide: PixiJS
|
|
2
|
+
|
|
3
|
+
PixiJS is a fast 2D rendering engine (not a full game framework). Use it for: games where you want full control over the game loop, custom physics, or non-standard rendering. Also great for interactive visualizations, animated UIs, and creative coding. Runs on WebGL/WebGPU with Canvas fallback.
|
|
4
|
+
|
|
5
|
+
PixiJS handles rendering. You build the game loop, physics, input handling, and scene management yourself (or bring a library).
|
|
6
|
+
|
|
7
|
+
## Project Setup
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm init -y && npm install pixi.js
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Core Architecture
|
|
14
|
+
|
|
15
|
+
### Application and Game Loop
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
import { Application, Assets, Sprite, Ticker } from 'pixi.js';
|
|
19
|
+
|
|
20
|
+
const app = new Application();
|
|
21
|
+
await app.init({
|
|
22
|
+
width: 800,
|
|
23
|
+
height: 600,
|
|
24
|
+
backgroundColor: 0x1099bb,
|
|
25
|
+
antialias: true,
|
|
26
|
+
resolution: window.devicePixelRatio,
|
|
27
|
+
preference: 'webgl', // or 'webgpu'
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
document.body.appendChild(app.canvas);
|
|
31
|
+
|
|
32
|
+
// Game loop via ticker
|
|
33
|
+
app.ticker.add((ticker) => {
|
|
34
|
+
// ticker.deltaTime = dimensionless scalar (~1.0 at 60fps)
|
|
35
|
+
// ticker.deltaMS = milliseconds since last frame
|
|
36
|
+
update(ticker.deltaTime);
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Display Objects and Scene Graph
|
|
41
|
+
|
|
42
|
+
PixiJS uses a tree of display objects. `app.stage` is the root container.
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
import { Container, Sprite, Graphics, Text } from 'pixi.js';
|
|
46
|
+
|
|
47
|
+
// Containers group display objects
|
|
48
|
+
const gameWorld = new Container();
|
|
49
|
+
const uiLayer = new Container();
|
|
50
|
+
app.stage.addChild(gameWorld);
|
|
51
|
+
app.stage.addChild(uiLayer); // UI renders on top
|
|
52
|
+
|
|
53
|
+
// Sprites
|
|
54
|
+
const texture = await Assets.load('player.png');
|
|
55
|
+
const player = new Sprite(texture);
|
|
56
|
+
player.anchor.set(0.5); // center origin
|
|
57
|
+
player.x = 400;
|
|
58
|
+
player.y = 300;
|
|
59
|
+
gameWorld.addChild(player);
|
|
60
|
+
|
|
61
|
+
// Graphics (primitives)
|
|
62
|
+
const rect = new Graphics();
|
|
63
|
+
rect.rect(0, 0, 50, 50);
|
|
64
|
+
rect.fill(0xff0000);
|
|
65
|
+
gameWorld.addChild(rect);
|
|
66
|
+
|
|
67
|
+
// Text
|
|
68
|
+
const scoreText = new Text({ text: 'Score: 0', style: { fontSize: 24, fill: 0xffffff } });
|
|
69
|
+
uiLayer.addChild(scoreText);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Asset Loading
|
|
73
|
+
|
|
74
|
+
```javascript
|
|
75
|
+
import { Assets, Spritesheet } from 'pixi.js';
|
|
76
|
+
|
|
77
|
+
// Single asset
|
|
78
|
+
const texture = await Assets.load('bunny.png');
|
|
79
|
+
|
|
80
|
+
// Multiple assets
|
|
81
|
+
const textures = await Assets.load(['player.png', 'enemy.png', 'tileset.png']);
|
|
82
|
+
|
|
83
|
+
// Asset bundles (recommended for larger games)
|
|
84
|
+
Assets.addBundle('game', {
|
|
85
|
+
player: 'assets/player.png',
|
|
86
|
+
enemy: 'assets/enemy.png',
|
|
87
|
+
tileset: 'assets/tileset.png',
|
|
88
|
+
spritesheet: 'assets/sprites.json',
|
|
89
|
+
});
|
|
90
|
+
const assets = await Assets.loadBundle('game');
|
|
91
|
+
|
|
92
|
+
// Background loading with progress
|
|
93
|
+
Assets.loadBundle('game', (progress) => {
|
|
94
|
+
console.log(`Loading: ${Math.round(progress * 100)}%`);
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Spritesheet Animations
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
import { AnimatedSprite, Assets, Texture } from 'pixi.js';
|
|
102
|
+
|
|
103
|
+
// Load spritesheet (JSON + PNG)
|
|
104
|
+
await Assets.load('spritesheet.json');
|
|
105
|
+
|
|
106
|
+
// Create frames array
|
|
107
|
+
const frames = [];
|
|
108
|
+
for (let i = 0; i < 8; i++) {
|
|
109
|
+
frames.push(Texture.from(`walk_${i.toString().padStart(4, '0')}.png`));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const animation = new AnimatedSprite(frames);
|
|
113
|
+
animation.anchor.set(0.5);
|
|
114
|
+
animation.animationSpeed = 0.15; // speed multiplier
|
|
115
|
+
animation.loop = true;
|
|
116
|
+
animation.play();
|
|
117
|
+
|
|
118
|
+
// Events
|
|
119
|
+
animation.onComplete = () => { /* non-looping animation finished */ };
|
|
120
|
+
animation.onFrameChange = (frame) => { /* trigger SFX on specific frames */ };
|
|
121
|
+
|
|
122
|
+
// Controls
|
|
123
|
+
animation.gotoAndPlay(0); // restart
|
|
124
|
+
animation.gotoAndStop(3); // freeze on frame
|
|
125
|
+
animation.stop();
|
|
126
|
+
|
|
127
|
+
gameWorld.addChild(animation);
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Input Handling
|
|
131
|
+
|
|
132
|
+
PixiJS has pointer events on display objects. For keyboard, use the browser directly.
|
|
133
|
+
|
|
134
|
+
```javascript
|
|
135
|
+
// Pointer events on sprites
|
|
136
|
+
sprite.eventMode = 'static'; // enable interaction
|
|
137
|
+
sprite.cursor = 'pointer';
|
|
138
|
+
sprite.on('pointerdown', (event) => { /* click/tap */ });
|
|
139
|
+
sprite.on('pointerover', () => { /* hover */ });
|
|
140
|
+
|
|
141
|
+
// Keyboard (browser API — build your own input manager)
|
|
142
|
+
const keys = {};
|
|
143
|
+
window.addEventListener('keydown', (e) => { keys[e.code] = true; });
|
|
144
|
+
window.addEventListener('keyup', (e) => { keys[e.code] = false; });
|
|
145
|
+
|
|
146
|
+
// In game loop
|
|
147
|
+
function update(dt) {
|
|
148
|
+
if (keys['ArrowLeft']) player.x -= SPEED * dt;
|
|
149
|
+
if (keys['ArrowRight']) player.x += SPEED * dt;
|
|
150
|
+
if (keys['Space']) jump();
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Ticker (Game Loop) Control
|
|
155
|
+
|
|
156
|
+
```javascript
|
|
157
|
+
import { Ticker, UPDATE_PRIORITY } from 'pixi.js';
|
|
158
|
+
|
|
159
|
+
// Priority-based updates (higher priority runs first)
|
|
160
|
+
app.ticker.add((ticker) => {
|
|
161
|
+
physics.update(ticker.deltaTime);
|
|
162
|
+
}, undefined, UPDATE_PRIORITY.HIGH);
|
|
163
|
+
|
|
164
|
+
app.ticker.add((ticker) => {
|
|
165
|
+
render(ticker.deltaTime);
|
|
166
|
+
}, undefined, UPDATE_PRIORITY.NORMAL);
|
|
167
|
+
|
|
168
|
+
// Speed control (slow motion / fast forward)
|
|
169
|
+
app.ticker.speed = 0.5; // half speed
|
|
170
|
+
app.ticker.speed = 2.0; // double speed
|
|
171
|
+
|
|
172
|
+
// Cap minimum FPS (prevents huge delta spikes on tab-away)
|
|
173
|
+
app.ticker.minFPS = 30;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Building a Game with PixiJS
|
|
177
|
+
|
|
178
|
+
Since PixiJS is a renderer, you need to build or bring these yourself:
|
|
179
|
+
|
|
180
|
+
### Scene Manager Pattern
|
|
181
|
+
|
|
182
|
+
```javascript
|
|
183
|
+
class SceneManager {
|
|
184
|
+
constructor(app) {
|
|
185
|
+
this.app = app;
|
|
186
|
+
this.currentScene = null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
switchTo(SceneClass, data = {}) {
|
|
190
|
+
if (this.currentScene) {
|
|
191
|
+
this.app.ticker.remove(this.currentScene.update, this.currentScene);
|
|
192
|
+
this.currentScene.destroy();
|
|
193
|
+
this.app.stage.removeChild(this.currentScene.container);
|
|
194
|
+
}
|
|
195
|
+
this.currentScene = new SceneClass(this.app, this, data);
|
|
196
|
+
this.app.stage.addChild(this.currentScene.container);
|
|
197
|
+
this.app.ticker.add(this.currentScene.update, this.currentScene);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
class GameScene {
|
|
202
|
+
constructor(app, manager, data) {
|
|
203
|
+
this.container = new Container();
|
|
204
|
+
this.manager = manager;
|
|
205
|
+
// set up game objects...
|
|
206
|
+
}
|
|
207
|
+
update(ticker) { /* game loop */ }
|
|
208
|
+
destroy() { this.container.destroy({ children: true }); }
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Simple AABB Collision
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
function intersects(a, b) {
|
|
216
|
+
return a.x < b.x + b.width &&
|
|
217
|
+
a.x + a.width > b.x &&
|
|
218
|
+
a.y < b.y + b.height &&
|
|
219
|
+
a.y + a.height > b.y;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// In update loop
|
|
223
|
+
for (const enemy of enemies) {
|
|
224
|
+
if (intersects(player.getBounds(), enemy.getBounds())) {
|
|
225
|
+
handleCollision(player, enemy);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Camera (Viewport) Pattern
|
|
231
|
+
|
|
232
|
+
```javascript
|
|
233
|
+
// Use a container as the "world" and move it to simulate camera
|
|
234
|
+
const world = new Container();
|
|
235
|
+
app.stage.addChild(world);
|
|
236
|
+
|
|
237
|
+
function updateCamera(target) {
|
|
238
|
+
world.x = -target.x + app.screen.width / 2;
|
|
239
|
+
world.y = -target.y + app.screen.height / 2;
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Project Structure Convention
|
|
244
|
+
|
|
245
|
+
```
|
|
246
|
+
src/
|
|
247
|
+
├── scenes/
|
|
248
|
+
│ ├── MenuScene.js
|
|
249
|
+
│ ├── GameScene.js
|
|
250
|
+
│ └── GameOverScene.js
|
|
251
|
+
├── objects/
|
|
252
|
+
│ ├── Player.js
|
|
253
|
+
│ └── Enemy.js
|
|
254
|
+
├── systems/
|
|
255
|
+
│ ├── InputManager.js # Keyboard/pointer state
|
|
256
|
+
│ ├── SceneManager.js # Scene switching
|
|
257
|
+
│ ├── Physics.js # Collision detection
|
|
258
|
+
│ └── Camera.js # Viewport management
|
|
259
|
+
├── config/
|
|
260
|
+
│ └── constants.js # Tuning parameters
|
|
261
|
+
└── main.js # App init, asset loading, scene start
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Tuning Parameters Pattern
|
|
265
|
+
|
|
266
|
+
```javascript
|
|
267
|
+
export const PLAYER = {
|
|
268
|
+
SPEED: 5, // pixels per frame at 60fps
|
|
269
|
+
JUMP_FORCE: -12,
|
|
270
|
+
GRAVITY: 0.5,
|
|
271
|
+
MAX_FALL_SPEED: 10,
|
|
272
|
+
};
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Performance Notes
|
|
276
|
+
|
|
277
|
+
- PixiJS is extremely fast — thousands of sprites at 60fps
|
|
278
|
+
- Use spritesheets/texture atlases to reduce draw calls (TexturePacker, free-tex-packer)
|
|
279
|
+
- `Container.cacheAsChild = true` for complex static containers (renders to texture)
|
|
280
|
+
- Use `ParticleContainer` for large numbers of simple sprites (limited features, big perf gain)
|
|
281
|
+
- Destroy textures and display objects when done: `sprite.destroy({ texture: true })`
|
|
282
|
+
- `app.ticker.minFPS = 30` prevents huge delta spikes when tab is backgrounded
|
|
283
|
+
|
|
284
|
+
## Useful Companion Libraries
|
|
285
|
+
|
|
286
|
+
- **bump.js** or custom AABB — collision detection
|
|
287
|
+
- **pixi-viewport** — camera/viewport with pan, zoom, follow
|
|
288
|
+
- **pixi-sound** — audio playback (PixiJS has no built-in audio)
|
|
289
|
+
- **pixi-filters** — blur, glow, outline, displacement, and other shader effects
|