当你在游戏中完成一个关卡时,它有时会以动画的方式显示你的分数。有时这涉及数字“旋转”,使得它们从最
在 Corona 中实现这种效果涉及一些简单的数学。让我们从一些初始设置开始
local scoreText = display.newText( "000000", display.contentCenterX, 60, native.systemFont, 48 )
这段代码非常简单——我们只需创建一个文本对象 scoreText
,初始显示为 000000,位于屏幕的
首先要理解的是,Corona 是一个
显然,游戏分数可能会有很大差异——一个游戏的最高分可能是 100 分,而另一个游戏的最高分可能是数百万分。因此,我们不希望计数器在每次帧更新时都以固定数量(如 +1)递增。如果是这样,1,000,000 的分数更新所需的时间太长——以每秒 60 帧的速度大约需要 16667 秒——而像 100 这样的分数完成得太快
更好的解决方案是确定**动画应该运行多长时间**,然后计算每次帧更新时应该递增的数量。
确定递增分数的数量可以通过一种称为**线性插值**的方法来完成。这基本上允许你根据某些条件计算两个值之间的中间点。让我们将一个用于此目的的函数添加到我们现有的代码中
local scoreText = display.newText( "000000", display.contentCenterX, 60, native.systemFont, 48 ) local function lerp( v0, v1, t ) return v0 + t * (v1 - v0) end
这个 lerp()
函数足够简单。我们取起始值和结束值之间的差v1 - v0
)t
)v0
) 中。
现在让我们添加一个 incrementScore()
函数,它将完成大部分实际工作
local scoreText = display.newText( "000000", display.contentCenterX, 60, native.systemFont, 48 ) local function lerp( v0, v1, t ) return v0 + t * (v1 - v0) end local function incrementScore( target, amount, duration, startValue ) local newScore = startValue or 0 local passes = (duration/1000) * display.fps local increment = lerp( 0, amount, 1/passes ) local count = 0 local function updateText() if ( count <= passes ) then newScore = newScore + increment target.text = string.format( "%06d", newScore ) count = count + 1 else Runtime:removeEventListener( "enterFrame", updateText ) target.text = string.format( "%06d", amount + (startValue or 0) ) end end Runtime:addEventListener( "enterFrame", updateText ) end
如你所见,此函数接受四个参数
target
— 应该更新的文本对象(必需)。amount
— 分数计数器递增的数量(必需)。duration
—startValue
— 分数计数器的可选起始值。如果要从大于 0 的值开始计数,例如添加到现有分数,则可以指定此值。**在函数内部**,我们基本上采取以下步骤
我们设置一个临时值 newScore
,其值为 startValue
参数startValue
,则为 0
)。
接下来,我们计算达到最终分数值所需的“遍数”。这是由指定的持续时间(从毫秒转换为秒)乘以应用程序的4000
(4 秒),并且应用程序以每秒 60 帧的速度运行,则结果为4 * 60
240
次。
在此之后,我们使用计算出的值运行 lerp()
函数。这将返回每次传递时计数器递增的数量,我们将其存储为 increment
变量。
在下一个块中,我们使用一个基本的计数器变量 (count
) 和一个嵌套的 updateText()
函数。此函数将每帧运行一次increment
值添加到分数中。然后将更新后的值设置为目标显示对象 (scoreText
) 的 text
属性,但在使用 string.format() 将其**格式化**为显示为 6 位数字(带前导零)之前不会设置。
当计数持续时间完成时,我们停止updateText()
函数,然后将分数计数器设置为最终值,再次格式化为显示为 6 位数字(带前导零)。
分数计数器值的正确格式 (string.format()
) 将取决于你的特定场景。如果你只计数到最大分数 100,则可能不应该将其格式化为 6 位数字,带"%03d"
(3 位数字)比 "%06d"
更好。另请注意,格式化是完全可选的,如果不需要,则不需要应用**任何**格式化。
有关字符串格式的进一步探讨,请参阅格式化字符串值教程。
updateText()
函数(如上所述,当运行计数过程很简单——只需使用所需的参数调用 incrementScore()
函数,例如
incrementScore( scoreText, 750800, 4000 )
这将使 scoreText
文本对象在 4 秒的总时间内从 000000 计数到 750800。
希望本教程能够帮助你开始为你的游戏使用经典的“旋转分数计数器”功能。只需 sedikit kreativitas,你就可以对其进行调整以适应几乎任何场景和任何最大分数阈值!