本指南讨论如何实现动画精灵并使用相关的 API。
Corona 中所有动画精灵的基础是**图像表单**。这可以比作一张纸,您可以在上面绘制动画对象(一个或多个)的各个帧。根据框架的不同,这也可以称为精灵表单、纹理图集或图像映射。Corona 使用**图像表单**术语(以及通过 graphics.newImageSheet() 创建的对象),因为它们的用法不限于动画精灵。事实上,您也可以将图像表单用于从图像表单的一部分中选取的静态图像(通常应该这样做)。有关图像表单的更多信息,请参阅图像表单指南。
下图是名为 `sprites-cat-running.png` 的正在奔跑的猫的示例图像表单。该表单由按特定顺序排列的八个“帧”组成。从概念上讲,动画从
2048 | |
512 | ![]() |
要在 Corona 中配置此图像表单,首先设置一个具有各种属性的索引表。以下示例使用
local sheetOptions = { width = 512, height = 256, numFrames = 8 }
在此表中,`width` 和 `height` 指定每个帧的像素尺寸。由于有 4 帧宽,并且图像表单的总宽度为 `2048` 像素,因此每帧宽 `512` 像素。类似地,由于有 2 行高,并且表单的总高度为 `512` 像素,因此每帧高 `256` 像素。
下一个参数 `numFrames` 指定图像表单上存在的帧总数。由于奔跑的猫显然有 8 帧动画,因此该值应设置为 `8`。
声明此选项表后,可以通过 graphics.newImageSheet() API 创建图像表单。图像表单文件名应作为第一个参数传递,`options` 表作为第二个参数传递。
local sheet_runningCat = graphics.newImageSheet( "sprites-cat-running.png", sheetOptions )
所有动画精灵都需要至少一个命名**序列**,声明为连续帧或
最基本的序列是连续帧。它接受一个序列名称、起始帧索引、帧数、动画的可选持续时间以及两个可选的循环参数。
-- sequences table local sequences_runningCat = { -- consecutive frames sequence { name = "normalRun", start = 1, count = 8, time = 800, loopCount = 0, loopDirection = "forward" } }
`name` 参数是必需的,可用于将精灵设置为该序列。`start` 和 `count` 参数也是必需的 — 由于奔跑的猫共有 8 帧,因此起始帧可以设置为 `1`,计数设置为 `8`。这告诉序列从第一帧开始并连续播放所有帧直到结束。
接下来,可选的 `time` 参数定义序列的总持续时间(以毫秒为单位)。可以省略此参数,在这种情况下,动画将以应用程序的帧速率进行动画处理(每个时间步一帧)。
`loopCount` 参数定义序列应循环(重复)的次数。将其设置为任何正整数以将序列循环该次数。或者,要无限循环序列,请将 `loopCount` 设置为 `0`。如果设置了循环,您还可以包含 `loopDirection` 参数。设置为 `“forward”` 将从头到尾循环序列,而设置为 `“bounce”` 将从头到尾播放序列,然后反向播放回起始帧。
序列也可以使用
-- sequences table local sequences_runningCat = { -- non-consecutive frames sequence { name = "fastRun", frames = { 1,3,5,7 }, time = 400, loopCount = 0, loopDirection = "forward" } }
序列数据表可以(并且通常会)包含多个序列。这允许您在一个位置定义精灵的所有序列,然后根据序列 `name` 参数设置或更改精灵的序列。
要声明多个序列,只需包含多个以逗号分隔的序列表
-- sequences table local sequences_runningCat = { -- first sequence (consecutive frames) { name = "normalRun", start = 1, count = 8, time = 800, loopCount = 0 }, -- next sequence (non-consecutive frames) { name = "fastRun", frames = { 1,3,5,7 }, time = 400, loopCount = 0 }, }
多序列设置中的第一个序列被视为默认序列。创建精灵对象时,将使用默认序列,除非您显式更改序列(请参阅下面的精灵控制方法部分)。
对于多序列设置,您不限于使用来自一个图像表单的帧 — 实际上,每个序列都可以访问唯一的图像表单。为此,只需将 `sheet` 参数添加到任何序列并将其值设置为任何
设置图像表单和序列后,可以使用 display.newSprite() API 创建新的 精灵对象
display.newSprite( [parent,] imageSheet, sequenceData )
对于此 API,`parent` 参数是可选的,表示要在其中插入精灵的显示组。`imageSheet` 参数定义精灵的默认图像表单,`sequenceData` 是包含精灵所有序列的表。
在本指南的上下文中,精灵声明如下所示
local runningCat = display.newSprite( sheet_runningCat, sequences_runningCat )
此行将创建一个名为 `runningCat` 的 显示对象,可以移动、旋转、过渡、链接到 物理主体等 — 并且因为它也是一个 精灵对象,所以它获得了下面概述的所有精灵 控制方法和 精灵属性。
精灵库提供了四种主要的控制方法,可用于控制精灵的播放
object:play() — 使用默认或设置的序列启动动画。创建精灵时,它们不会自动开始播放,因此您必须使用此命令启动它们。
object:pause() — 暂停动画。没有“停止”控制方法,因此此方法用于这两种目的。
object:setFrame() — 立即将当前序列中的指示帧索引设置为或跳到该索引。如果要在动画开始播放后“停止并重置”动画,请连续使用 pause() 和 setFrame() 命令,将帧设置回序列的开头。
object:setSequence() — 将精灵设置为特定序列。例如,要将 `runningCat` 精灵动画从 `normalRun` 更改为 `fastRun`(假设这两个序列都在 `sequences_runningCat` 表中声明),请调用 `runningCat:setSequence( "fastRun" )`。然后,调用 `runningCat:play()` 开始播放动画,因为设置/更改序列后精灵不会自动开始播放。
所有精灵对象都具有各种属性。您甚至可以修改特定精灵的相对动画速度。这些属性如下:
object.frame — 表示加载序列的当前显示索引的只读整数。此属性不设置帧;使用 setFrame() 函数显式设置动画帧。
object.isPlaying — 如果动画正在播放,则此属性为 `true`,否则为 `false`。
object.numFrames — 表示当前动画序列中帧数的只读属性。
object.sequence — 指示当前动画序列名称的只读属性。
object.timeScale — 获取或设置应用于动画时间的比例(比率),允许您动态调整精灵的动画速度。
精灵系统可以通过实现精灵侦听器函数来检查 精灵事件。这允许您检测动画何时开始播放、动画何时结束、何时循环等。
要将精灵事件侦听器添加到特定精灵,请使用标准的 object:addEventListener() 方法,并将 `eventName` 属性设置为 `“sprite”` 并引用侦听器函数
object:addEventListener( "sprite", spriteListener )
添加事件侦听器后,`spriteListener` 函数将在动画期间的特定 阶段 被调用
使用这些阶段,假设您希望 `runningCat` 精灵循环播放 `normalRun` 序列的 4 个周期,然后更改为 `fastRun` 序列并无限循环。首先,必须通过将 `loopCount` 更改为 `4` 来修改 `normalRun` 序列。这允许您在所有 4 个循环完成后检测 `ended` 阶段。
local sequences_runningCat = { { name = "normalRun", start = 1, count = 8, time = 800, loopCount = 4 }, { name = "fastRun", frames = { 1,3,5,7 }, time = 400, loopCount = 0 }, }
接下来,编写侦听器函数并将事件侦听器添加到 `runningCat` 对象。您可以在创建精灵对象后包含此代码,因为事件侦听器是通过单独的命令添加的,而不是在精灵实例化期间声明的。
-- sprite listener function local function spriteListener( event ) local thisSprite = event.target -- "event.target" references the sprite if ( event.phase == "ended" ) then thisSprite:setSequence( "fastRun" ) -- switch to "fastRun" sequence thisSprite:play() -- play the new sequence end end -- add the event listener to the sprite runningCat:addEventListener( "sprite", spriteListener )
请注意,精灵侦听器将**所有**阶段传输到侦听器函数,因此您有责任使用条件子句并在动画序列中出现特定阶段时执行适当的操作。在上面的示例中,仅检测到 `ended` 阶段,该阶段发生在 `normalRun` 序列的 4 个完整循环之后。当该序列结束时,将设置并播放 `fastRun` 序列,并且由于它无限循环,因此将不会再出现 `ended` 阶段。