| name | sprites-and-images |
| description | Use this skill when creating Sprites or Images in Phaser 4. Covers factory methods, texture/frame selection, position, scale, rotation, tint, flip, alpha, origin, depth, and the component mixin system. Triggers on: Sprite, Image, this.add.sprite, this.add.image, texture, setTint, setAlpha. |
Sprites and Images
Creating and manipulating Sprite and Image game objects in Phaser 4 -- factory methods, texture/frame selection, the component mixin system, and common visual operations (position, scale, rotation, tint, flip, alpha, origin, depth).
Key source paths: src/gameobjects/sprite/, src/gameobjects/image/, src/gameobjects/GameObject.js, src/gameobjects/components/
Related skills: ../loading-assets/SKILL.md, ../animations/SKILL.md, ../physics-arcade/SKILL.md, ../game-object-components/SKILL.md
Quick Start
const bg = this.add.image(400, 300, 'background');
const player = this.add.sprite(100, 200, 'player', 'idle-0');
player.setPosition(200, 300);
player.setScale(2);
player.setAngle(45);
player.setTint(0xff0000);
player.setAlpha(0.8);
player.setOrigin(0, 1);
player.setDepth(10);
player.setFlip(true, false);
player.setVisible(false);
this.add.sprite(100, 100, 'coin')
.setScale(0.5)
.setTint(0xffff00)
.play('spin');
Core Concepts
Sprite vs Image
Both extend GameObject and share the same set of component mixins. The only difference is that Sprite includes an AnimationState instance (sprite.anims) and animation convenience methods (play, stop, chain, etc.).
| Feature | Image | Sprite |
|---|
| Static texture display | Yes | Yes |
| Tint, alpha, flip, scale, rotate | Yes | Yes |
| Physics body | Yes | Yes |
| Input / hit area | Yes | Yes |
Animation (play, stop, chain) | No | Yes |
preUpdate called each frame | No | Yes (updates animation) |
Added to Scene updateList | No | Yes |
Rule of thumb: Use Image for anything that does not need frame-by-frame animation. It skips the per-frame preUpdate cost and has a smaller API surface. Use Sprite only when you need the Animation component.
The Component Mixin System
Phaser builds Game Object classes by mixing component objects into the prototype. Both Sprite and Image share this identical Mixins array (sourced from src/gameobjects/sprite/Sprite.js and src/gameobjects/image/Image.js):
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.Depth,
Components.Flip,
Components.GetBounds,
Components.Lighting,
Components.Mask,
Components.Origin,
Components.RenderNodes,
Components.ScrollFactor,
Components.Size,
Components.TextureCrop,
Components.Tint,
Components.Transform,
Components.Visible,
SpriteRender / ImageRender // render-specific (differs per class)
]
The base GameObject class itself mixes in:
Mixins: [
Components.Filters,
Components.RenderSteps
]
Each component adds specific properties and methods to every instance. For example, Components.Transform adds x, y, scale, rotation, setPosition(), etc. The full list of available components is in src/gameobjects/components/index.js.
Key point for agents: When you see a method like setAlpha() on a Sprite, it comes from Components.Alpha, not from the Sprite class itself. The component source file is the authoritative reference for that method's signature and behavior.
Texture and Frame
Both Sprite and Image use the TextureCrop component which provides:
texture -- the Phaser.Textures.Texture instance
frame -- the current Phaser.Textures.Frame instance
setTexture(key, frame) -- change the texture (and optionally the frame)
setFrame(frame, updateSize, updateOrigin) -- change only the frame
setCrop(x, y, width, height) -- crop a rectangular region of the texture
isCropped -- boolean, toggle cropping on/off after setCrop
The texture parameter in factory methods and constructors accepts either a string key (as registered in the Texture Manager) or a Phaser.Textures.Texture instance.
The frame parameter accepts a string name or numeric index into the texture's frame collection. If omitted, the base frame (frame 0 / '__BASE') is used.
sprite.setTexture('enemies', 'goblin-walk-1');
sprite.setFrame('goblin-walk-2');
sprite.setFrame('small-frame', false, false);
sprite.setCrop(10, 10, 50, 50);
sprite.setCrop();
Common Patterns
Creating and Positioning
Transform component (src/gameobjects/components/Transform.js):
sprite.x
sprite.y
sprite.z
sprite.w
sprite.setPosition(x, y, z, w)
sprite.setRandomPosition(x, y, w, h)
sprite.copyPosition(source)
Size component (src/gameobjects/components/Size.js):
sprite.width
sprite.height
sprite.displayWidth
sprite.displayHeight
sprite.setSize(width, height)
sprite.setDisplaySize(width, height)
sprite.setSizeToFrame(frame)
Scaling and Rotation
Transform component (continued):
sprite.scale
sprite.scaleX
sprite.scaleY
sprite.setScale(x, y)
sprite.rotation
sprite.angle
sprite.setRotation(radians)
sprite.setAngle(degrees)
Tinting and Alpha
Tint component (src/gameobjects/components/Tint.js) -- WebGL only:
sprite.tint
sprite.tintTopLeft
sprite.tintTopRight
sprite.tintBottomLeft
sprite.tintBottomRight
sprite.tintMode
sprite.isTinted
sprite.setTint(topLeft, topRight, bottomLeft, bottomRight)
sprite.setTintMode(mode)
sprite.clearTint()
Phaser 4 change: setTintFill() is removed. Use setTint(color).setTintMode(Phaser.TintModes.FILL) instead.
Alpha component (src/gameobjects/components/Alpha.js):
sprite.alpha
sprite.alphaTopLeft
sprite.alphaTopRight
sprite.alphaBottomLeft
sprite.alphaBottomRight
sprite.setAlpha(topLeft, topRight, bottomLeft, bottomRight)
sprite.clearAlpha()
Setting alpha to 0 clears the render flag so the object is not drawn. Setting it back to any non-zero value restores it.
Flipping
Flip component (src/gameobjects/components/Flip.js):
sprite.flipX
sprite.flipY
sprite.setFlipX(value)
sprite.setFlipY(value)
sprite.setFlip(x, y)
sprite.toggleFlipX()
sprite.toggleFlipY()
sprite.resetFlip()
Flipping is a rendering toggle only. It does not affect physics bodies or hit areas. Flip occurs from the middle of the texture and does not change the scale value.
Origin and Depth
Origin component (src/gameobjects/components/Origin.js):
sprite.originX
sprite.originY
sprite.displayOriginX
sprite.displayOriginY
sprite.setOrigin(x, y)
sprite.setDisplayOrigin(x, y)
sprite.setOriginFromFrame()
sprite.updateDisplayOrigin()
Depth component (src/gameobjects/components/Depth.js):
sprite.depth
sprite.setDepth(value)
sprite.setToTop()
sprite.setToBack()
sprite.setAbove(gameObject)
sprite.setBelow(gameObject)
Setting depth queues a depth sort in the Scene. The setToTop/setToBack/setAbove/setBelow methods change display list position without modifying the depth value.
Destroying Game Objects
sprite.destroy();
sprite.ignoreDestroy = true;
sprite.isDestroyed
For Sprites, destroy() also calls this.anims.destroy() to clean up the AnimationState.
Additional Components
Visible (src/gameobjects/components/Visible.js):
sprite.visible
sprite.setVisible(value)
ScrollFactor (src/gameobjects/components/ScrollFactor.js):
sprite.scrollFactorX
sprite.scrollFactorY
sprite.setScrollFactor(x, y)
BlendMode (src/gameobjects/components/BlendMode.js):
sprite.blendMode
sprite.setBlendMode(value)
Performance note: Changing blend mode breaks WebGL batches. Group objects by blend mode when possible (e.g., render all ADD-mode sprites together) to minimize draw calls.
Factory Methods
this.add.sprite
Source: src/gameobjects/sprite/SpriteFactory.js
this.add.sprite(x, y, texture, frame);
| Param | Type | Required | Description |
|---|
x | number | Yes | Horizontal position in world coordinates |
y | number | Yes | Vertical position in world coordinates |
texture | string | Phaser.Textures.Texture | Yes | Texture key or Texture instance |
frame | string | number | No | Frame name or index within the texture |
Returns: Phaser.GameObjects.Sprite
Internally does: this.displayList.add(new Sprite(this.scene, x, y, texture, frame))
The Sprite constructor calls: setTexture -> setPosition -> setSizeToFrame -> setOriginFromFrame -> initRenderNodes.
this.add.image
Source: src/gameobjects/image/ImageFactory.js
this.add.image(x, y, texture, frame);
| Param | Type | Required | Description |
|---|
x | number | Yes | Horizontal position in world coordinates |
y | number | Yes | Vertical position in world coordinates |
texture | string | Phaser.Textures.Texture | Yes | Texture key or Texture instance |
frame | string | number | No | Frame name or index within the texture |
Returns: Phaser.GameObjects.Image
Internally does: this.displayList.add(new Image(this.scene, x, y, texture, frame))
The Image constructor calls the same init sequence as Sprite: setTexture -> setPosition -> setSizeToFrame -> setOriginFromFrame -> initRenderNodes.
Specialized Game Objects
NineSlice
Scalable UI panels with fixed-size corners and stretchable edges/center. Ideal for buttons, panels, and dialog boxes that need to resize without distorting borders.
const panel = this.add.nineslice(400, 300, 'panel', null, 300, 200, 20, 20, 20, 20);
panel.setSize(500, 400);
TileSprite
Repeating texture that fills an area. Supports atlas frames in v4 and a new tileRotation property.
const bg = this.add.tileSprite(400, 300, 800, 600, 'grass');
bg.tilePositionX += 0.5;
bg.tilePositionY += 0.25;
bg.tileRotation = 0.1;
Blitter
High-performance batched rendering for large numbers of static or semi-static sprites. Blitter children (Bobs) have no rotation, scale, or physics, but render significantly faster than individual Sprites.
const blitter = this.add.blitter(0, 0, 'particles');
for (let i = 0; i < 1000; i++) {
const bob = blitter.create(
Phaser.Math.Between(0, 800),
Phaser.Math.Between(0, 600),
'particle_01'
);
bob.setAlpha(Math.random());
}
Video
Video playback as a game object with position, scale, and filter support.
this.load.video('intro', 'intro.mp4');
const video = this.add.video(400, 300, 'intro');
video.play();
For detailed configuration options, API reference tables, and source file maps, see the reference guide.