教程:使用“enterFrame”监听器实现动画

教程:使用“enterFrame”监听器实现动画

在 Corona 中,有两种动画方法:精灵动画程序动画。精灵动画 (指南) 涉及使用以循环方式显示的多个帧(图像),从而产生对象内部运动的错觉。相比之下,程序动画涉及使用编程技术来移动、旋转、缩放或以其他方式更改对象的状态。

之前的教程概述了使用过渡的程序动画。本周,我们将讨论如何使用 "enterFrame" 事件来操作对象。

概述

当应用程序运行时,Corona 会每秒更新屏幕 30 次或 60 次,这个概念称为每秒帧数fps。您可以通过应用程序的 config.lua 文件中的 fps 值来控制此速率 (指南)

当应用程序运行时,每次 Corona 准备更新屏幕时(每一帧),它都会生成一个名为 "enterFrame" 的事件 (参考)。将此事件与事件监听器结合使用,您可以通过在每一帧更改对象的某些方面来实现动画效果。

基本设置

考虑一下像太空侵略者®这样的经典游戏。在这个游戏中,外星人以设定的模式来回移动,偶尔会有一个特殊的 UFO 飞过屏幕顶部。让我们说明如何使用 "enterFrame" 监听器来移动那个 UFO

这种设置可能比您编写的更冗长,但它有助于解释所涉及的数学原理。计时基于时钟/帧“刻度”,因此在 60 fps 的游戏中,每秒将触发 60 个事件。如果我们想在 5 秒内将我们的 UFO 移动穿过 320 点的屏幕,我们必须精确计算出在每个刻度上移动多少。

点与像素

Corona 使用在 config.lua 中通过 widthheight 定义的虚拟“内容区域”大小(见上文)。但是,这通常不会精确“映射”到真实设备上的像素宽度。例如,iPhone 6 屏幕的宽度为 750 像素,而 iPad Air 屏幕的宽度为 1536 像素。因此,对于 UFO 在屏幕上的基于帧的动画,将每个位置更改转换为会很有用。

在此示例中,我们总共有 300 个“刻度”来移动 UFO 穿过屏幕,因为 fps 为 60,我们将使其在 5 秒的时间内移动 (60 × 5 = 300)。UFO 的起始 x 位置为 340,这比内容区域的右侧偏移 20 个点 (320+20),其目的地 x 位置为 -20,这比内容区域的侧偏移 20 个点。因此,实际移动距离为 360 个点 (340 − -20 = 360)。由于我们需要知道每个刻度移动对象的点数,我们只需将距离除以刻度数 (360/300) 即可得到结果 1.2

使用“enterFrame”事件

现在我们已经计算出了移动 UFO 的方法,让我们编写一个在每个刻度上执行的函数

在该函数之外 — 在此示例的最后一行 — 我们将 "enterFrame" 事件监听器添加到 Runtime,并将 ufo 显示对象作为目标传递。这将启动基于帧的动画过程。

对于函数声明,我们使用 : 运算符将该函数“附加”到 UFO 对象,以便传递该对象。这被称为 Lua 对象方法,通过这样做,我们可以将函数内的 UFO 对象作为 self 访问。

在函数内部,在每一帧中,我们希望将 UFO 向左移动。已知 pointsPerTick 值为 1.2,只需使用 object:translate() API 从对象的 x 坐标中减去该值即可。额外的代码会检查 UFO 是否经过了 -20 的最终目标点,如果经过,则会移除 "enterFrame" 事件侦听器,从而有效地停止 UFO 的移动。

当然,这仅执行沿 x 轴的非常简单的运动,这可以通过过渡轻松完成,但基于帧的动画可能用于更复杂的场景,例如按模式移动对象、来回重复移动敌人、滚动游戏背景等。

增量时间

请注意,在使用基于帧的动画时,可能需要考虑“增量”时间波动。这是因为,在内部,不能保证帧精确地按时触发,并且取决于您的应用中发生的其他活动量,这种不精确性会影响整体动画。如果需要更高的精度,请参阅本教程,其中概述了如何利用增量时间。

结论

如您所见,"enterFrame" 事件为 Corona 中动画对象提供了另一种选择,尤其是在所需的动画超出单个过渡的能力时。


Rob Miracle
[email protected]

Rob 是 Corona Labs 的开发者关系经理。除了热衷于帮助其他开发者使用 Corona 制作出色的游戏外,他还喜欢在业余时间制作游戏。Rob 从 1979 年开始编码游戏,从个人电脑到大型机。他在游戏行业拥有超过 16 年的专业经验。

1 条评论
  • Thomas Vanden Abeele
    发布于 08:02,8 月 26 日

    有点短,但提到 enterFrame 事件很酷 - 我认为这是游戏(代码)设计中最强大的概念,也是每个初学者都应该努力掌握的东西。