$npx -y skills add Yakoub-ai/phaser4-gamedev --skill phaser-gameobjThis skill should be used when the user asks to "add a sprite", "create a player", "add text to game", "create particles", "add a tilemap", "create a group", "add a container", "create game objects", "draw shapes", "add UI elements", "create a camera", "add depth", or needs to ad
| 1 | # Phaser 4 Game Objects |
| 2 | |
| 3 | Choose the right game object type for each use case. Every object is created with `this.add.*` (visual only) or `this.physics.add.*` (with Arcade Physics body). |
| 4 | |
| 5 | ## Object Type Reference |
| 6 | |
| 7 | ### Sprite — Animated, interactive, can have physics |
| 8 | |
| 9 | ```typescript |
| 10 | // Static display sprite (no physics) |
| 11 | const sprite = this.add.sprite(x, y, 'textureKey'); |
| 12 | const sprite = this.add.sprite(x, y, 'atlas', 'frameName.png'); // atlas frame |
| 13 | |
| 14 | // Physics sprite (dynamic body, affected by gravity/velocity) |
| 15 | const sprite = this.physics.add.sprite(x, y, 'textureKey'); |
| 16 | |
| 17 | // Configure physics body |
| 18 | (sprite.body as Phaser.Physics.Arcade.Body) |
| 19 | .setSize(24, 32) // hitbox size (smaller than visual for player) |
| 20 | .setOffset(4, 8) // offset from sprite origin |
| 21 | .setMaxVelocity(300, 600); // cap velocity |
| 22 | |
| 23 | // Common sprite settings |
| 24 | sprite.setOrigin(0.5, 0.5); // pivot point (default: 0.5, 0.5 = center) |
| 25 | sprite.setScale(2); // scale up |
| 26 | sprite.setAlpha(0.8); // transparency |
| 27 | sprite.setDepth(10); // render order (higher = on top) |
| 28 | sprite.setFlipX(true); // mirror horizontally |
| 29 | sprite.setTint(0xff0000); // tint red |
| 30 | sprite.clearTint(); |
| 31 | ``` |
| 32 | |
| 33 | ### Image — Static visual, no animation |
| 34 | |
| 35 | ```typescript |
| 36 | const img = this.add.image(x, y, 'key'); |
| 37 | const img = this.add.image(x, y, 'atlas', 'frame.png'); |
| 38 | |
| 39 | // Useful for: backgrounds, UI panels, static decorations |
| 40 | // Lighter than Sprite (no animation overhead) |
| 41 | img.setScrollFactor(0); // Fixed to camera (for UI) |
| 42 | img.setScrollFactor(0.5); // Parallax at half speed |
| 43 | ``` |
| 44 | |
| 45 | ### Text — Dynamic text display |
| 46 | |
| 47 | ```typescript |
| 48 | const text = this.add.text(x, y, 'Score: 0', { |
| 49 | fontSize: '24px', |
| 50 | fontFamily: 'Arial, sans-serif', |
| 51 | color: '#ffffff', |
| 52 | stroke: '#000000', |
| 53 | strokeThickness: 4, |
| 54 | align: 'center', |
| 55 | backgroundColor: '#333333', |
| 56 | padding: { x: 8, y: 4 }, |
| 57 | wordWrap: { width: 400, useAdvancedWrap: true }, |
| 58 | }); |
| 59 | |
| 60 | text.setText('Score: 100'); // update text |
| 61 | text.setScrollFactor(0); // fixed to camera (HUD) |
| 62 | ``` |
| 63 | |
| 64 | **BitmapText** — faster for many text objects (renders as texture): |
| 65 | ```typescript |
| 66 | // Must load bitmap font first in preload: |
| 67 | this.load.bitmapFont('arcade', 'assets/fonts/arcade.png', 'assets/fonts/arcade.xml'); |
| 68 | |
| 69 | const bmpText = this.add.bitmapText(x, y, 'arcade', 'Score: 0', 32); |
| 70 | bmpText.setText('Score: 100'); |
| 71 | ``` |
| 72 | |
| 73 | ### Graphics — Draw shapes programmatically |
| 74 | |
| 75 | ```typescript |
| 76 | const gfx = this.add.graphics(); |
| 77 | |
| 78 | // Filled shapes |
| 79 | gfx.fillStyle(0xff0000, 1.0); // color, alpha |
| 80 | gfx.fillRect(x, y, width, height); |
| 81 | gfx.fillCircle(x, y, radius); |
| 82 | gfx.fillTriangle(x1,y1, x2,y2, x3,y3); |
| 83 | |
| 84 | // Stroked shapes |
| 85 | gfx.lineStyle(2, 0xffffff, 1.0); // lineWidth, color, alpha |
| 86 | gfx.strokeRect(x, y, width, height); |
| 87 | gfx.strokeCircle(x, y, radius); |
| 88 | |
| 89 | // Paths |
| 90 | gfx.beginPath(); |
| 91 | gfx.moveTo(x1, y1); |
| 92 | gfx.lineTo(x2, y2); |
| 93 | gfx.closePath(); |
| 94 | gfx.strokePath(); |
| 95 | |
| 96 | gfx.clear(); // erase everything (call each frame if updating) |
| 97 | ``` |
| 98 | |
| 99 | ### Container — Group objects for relative positioning |
| 100 | |
| 101 | ```typescript |
| 102 | // Create a health bar from multiple objects |
| 103 | const healthBar = this.add.container(x, y); |
| 104 | const bg = this.add.graphics().fillStyle(0x333333).fillRect(0, 0, 100, 12); |
| 105 | const bar = this.add.graphics().fillStyle(0x00ff00).fillRect(0, 0, 100, 12); |
| 106 | const label = this.add.text(50, -14, 'HP', { fontSize: '10px' }).setOrigin(0.5); |
| 107 | healthBar.add([bg, bar, label]); |
| 108 | |
| 109 | // All children move/rotate/scale with container |
| 110 | healthBar.setPosition(200, 50); |
| 111 | healthBar.setDepth(10); |
| 112 | // Note: Physics does NOT work on containers — physics lives on individual sprites |
| 113 | ``` |
| 114 | |
| 115 | ### Group — Manage a collection of objects |
| 116 | |
| 117 | ```typescript |
| 118 | // Static group (pool of objects created manually) |
| 119 | const stars = this.add.group(); |
| 120 | for (let i = 0; i < 20; i++) { |
| 121 | stars.add(this.add.sprite( |
| 122 | Phaser.Math.Between(0, 800), |
| 123 | Phaser.Math.Between(0, 600), |
| 124 | 'star' |
| 125 | )); |
| 126 | } |
| 127 | |
| 128 | // Physics group with automatic pooling |
| 129 | const bullets = this.physics.add.group({ |
| 130 | classType: Bullet, // custom class extending Arcade.Sprite |
| 131 | maxSize: 30, |
| 132 | runChildUpdate: true, // calls update() on active members |
| 133 | }); |
| 134 | |
| 135 | // Get a member from the pool |
| 136 | const bullet = bullets.get(x, y) as Bullet; |
| 137 | if (bullet) { |
| 138 | bullet.setActive(true).setVisible(true); |
| 139 | bullet.setVelocityY(-400); |
| 140 | } |
| 141 | |
| 142 | // Static group (for tilemap-like platforms) |
| 143 | const platforms = this.physics.add.staticGroup(); |
| 144 | platforms.create(400, 580, 'platform'); |
| 145 | platforms.create(100, 400, 'platform'); |
| 146 | ``` |
| 147 | |
| 148 | ### Particles — Visual effects |
| 149 | |
| 150 | ```typescript |
| 151 | // Phaser 4 particles API (same pattern as late v3) |
| 152 | const emitter = this.add.particles(0, 0, 'star', { |
| 153 | speed: { min: 50, max: 150 }, |
| 154 | scale: { s |