在游戏设计中,一个常见的元素是对象生成,无论是生成数量可变的敌人并将它们随机放置在屏幕上,还是在计时器增量上重复生成物品。在本教程中,我们将逐步介绍一个基本的生成模块,其中包含以下功能:
让我们从几个初始命令开始……
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" )
希望本教程为您提供一个简单的基础模块,您可以在此基础上构建更全面的生成方法,包括动画精灵、物理对象、可变时间增量等等。