在游戏设计中,一个常见的元素是对象生成,无论是生成数量可变的敌人并将它们随机放置在屏幕上,还是在计时器增量上重复生成物品。在本教程中,我们将逐步介绍一个基本的生成模块,其中包含以下功能:
让我们从几个初始命令开始……
local spawnTimer
local spawnedObjects = {}
-- Seed the random number generator
math.randomseed( os.time() )
第一个变量 spawnTimer 只是对我们将用于控制生成过程的计时器对象的 Lua 前向引用。第二个变量 spawnedObjects 是一个基本表,我们将在其中插入生成的项目,为我们提供跟踪它们、计数它们、循环它们等的基本方法。
第三个命令设置
现在,让我们设置一个基本生成参数表,我们可以使用它来调整/控制生成
local spawnParams = {
xMin = 20,
xMax = 300,
yMin = 20,
yMax = 460,
spawnTime = 200,
spawnOnTimer = 12,
spawnInitial = 4
}
所有这些参数都是可选的,并且将默认为各种值(稍后详细介绍),但通常应将它们设置为适合您游戏的值。本质上,前四个参数定义了屏幕上将生成项目的矩形区域,由 x 和 y 的最小值和最大值定义。下一个参数 (spawnTime) 定义了生成新项目的时间增量(以毫秒为单位),假设项目数量由 spawnOnTimer 参数定义。最后,如果游戏设计需要,spawnInitial 参数可用于立即生成一定数量的项目。
接下来,我们需要一个创建对象的基本生成函数
-- Spawn an item
local function spawnItem( bounds )
-- Create an item
local item = display.newCircle( 0, 0, 20 )
-- Position item randomly within set bounds
item.x = math.random( bounds.xMin, bounds.xMax )
item.y = math.random( bounds.yMin, bounds.yMax )
-- Add item to "spawnedObjects" table for tracking purposes
spawnedObjects[#spawnedObjects+1] = item
end
前几行创建了一个示例项目——在本例中是一个基本的白色矢量圆圈。显然,这些项目可以是图像、动画精灵、您随后启用物理使用的对象等。
接下来的几行将项目随机放置在声明的边界内。回想一下,我们将这些声明为 spawnParams 表中的前四个参数。
最后一行只是将新项目添加到 spawnedObjects 表中,提供了一种跟踪和管理生成对象的简单方法。
下一步是创建一个简单但功能强大的“控制器”函数,它允许我们启动、停止、暂停和恢复生成过程。此函数将接受两个参数:表示要执行的操作的 action 参数和 params 参数(这表示我们上面声明的 spawnParams 表)。
local function spawnController( action, params )
-- Cancel timer on "start" or "stop", if it exists
if ( spawnTimer and ( action == "start" or action == "stop" ) ) then
timer.cancel( spawnTimer )
end
-- Start spawning
if ( action == "start" ) then
-- Gather/set spawning bounds
local spawnBounds = {}
spawnBounds.xMin = params.xMin or 0
spawnBounds.xMax = params.xMax or display.contentWidth
spawnBounds.yMin = params.yMin or 0
spawnBounds.yMax = params.yMax or display.contentHeight
-- Gather/set other spawning params
local spawnTime = params.spawnTime or 1000
local spawnOnTimer = params.spawnOnTimer or 50
local spawnInitial = params.spawnInitial or 0
-- If "spawnInitial" is greater than 0, spawn that many item(s) instantly
if ( spawnInitial > 0 ) then
for n = 1,spawnInitial do
spawnItem( spawnBounds )
end
end
-- Start repeating timer to spawn items
if ( spawnOnTimer > 0 ) then
spawnTimer = timer.performWithDelay( spawnTime,
function() spawnItem( spawnBounds ); end,
spawnOnTimer )
end
-- Pause spawning
elseif ( action == "pause" ) then
timer.pause( spawnTimer )
-- Resume spawning
elseif ( action == "resume" ) then
timer.resume( spawnTimer )
end
end
让我们检查一下这个函数
spawnTimer),因此我们可以在这里安全地使用该引用。-- Cancel timer on "start" or "stop", if it exists
if ( spawnTimer and ( action == "start" or action == "stop" ) ) then
timer.cancel( spawnTimer )
end
我们为什么要在停止操作上取消计时器,这很明显,但为什么我们也要在启动操作上取消它呢?基本上,这只是一个
在此条件块的初始行中,我们根据先前声明的 spawnParams 表中定义的参数收集/设置各种参数。如前所述,所有这些参数都是可选的,因此如果未定义任何参数,我们将在其位置设置一些基本默认值。
-- Start spawning
if ( action == "start" ) then
-- Gather/set spawning bounds
local spawnBounds = {}
spawnBounds.xMin = params.xMin or 0
spawnBounds.xMax = params.xMax or display.contentWidth
spawnBounds.yMin = params.yMin or 0
spawnBounds.yMax = params.yMax or display.contentHeight
-- Gather/set other spawning params
local spawnTime = params.spawnTime or 1000
local spawnOnTimer = params.spawnOnTimer or 50
local spawnInitial = params.spawnInitial or 0
接下来,我们检查 spawnInitial 参数是否大于 0,如果是,我们立即生成该数量的项目。请注意,我们将 spawnBounds 表传递给 spawnItem() 函数,以便它识别生成项目的限制。
-- Start spawning
if ( action == "start" ) then
-- Gather/set spawning bounds
local spawnBounds = {}
spawnBounds.xMin = params.xMin or 0
spawnBounds.xMax = params.xMax or display.contentWidth
spawnBounds.yMin = params.yMin or 0
spawnBounds.yMax = params.yMax or display.contentHeight
-- Gather/set other spawning params
local spawnTime = params.spawnTime or 1000
local spawnOnTimer = params.spawnOnTimer or 50
local spawnInitial = params.spawnInitial or 0
-- If "spawnInitial" is greater than 0, spawn that many item(s) instantly
if ( spawnInitial > 0 ) then
for n = 1,spawnInitial do
spawnItem( spawnBounds )
end
end
之后,我们检查 spawnOnTimer 参数是否大于 0,如果是,我们启动一个计时器,该计时器在设置的 spawnTime 增量上生成该数量的项目。请注意,我们将此计时器对象设置为 spawnTimer 引用,以便我们可以根据需要暂停、恢复或停止它。如上所述,我们将 spawnBounds 表传递给匿名函数,以便所有项目都在所需的边界内生成。
-- Start spawning
if ( action == "start" ) then
-- Gather/set spawning bounds
local spawnBounds = {}
spawnBounds.xMin = params.xMin or 0
spawnBounds.xMax = params.xMax or display.contentWidth
spawnBounds.yMin = params.yMin or 0
spawnBounds.yMax = params.yMax or display.contentHeight
-- Gather/set other spawning params
local spawnTime = params.spawnTime or 1000
local spawnOnTimer = params.spawnOnTimer or 50
local spawnInitial = params.spawnInitial or 0
-- If "spawnInitial" is greater than 0, spawn that many item(s) instantly
if ( spawnInitial > 0 ) then
for n = 1,spawnInitial do
spawnItem( spawnBounds )
end
end
-- Start repeating timer to spawn items
if ( spawnOnTimer > 0 ) then
spawnTimer = timer.performWithDelay( spawnTime,
function() spawnItem( spawnBounds ); end,
spawnOnTimer )
end
-- Pause spawning
elseif ( action == "pause" ) then
timer.pause( spawnTimer )
-- Resume spawning
elseif ( action == "resume" ) then
timer.resume( spawnTimer )
end
end
从这一点开始,可以轻松地使用四种可能的动作调用生成控制器。请注意,使用 "start" 作为 action 参数调用 spawnController() 函数是唯一需要 spawnParams 表的用例——其他操作假定生成过程已经在进行中。
spawnController( "start", spawnParams )
spawnController( "pause" )
spawnController( "resume" )
spawnController( "stop" )
希望本教程为您提供一个简单的基础模块,您可以在此基础上构建更全面的生成方法,包括动画精灵、物理对象、可变时间增量等等。