corona sdk 에서 level director 이용 level간 전환하기
corona sdk에서 story board가 api가 생겨서 변환이 쉽게 되지만 LD에서는 storyboard api 사용 없이도 쉽게 변환 할 수 있습니다.
LD site 예제에서 찾아보았습니다.
V2Demo 예제에서 사용법을 찾아볼 수 있습니다.
function loadScene() if (scene > 0) then myLevel:removeLevel() clickText:removeEventListener("tap",loadScene) Runtime:removeEventListener("enterFrame",move) Runtime:removeEventListener("touch", drag ) if (toggle) then toggle:removeSelf() toggle = nil end end scene = scene + 1 if (scene > 4) then scene = 1 end myLevel = LD:loadLevel ('Scene' .. scene) --print ('layers ' .. #myLevel.layers) clickText = myLevel:getLayerObject("Text","click").view clickText:addEventListener( "tap", loadScene ) initScene() end loadScene()
레벨을 로딩할때 LD:loadLevel() 함수를 사용하고 제거시 myLevel:removeLevel() 함수를 사용하면 됩니다.
지난번 animation 작업하던곳에 새로운 level을 만들어서 object가 5번 생성되면 다음 level로 전환되는 예제를 만들어 보도록 하겠습니다.
level01은 기존 그대로 사용하고 level02는 level01을 그대로 복사합니다.
level02
그후에 bird를 삭제하고 y만 남겨두고 위치를 변경합니다.
그리고 itemGet이라는 level을 새로 만듭니다. 복사를 안하고 만들면 asset이 하나도 생기지 않습니다.
level01->level02->itemGet 순으로 level이 변경되도록 제작하겠습니다.
아래는 소스입니다.
physics = require ("physics") physics.start() local LD = require("lib.LD_LoaderG2") -- G2 is for Corona Graphic2.0, remove for Graphics1.0 local myLevel ={} local yobj local bird local tPrevious = system.getTimer() local deltaSum = 0 local level = 0 local count = 0 local tm local initScene = nil ------------------------------------------------- --function to position new ball and update scores ------------------------------------------------- function spawnObject() local objProps = { name = "bird_dy", x = math.random(20,300), y = 0, xScale = 1, yScale = 1, assetName = "bird_png_1", } -- set the graphics local bird_d = myLevel:createObject("New Layer", objProps).view bird_d:setSequence("Sequence0") bird_d:play() transition.moveTo( bird_d, { x=yobj.x, y=yobj.y, time=8000 } ) end ------------------------------------- function update(event) ------------------------------------- if( level == 1 ) then local tDelta = event.time - tPrevious tPrevious = event.time deltaSum = deltaSum + tDelta; if (deltaSum > 5000 ) then deltaSum = 0 count = count + 1 if (count > 5 ) then initScene() count = 0 print("initscene",level) else spawnObject() end end elseif( level == 2 ) then local tDelta = event.time - tPrevious tPrevious = event.time deltaSum = deltaSum + tDelta; if (deltaSum > 5000 ) then deltaSum = 0 count = count + 1 if (count > 5 ) then level = 10000 initScene() count = 0 print("initscene",level) else spawnObject() end end end end -- poop collision handler function onGlobalCollision( event ) if( level == 1 ) then if event.phase == "began" then local obj1 = event.object1; local obj2 = event.object2; print (obj1.name) print (obj2.name) if ( obj1.name == "bird_dy" and obj2.name == "y" ) or ( obj1.name == "y" and obj2.name == "bird_dy" ) then if( obj1.name == "y" ) then myLevel:removeLayerObject("New Layer", obj2.name) obj2 = nil else myLevel:removeLayerObject("New Layer", obj1.name) obj1 = nil end end end end end function initScene(event) print("initscene") if ( level~=0 ) then print("remove") myLevel:removeLevel() myLevel = nil end if( level < 10000 ) then level = level+1 myLevel=LD:loadLevel("level0"..level) else if ( level == 10000 ) then myLevel=LD:loadLevel("itemGet") end end print("level",level) if ( level == 1 ) then bird = myLevel:getLayerObject("New Layer","bird").view bird:setSequence("Sequence0") bird:play() yobj = myLevel:getLayerObject("New Layer","y").view yobj:setSequence("Sequence0") yobj:play() elseif ( level == 2 ) then yobj = myLevel:getLayerObject("New Layer","y").view yobj:setSequence("Sequence0") yobj:play() end end initScene() -- add frame handler Runtime:addEventListener( "enterFrame", update ) Runtime:addEventListener( "collision", onGlobalCollision )
이전 예제에서 잘못구현한 내용이 있는데 동적 object삭제시 아래와 같이 LD api를 이용하여 삭제 하여야 합니다.
myLevel:removeLayerObject("New Layer", obj2.name)
myLevel:removeLayerObject("New Layer", obj1.name)
최종 개선한 코드 입니다.
birdcount 부분을 추가하였습니다. 왜냐하면 이름이 같아버리면 충돌시 삭제할때 어려움이 있었습니다. 충돌시 myLevel:removeLayerObject("New Layer", obj2.name) 함수를 이용하여 object를 제거할때 이름이 같아버려서 오동작을 하는 경우가 있었습니다.
function spawnObject()
birdcount = birdcount + 1
local objProps =
{
name = "bird_dy "..birdcount,
physics = require ("physics") physics.start() local LD = require("lib.LD_LoaderG2") -- G2 is for Corona Graphic2.0, remove for Graphics1.0 local myLevel ={} local yobj local bird local tPrevious = system.getTimer() local deltaSum = 0 local level = 0 local count = 0 local tm local initScene = nil local birdcount = 0 ------------------------------------------------- --function to position new ball and update scores ------------------------------------------------- function spawnObject() birdcount = birdcount + 1 local objProps = { name = "bird_dy "..birdcount, x = math.random(20,300), y = 0, xScale = 1, yScale = 1, assetName = "bird_png_1", } -- set the graphics local bird_d = myLevel:createObject("New Layer", objProps).view bird_d:setSequence("Sequence0") bird_d:play() transition.moveTo( bird_d, { x=yobj.x, y=yobj.y, time=math.random(500,10000) } ) end ------------------------------------- function update(event) ------------------------------------- if( level == 1 ) then local tDelta = event.time - tPrevious tPrevious = event.time deltaSum = deltaSum + tDelta; if (deltaSum > 1000 ) then deltaSum = 0 count = count + 1 if (count > 50 ) then initScene() count = 0 print("initscene",level) else spawnObject() end end elseif( level == 2 ) then local tDelta = event.time - tPrevious tPrevious = event.time deltaSum = deltaSum + tDelta; if (deltaSum > 5000 ) then deltaSum = 0 count = count + 1 if (count > 5 ) then level = 10000 initScene() count = 0 print("initscene",level) else spawnObject() end end end end -- poop collision handler function onGlobalCollision( event ) if( level == 1 ) then if event.phase == "began" then local obj1 = event.object1; local obj2 = event.object2; local sp = string.find(obj1.name," ") local obj1_name if (sp == nil) then obj1_name = obj1.name else obj1_name = string.sub(obj1.name, 0,string.find(obj1.name," ")-1) end local sp = string.find(obj2.name," ") local obj2_name if (sp == nil) then obj2_name = obj2.name else obj2_name = string.sub(obj2.name, 0,string.find(obj2.name," ")-1) end print (obj1_name, obj1.name) print (obj2_name, obj2.name) if ( obj1_name == "bird_dy" and obj2_name == "y" ) or ( obj1_name == "y" and obj2_name == "bird_dy" ) then if( obj1_name == "y" ) then myLevel:removeLayerObject("New Layer", obj2.name) obj2 = nil else myLevel:removeLayerObject("New Layer", obj1.name) obj1 = nil end end end end end function initScene(event) print("initscene") if ( level~=0 ) then print("remove") myLevel:removeLevel() myLevel = nil end if( level < 10000 ) then level = level+1 myLevel=LD:loadLevel("level0"..level) else if ( level == 10000 ) then myLevel=LD:loadLevel("itemGet") end end print("level",level) if ( level == 1 ) then bird = myLevel:getLayerObject("New Layer","bird").view bird:setSequence("Sequence0") bird:play() yobj = myLevel:getLayerObject("New Layer","y").view yobj:setSequence("Sequence0") yobj:play() elseif ( level == 2 ) then yobj = myLevel:getLayerObject("New Layer","y").view yobj:setSequence("Sequence0") yobj:play() end end initScene() -- add frame handler Runtime:addEventListener( "enterFrame", update ) Runtime:addEventListener( "collision", onGlobalCollision )
충돌 처리가 상당히 복잡해 졌습니다.
그래서 Tool > Options > Project 항목에 Class Types을 이용합니다.
y,brid를 추가하고
object의 Object Class를 변경합니다.
y의 경우 꺼내 놓은 객체를 변경하도록 합니다.
충돌 검사 소스를 변경합니다.
physics = require ("physics") physics.start() local LD = require("lib.LD_LoaderG2") -- G2 is for Corona Graphic2.0, remove for Graphics1.0 local myLevel ={} local yobj local bird local tPrevious = system.getTimer() local deltaSum = 0 local level = 0 local count = 0 local tm local initScene = nil local birdcount = 0 ------------------------------------------------- --function to position new ball and update scores ------------------------------------------------- function spawnObject() birdcount = birdcount + 1 local objProps = { name = "bird_dy "..birdcount, x = math.random(20,300), y = 0, xScale = 1, yScale = 1, assetName = "bird_png_1", } -- set the graphics local bird_d = myLevel:createObject("New Layer", objProps).view bird_d:setSequence("Sequence0") bird_d:play() transition.moveTo( bird_d, { x=yobj.x, y=yobj.y, time=math.random(500,10000) } ) end ------------------------------------- function update(event) ------------------------------------- if( level == 1 ) then local tDelta = event.time - tPrevious tPrevious = event.time deltaSum = deltaSum + tDelta; if (deltaSum > 1000 ) then deltaSum = 0 count = count + 1 if (count > 50 ) then initScene() count = 0 print("initscene",level) else spawnObject() end end elseif( level == 2 ) then local tDelta = event.time - tPrevious tPrevious = event.time deltaSum = deltaSum + tDelta; if (deltaSum > 5000 ) then deltaSum = 0 count = count + 1 if (count > 5 ) then level = 10000 initScene() count = 0 print("initscene",level) else spawnObject() end end end end -- poop collision handler function onGlobalCollision( event ) --[[ if( level == 1 ) then if event.phase == "began" then local obj1 = event.object1; local obj2 = event.object2; local sp = string.find(obj1.name," ") local obj1_name if (sp == nil) then obj1_name = obj1.name else obj1_name = string.sub(obj1.name, 0,string.find(obj1.name," ")-1) end local sp = string.find(obj2.name," ") local obj2_name if (sp == nil) then obj2_name = obj2.name else obj2_name = string.sub(obj2.name, 0,string.find(obj2.name," ")-1) end print (obj1_name, obj1.name) print (obj2_name, obj2.name) if ( obj1_name == "bird_dy" and obj2_name == "y" ) or ( obj1_name == "y" and obj2_name == "bird_dy" ) then if( obj1_name == "y" ) then myLevel:removeLayerObject("New Layer", obj2.name) obj2 = nil else myLevel:removeLayerObject("New Layer", obj1.name) obj1 = nil end end end end ]] if( level == 1 ) then if event.phase == "began" then local obj1 = event.object1; local obj2 = event.object2; if ( obj1.class == "bird" and obj2.class == "y" ) or ( obj1.class == "y" and obj2.class == "bird" ) then if( obj1.class == "y" ) then myLevel:removeLayerObject("New Layer", obj2.name) obj2 = nil else myLevel:removeLayerObject("New Layer", obj1.name) obj1 = nil end end end end end function initScene(event) print("initscene") if ( level~=0 ) then print("remove") myLevel:removeLevel() myLevel = nil end if( level < 10000 ) then level = level+1 myLevel=LD:loadLevel("level0"..level) else if ( level == 10000 ) then myLevel=LD:loadLevel("itemGet") end end print("level",level) if ( level == 1 ) then bird = myLevel:getLayerObject("New Layer","bird").view bird:setSequence("Sequence0") bird:play() yobj = myLevel:getLayerObject("New Layer","y").view yobj:setSequence("Sequence0") yobj:play() elseif ( level == 2 ) then yobj = myLevel:getLayerObject("New Layer","y").view yobj:setSequence("Sequence0") yobj:play() end end initScene() -- add frame handler Runtime:addEventListener( "enterFrame", update ) Runtime:addEventListener( "collision", onGlobalCollision )
기타 참고 : http://www.retrofitproductions.com/level-director/utility-library/