mcpField
S
sprites-and-images

sprites-and-images

github.com/phaserjs开发40.6k1.1k 次安装10 周前更新
代码仓库

关于 sprites-and-images

面向 Phaser 4 开发者的技能参考,介绍 Image 和 Sprite 游戏对象的创建与操作,涵盖两者的组件系统及专用显示对象。

主要功能

  1. 01创建 Image 和 Sprite
  2. 02选择纹理与帧
  3. 03变换、色调、透明度和深度控制
  4. 04共享组件混入说明
  5. 05NineSlice、TileSprite 与 Blitter 用法

适用场景

  1. 01为游戏对象选择 Image 或 Sprite
  2. 02运行时更换纹理或帧
  3. 03缩放面板且保持边角尺寸
  4. 04渲染大量轻量静态对象

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/phaserjs/phaser --skill sprites-and-images

安装后在 Claude Code 中输入/sprites-and-images确认已加载。

附带文件references/REFERENCE.md

详细介绍

Sprite 和 Image

在 Phaser 4 中创建和操作 Sprite 与 Image 游戏对象——工厂方法、纹理/帧选择、组件混入系统,以及常见的视觉操作(位置、缩放、旋转、着色、翻转、透明度、原点、深度)。

关键源码路径: src/gameobjects/sprite/、src/gameobjects/image/、src/gameobjects/GameObject.js、src/gameobjects/components/ 相关技能: ../loading-assets/SKILL.md、../animations/SKILL.md、../physics-arcade/SKILL.md、../game-object-components/SKILL.md

快速开始

// In a Scene's create() method:

// Static image (no animation support, slightly cheaper)
const bg = this.add.image(400, 300, 'background');

// Sprite (supports animations)
const player = this.add.sprite(100, 200, 'player', 'idle-0');

// Common operations -- all methods return `this` for chaining
player.setPosition(200, 300);
player.setScale(2);
player.setAngle(45);
player.setTint(0xff0000);
player.setAlpha(0.8);
player.setOrigin(0, 1);       // bottom-left
player.setDepth(10);
player.setFlip(true, false);  // flip horizontally
player.setVisible(false);

// Chained
this.add.sprite(100, 100, 'coin')
    .setScale(0.5)
    .setTint(0xffff00)
    .play('spin');

核心概念

Sprite 与 Image

两者都继承自 GameObject,并共享同一组组件混入。唯一的区别是 Sprite 包含一个 AnimationState 实例(sprite.anims)以及动画便捷方法(play、stop、chain 等)。

特性ImageSprite
静态纹理显示是是
着色、透明度、翻转、缩放、旋转是是
物理刚体是是
输入 / 命中区域是是
动画(play、stop、chain)否是
每帧调用 preUpdate否是(更新动画)
添加到 Scene 的 updateList否是

经验法则: 对于任何不需要逐帧动画的对象,使用 Image。它省去了每帧 preUpdate 的开销,并且 API 表面积更小。仅当需要 Animation 组件时才使用 Sprite。

组件混入系统

Phaser 通过将组件对象混入原型来构建游戏对象类。Sprite 和 Image 共享完全相同的 Mixins 数组(来源于 src/gameobjects/sprite/Sprite.js 和 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)
]

基类 GameObject 本身混入了:

Mixins: [
    Components.Filters,
    Components.RenderSteps
]

每个组件都会为每个实例添加特定的属性和方法。例如,Components.Transform 添加了 x、y、scale、rotation、setPosition() 等。可用组件的完整列表位于 src/gameobjects/components/index.js。

对 Agent 的关键点: 当你在 Sprite 上看到 setAlpha() 这样的方法时,它来自 Components.Alpha,而不是 Sprite 类本身。组件源文件是该方法签名和行为的权威参考。

纹理与帧

Sprite 和 Image 都使用 TextureCrop 组件,它提供:

  • texture -- Phaser.Textures.Texture 实例
  • frame -- 当前的 Phaser.Textures.Frame 实例
  • setTexture(key, frame) -- 更改纹理(并可选地更改帧)
  • setFrame(frame, updateSize, updateOrigin) -- 仅更改帧
  • setCrop(x, y, width, height) -- 裁剪纹理的矩形区域
  • isCropped -- 布尔值,在 setCrop 之后切换裁剪开关

工厂方法和构造函数中的 texture 参数接受字符串键(在 Texture Manager 中注册的)或 Phaser.Textures.Texture 实例。

frame 参数接受字符串名称或纹理帧集合中的数字索引。如果省略,则使用基础帧(帧 0 / '__BASE')。

// Change texture at runtime
sprite.setTexture('enemies', 'goblin-walk-1');

// Change only the frame (must belong to current texture)
sprite.setFrame('goblin-walk-2');

// setFrame signature:
// setFrame(frame, updateSize=true, updateOrigin=true)
// Pass false to prevent automatic resize/origin recalculation
sprite.setFrame('small-frame', false, false);

// Crop to show only a 50x50 region starting at (10, 10)
sprite.setCrop(10, 10, 50, 50);
// Reset crop
sprite.setCrop();

常见模式

创建与定位

Transform 组件(src/gameobjects/components/Transform.js):

// Properties (all read/write)
sprite.x           // horizontal position (default: 0)
sprite.y           // vertical position (default: 0)
sprite.z           // z position (does NOT control render order -- use depth)
sprite.w           // w position

// Methods
sprite.setPosition(x, y, z, w)        // y defaults to x if omitted
sprite.setRandomPosition(x, y, w, h)  // random within area; defaults to game size
sprite.copyPosition(source)            // copy from any {x, y} object

Size 组件(src/gameobjects/components/Size.js):

sprite.width            // native (un-scaled) width
sprite.height           // native (un-scaled) height
sprite.displayWidth      // scaled width (read/write -- setting adjusts scaleX)
sprite.displayHeight     // scaled height (read/write -- setting adjusts scaleY)

sprite.setSize(width, height)           // set internal size (not visual)
sprite.setDisplaySize(width, height)    // set visual size (adjusts scale)
sprite.setSizeToFrame(frame)            // reset size to match frame
缩放与旋转

Transform 组件(续):

// Scale properties
sprite.scale       // uniform scale (getter returns average of scaleX+scaleY)
sprite.scaleX      // horizontal scale (default: 1)
sprite.scaleY      // vertical scale (default: 1)

// Scale methods
sprite.setScale(x, y)    // y defaults to x if omitted

// Rotation properties
sprite.rotation    // in radians (right-hand clockwise: 0=right, PI/2=down)
sprite.angle       // in degrees (0=right, 90=down, 180/-180=left, -90=up)

// Rotation methods
sprite.setRotation(radians)   // defaults to 0
sprite.setAngle(degrees)      // defaults to 0
着色与透明度

Tint 组件(src/gameobjects/components/Tint.js)-- 仅限 WebGL:

// Properties
sprite.tint             // overall tint (getter returns tintTopLeft)
sprite.tintTopLeft      // default: 0xffffff
sprite.tintTopRight     // default: 0xffffff
sprite.tintBottomLeft   // default: 0xffffff
sprite.tintBottomRight  // default: 0xffffff
sprite.tintMode         // default: Phaser.TintModes.MULTIPLY
sprite.isTinted         // read-only boolean

// Methods
sprite.setTint(topLeft, topRight, bottomLeft, bottomRight)
// If only topLeft given, applies uniformly to all four corners
sprite.setTintMode(mode)   // Phaser.TintModes.MULTIPLY | FILL | ADD | SCREEN | OVERLAY | HARD_LIGHT
sprite.clearTint()         // resets to 0xffffff + MULTIPLY mode

Phaser 4 变更: setTintFill() 已移除。请改用 setTint(color).setTintMode(Phaser.TintModes.FILL)。

Alpha 组件(src/gameobjects/components/Alpha.js):

// Properties
sprite.alpha             // global alpha 0-1 (default: 1)
sprite.alphaTopLeft      // per-corner alpha (WebGL only)
sprite.alphaTopRight
sprite.alphaBottomLeft
sprite.alphaBottomRight

// Methods
sprite.setAlpha(topLeft, topRight, bottomLeft, bottomRight)
// If only topLeft given, applies uniformly to whole object
sprite.clearAlpha()     // resets to 1 (fully opaque)

将 alpha 设置为 0 会清除渲染标志,因此对象不会被绘制。将其设置回任何非零值即可恢复绘制。

翻转

Flip 组件(src/gameobjects/components/Flip.js):

// Properties
sprite.flipX    // boolean (default: false)
sprite.flipY    // boolean (default: false)

// Methods
sprite.setFlipX(value)        // set horizontal flip
sprite.setFlipY(value)        // set vertical flip
sprite.setFlip(x, y)          // set both at once
sprite.toggleFlipX()          // invert current horizontal flip
sprite.toggleFlipY()          // invert current vertical flip
sprite.resetFlip()            // set both to false

翻转仅是一种渲染开关。它不会影响物理体或命中区域。翻转从纹理中间进行,且不会改变缩放值。

原点与深度

Origin 组件(src/gameobjects/components/Origin.js):

// Properties (normalized 0-1)
sprite.originX          // default: 0.5 (center)
sprite.originY          // default: 0.5 (center)
sprite.displayOriginX   // pixel value (originX * width)
sprite.displayOriginY   // pixel value (originY * height)

// Methods
sprite.setOrigin(x, y)           // y defaults to x; defaults to 0.5
sprite.setDisplayOrigin(x, y)    // set origin in pixels; y defaults to x
sprite.setOriginFromFrame()      // use Frame pivot if set, else 0.5
sprite.updateDisplayOrigin()     // recalculate pixel origin from normalized

Depth 组件(src/gameobjects/components/Depth.js):

// Properties
sprite.depth    // default: 0 (higher = renders on top)

// Methods
sprite.setDepth(value)
sprite.setToTop()              // move to top of display list (no depth change)
sprite.setToBack()             // move to back of display list (no depth change)
sprite.setAbove(gameObject)    // position above another object in the list
sprite.setBelow(gameObject)    // position below another object in the list

设置 depth 会在场景中排队一次深度排序。setToTop/setToBack/setAbove/setBelow 方法会改变显示列表中的位置,但不会修改 depth 值。

销毁游戏对象
sprite.destroy();           // removes from display list, update list, and cleans up
sprite.ignoreDestroy = true; // prevent destruction (you manage lifecycle manually)
sprite.isDestroyed           // boolean, true after destroy() has been called

对于 Sprite,destroy() 还会调用 this.anims.destroy() 来清理 AnimationState。

其他组件

Visible(src/gameobjects/components/Visible.js):

sprite.visible              // boolean (default: true)
sprite.setVisible(value)    // invisible objects skip rendering but still update

ScrollFactor(src/gameobjects/components/ScrollFactor.js):

sprite.scrollFactorX        // default: 1 (moves with camera)
sprite.scrollFactorY        // default: 1
sprite.setScrollFactor(x, y)  // 0 = fixed to camera; y defaults to x

BlendMode(src/gameobjects/components/BlendMode.js):

sprite.blendMode            // default: Phaser.BlendModes.NORMAL
sprite.setBlendMode(value)  // Phaser.BlendModes.ADD, MULTIPLY, SCREEN, ERASE, etc.

性能说明: 更改混合模式会打断 WebGL 批处理。尽可能按混合模式对对象进行分组(例如,将所有 ADD 模式的 Sprite 一起渲染),以尽量减少绘制调用。

工厂方法

this.add.sprite

来源:src/gameobjects/sprite/SpriteFactory.js

// Signature
this.add.sprite(x, y, texture, frame);
参数类型必填描述
xnumber是世界坐标中的水平位置
ynumber是世界坐标中的垂直位置
texturestring | Phaser.Textures.Texture是纹理键或 Texture 实例
framestring | number否纹理中的帧名称或索引

返回:Phaser.GameObjects.Sprite

内部执行:this.displayList.add(new Sprite(this.scene, x, y, texture, frame))

Sprite 构造函数调用:setTexture -> setPosition -> setSizeToFrame -> setOriginFromFrame -> initRenderNodes。

this.add.image

来源:src/gameobjects/image/ImageFactory.js

// Signature
this.add.image(x, y, texture, frame);
参数类型必填描述
xnumber是世界坐标中的水平位置
ynumber是世界坐标中的垂直位置
texturestring | Phaser.Textures.Texture是纹理键或 Texture 实例
framestring | number否纹理中的帧名称或索引

返回:Phaser.GameObjects.Image

内部执行:this.displayList.add(new Image(this.scene, x, y, texture, frame))

Image 构造函数调用与 Sprite 相同的初始化序列:setTexture -> setPosition -> setSizeToFrame -> setOriginFromFrame -> initRenderNodes。

专用游戏对象

NineSlice

具有固定尺寸角和可拉伸边缘/中心的可缩放 UI 面板。非常适合需要调整大小而不扭曲边框的按钮、面板和对话框。

// nineslice(x, y, texture, frame, width, height, leftWidth, rightWidth, topHeight, bottomHeight)
const panel = this.add.nineslice(400, 300, 'panel', null, 300, 200, 20, 20, 20, 20);

// Resize at runtime -- corners stay fixed, edges stretch
panel.setSize(500, 400);
TileSprite

填充区域的重复纹理。在 v4 中支持图集帧以及新的 tileRotation 属性。

const bg = this.add.tileSprite(400, 300, 800, 600, 'grass');

// Scroll the tile in update() for parallax backgrounds
bg.tilePositionX += 0.5;
bg.tilePositionY += 0.25;

// v4: rotate the tile pattern
bg.tileRotation = 0.1;
Blitter

面向大量静态或半静态 Sprite 的高性能批处理渲染。Blitter 子对象(Bobs)没有旋转、缩放或物理特性,但渲染速度比单个 Sprite 显著更快。

const blitter = this.add.blitter(0, 0, 'particles');

// Create Bobs (lightweight display objects)
for (let i = 0; i < 1000; i++) {
    const bob = blitter.create(
        Phaser.Math.Between(0, 800),
        Phaser.Math.Between(0, 600),
        'particle_01'   // frame name within the texture
    );
    bob.setAlpha(Math.random());
}
Video

作为游戏对象进行视频播放,支持位置、缩放和滤镜。

// Load in preload:
this.load.video('intro', 'intro.mp4');

// Create in create:
const video = this.add.video(400, 300, 'intro');
video.play();

有关详细配置选项、API 参考表和源文件映射,请参阅参考指南。

评论

支持 Markdown