本页内容

精灵动画

精灵引擎

该 Qt Quick 精灵引擎是一种随机状态机,同时具备将包含动画多帧的图像分割开来的能力。

状态机

精灵引擎的主要功能之一是其内部状态机。这与Qt Quick 中的状态和过渡不同,更类似于传统的状态机。精灵可以具有向其他精灵过渡或返回自身的加权过渡。 当一个精灵动画结束时,精灵引擎会根据刚刚结束的精灵可用的加权过渡规则,随机选择下一个精灵。

您可以通过两种方式影响当前正在播放的精灵:可以任意强制其立即开始播放任意精灵,也可以指示其逐渐过渡到指定的精灵。 若指令其渐变过渡,则系统将通过有效状态转换,以最少的过渡精灵数量(但忽略相对权重)到达目标精灵。这使您能够轻松地在两个不同的精灵之间插入过渡动画。

显示角色在站立、等待、行走和跳跃状态之间转换的状态图

举个例子,请看上图所示的某个假想的2D平台游戏角色的精灵图。角色最初显示的是站立状态。从该状态开始,除非有外部输入,否则他将过渡到等待动画、行走动画,或者再次播放站立动画。 由于这些过渡的权重分别为1、0和3,因此当站立动画结束时,角色有四分之一的机会播放等待动画,有四分之三的机会再次播放站立动画。这使得角色在等待时能够表现出略带动态且多变的行为。

由于向行走动画的过渡权重为零,静止动画通常不会过渡到行走动画。但如果你将目标动画设置为行走动画,则静止动画结束后会播放行走动画。如果角色此前处于等待动画中,它会先播放完该动画,接着播放静止动画,然后播放行走动画。 随后角色将持续播放行走动画,直到目标动画被取消设置;此时,在行走动画结束后,角色将切换回站立动画。

如果你随后将目标状态设置为跳跃动画,它会在播放完行走动画后才开始播放跳跃动画。由于跳跃动画不会过渡到其他状态,因此它会一直播放跳跃动画,直到状态被强制更改为止。 在此示例中,你可以将其重新设为“行走”,并将目标动画改为“行走”或“无”(这将导致它在“行走”动画结束后播放“站立”动画)。请注意,通过强制设置动画,你可以立即开始播放该动画。

输入格式

精灵引擎支持的文件格式与其他 QML 类型(如Image )所支持的文件格式相同。但是,为了对图像进行动画处理,精灵引擎要求图像文件包含动画的所有帧。 这些帧应排列成连续的一行,可以从文件的右边缘折行到文件的左边缘开始的下一行(该行直接位于上一行的正下方)。

显示精灵图中帧编号顺序的网格

以上图为例。 目前,我们只考虑黑色的数字,并假设每个方块为 40x40 像素。通常,图像是从左上角开始读取的。如果你将帧大小指定为 40x40 像素,帧数指定为 8,那么它将按照编号顺序读取帧。 左上角的帧将是第一帧,右上角的帧将是第五帧,然后会循环到下一行(文件中位于像素位置 0,40)以读取第六帧。 在读取完标记为 8 的帧后,读取过程将停止;如果第四帧下方的方块中存在任何图像数据,则该数据不会被包含在动画中。

虽然可以从任意偏移量开始加载动画,但加载模式仍然保持不变。现在考虑红色数字的情况。如果我们指定动画从像素坐标 120,0 开始,帧数为 5,且帧大小与之前相同,那么它将按照红色标注的帧序加载帧。 图像的前 120x40 区域将不会被使用,因为它从 120,0 位置开始读取 40x40 的块。当到达 160,0 的文件末尾时,它会从 0,40 开始读取下一行。

如果尝试从坐标 (40,40) 开始加载两帧该尺寸的动画,蓝色数字即表示帧号。请注意,可以从一个图像文件中加载多个精灵。 红色、蓝色和黑色的数字均可作为独立动画加载到同一个精灵引擎中。以下代码会根据图片所示加载这些动画,并指定动画以每秒 20 帧的速度播放。

Sprite {
    name: "black"
    source: "image.png"
    frameCount: 8
    frameWidth: 40
    frameHeight: 40
    frameRate: 20
}
Sprite {
    name: "red"
    source: "image.png"
    frameX: 120
    frameCount: 5
    frameWidth: 40
    frameHeight: 40
    frameRate: 20
}
Sprite {
    name: "blue"
    source: "image.png"
    frameX: 40
    frameX: 40
    frameCount: 2
    frameWidth: 40
    frameHeight: 40
    frameRate: 20
}

同一动画内的帧必须具有相同大小。但同一文件中的多个动画则无此限制。未指定frameCount 的精灵默认占用整个文件,此时必须指定帧大小。未指定帧大小的精灵默认被视为正方形且占用整个文件(不循环),此时必须指定帧数。

精灵引擎会在内部复制并裁剪图像,以适应更易于读取的内部格式,这会导致一些图形内存限制。由于单个引擎中的所有精灵都必须位于同一张纹理中,因此在嵌入式设备上尝试加载大量不同的动画可能会遇到纹理内存限制。 在这种情况下,控制台会输出包含最大纹理大小的警告信息。

有多种工具可帮助将一组图像转换为精灵图。以下是一些示例:

使用精灵引擎的 QML 类型

可以使用Sprite 类型来定义精灵引擎所需的精灵。该类型包含输入参数、动画时长以及与其他动画的加权过渡。它纯粹是一个数据类,不会进行任何渲染。

SpriteSequence 是一种利用精灵引擎绘制其中定义的精灵的类型。它是一个独立且自包含的精灵引擎,不会与其他精灵引擎交互。Sprite 类型可在使用精灵引擎的类型之间共享,但不会自动进行。 因此,如果您在某个SpriteSequence 中定义了一个精灵,则需要在另一个SpriteSequence 的 sprites 属性中重新定义它(或引用相同的Sprite 类型),才能过渡到该动画。

此外,ImageParticle 可以使用Sprite 类型为每个粒子定义精灵。这同样是每种类型仅有一个精灵引擎。其工作原理与SpriteSequence 类似,但同时也具备ImageParticle 类型所提供的参数化可变性。

AnimatedSprite 类型

对于不需要在动画之间进行过渡的使用场景,请考虑使用AnimatedSprite 类型。该类型采用相同的输入格式来显示精灵动画,但每次仅显示一个。由于没有精灵引擎在后台管理时机和过渡效果,因此它还提供了更精细的手动控制。

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.