2016년 2월 12일 금요일

make game as corona sdk (Fly a rocketman)(4) - performWithDelay

이번에 작업할 내용은 이벤트가 발생하게 되면 하나의 object를 생성하는게 아니라 그룹형태로 생성 할 목록을 지니도록 할 예정입니다.

지난번에 group 0 이면 특정 객체를 생성하게 구현하였는데 group 번호에 따라 다른 동작이 이루어 지도록 구현 하였습니다.

데이터의 예제가 아래와 같습니다.
self.data 안에 있는 마지막에 있는 type 이 1이면 생성할때는 self.typeCreateData 를 이용하여 rect 2개를 생성하고,
-- type 1
{
{"rect",-100, 30},
{"rect", 100,-30},
일정 시간 후에 동작하는 움직임 제어를 위해서는,
self.typeActionData 자료를 참고하여 구현하였습니다.
self.typeActionData = {
-- type 1
{
--time, action, param
{700,"move_y",-100},
{500,"move_y",200},

아래는 전체 data 입니다.


self.data = {
  -- group 1
  {
  -- tick, y, type
   {30,100,1},
   {30,200,2},
   {30,300,1}
  },
  -- group 2
  {
  -- tick, y, type
   {30,100,1},
   {30,200,2},
   {0 ,100,1}, -- todo
   {0 ,150,1}, -- todo
   {0 ,200,1}, -- todo
   {0 ,250,1}, -- todo
   {30,300,1}
  },
    }

    self.typeActionData = {
     -- type 1
     {
      --time, action, param
      {700,"move_y",-100},
      {500,"move_y",200},
     },
     -- type 2
     {
      --tick, action, param
      -- -1 is nothing
      {-1},
     },
    }

    self.typeCreateData = {
     -- type 1
     {
      {"rect",-100, 30},
      {"rect", 100,-30},
     },
     -- type 2
     {
      {"rect",-100,  0},
     },
    }


이전시간에 tick을 이용하여 self.data 를 호출 하도록 구현하였습니다.
self.typeActionData 의 경우 일정 시간 후 동작해야 하므로 timer를 이용하였습니다.
corona sdk에서는 performWithDelay 함수가 준비되어 있습니다.

해당 함수를 사용하면서 주의해야 할것은 listener가 parameter 가 존재하는 경우가 있는 경우 처리를 제대로 해줘야합니다.

https://docs.coronalabs.com/api/library/timer/performWithDelay.html

즉, 비슷하면서도 헷갈리는 동작입니다만, 시험을 해보면 오류가 발생하지는 않으나, 후자의 경우 Delay없이 실행되게 됩니다.
따라서 디버깅이 쉽지 않는 경우가 있습니다.

timer.performWithDelay(firstTime, function() self:timerActionCB(object) end)
timer.performWithDelay(firstTime, self:timerActionCB(object))
위의 예제에서는 빨간색 상단이 맞는 것입니다.

인자가 있는 경우 아래 두가지 용법을 잘 기억해 두어야 합니다.
local tm = timer.performWithDelay( 1000, onTimer )
-- Assign a table of parameters to the "tm" handle
tm.params = { myParam1 = "Parameter1", myParam2 = "Parameter2" }
local myClosure = function() return spawnBall( randomPosition ) end
timer.performWithDelay( 2000, myClosure, 1 )

triggerGroup.lua 입니다. 나머지는 앞쪽 소스 참고하시기 바랍니다.


local M = {}
local random = math.random

function M:init()
 print("init")
 math.randomseed( os.time() )
 self.cwidth = display.contentWidth
 self.frameTick = 0
 self.data = {
  -- group 1
  {
  -- tick, y, type
   {30,100,1},
   {30,200,2},
   {30,300,1}
  },
  -- group 2
  {
  -- tick, y, type
   {30,100,1},
   {30,200,2},
   {0 ,100,1}, -- todo
   {0 ,150,1}, -- todo
   {0 ,200,1}, -- todo
   {0 ,250,1}, -- todo
   {30,300,1}
  },
    }

    self.typeActionData = {
     -- type 1
     {
      --time, action, param
      {700,"move_y",-100},
      {500,"move_y",200},
     },
     -- type 2
     {
      --tick, action, param
      -- -1 is nothing
      {-1},
     },
    }

    self.typeCreateData = {
     -- type 1
     {
      {"rect",-100, 30},
      {"rect", 100,-30},
     },
     -- type 2
     {
      {"rect",-100,  0},
     },
    }

    self.currentGroupNum = nil
    self.currentPC = nil
    self.nextEventTick = 0
end

function M:changeGroup()
 self.currentGroupNum = random(1,#self.data)
 print("group selected:",self.currentGroupNum)
 self.currentPC = 1;
 -- get tick
 self.nextEventTick = self.data[self.currentGroupNum][self.currentPC][1]
end

function M:loadNextInfo()
 self.frameTick = 0
 self.currentPC = self.currentPC + 1
 if( self.currentPC > #self.data[self.currentGroupNum] ) then
  -- all group end
  self:changeGroup()
 else
  self.nextEventTick = self.data[self.currentGroupNum][self.currentPC][1]
 end
end

function M:timerActionCB(selfobj)
 print("aa",selfobj,selfobj.actionPC);
 if( selfobj.actionPC == nil ) then return end

 --object:removeSelf()
 local action = self.typeActionData[selfobj.actionObjectType][selfobj.actionPC]
 if(action[2]=="move_y")then
  local vx, vy = selfobj:getLinearVelocity()
  selfobj:setLinearVelocity(vx,vy+action[3])
  print("action")
 end
 selfobj.actionPC = selfobj.actionPC + 1
 if( #self.typeActionData[selfobj.actionObjectType] >= selfobj.actionPC ) then
  timer.performWithDelay(self.typeActionData[selfobj.actionObjectType][selfobj.actionPC][1], function() self:timerActionCB(selfobj) end)
  --timer.performWithDelay(self.typeActionData[selfobj.actionObjectType][selfobj.actionPC][1], self:timerActionCB(selfobj))
 end
end

function M:runEvent()
 local y = self.data[self.currentGroupNum][self.currentPC][2]
 local gtype = self.data[self.currentGroupNum][self.currentPC][3]
 local firstTime = self.typeActionData[gtype][1][1]
 
 local cdata = self.typeCreateData[gtype]
 local count = #cdata
 for i = 1, count, 1 do
  local object
  if( cdata[i][1] == "rect" ) then
   object = display.newRect( self.cwidth + self.cwidth/2 , y, 40, 80 )
   physics.addBody(object,"dynamic",{ density=1 })
   object:setLinearVelocity(-300,0)
  end
  if( object~=nil and firstTime >= 0 ) then
   object.actionPC = 1
   object.actionObjectType = gtype;
   print("fristTime",firstTime)
   timer.performWithDelay(firstTime, function() self:timerActionCB(object) end)
   --timer.performWithDelay(firstTime, self:timerActionCB(object))
  end
 end
end

function M:tick()
 self.frameTick = self.frameTick + 1

 if( self.currentGroupNum == nil ) then
  -- need to change group
  self:changeGroup()

 end
 if( self.frameTick > self.nextEventTick ) then
  repeat
   self:runEvent()
   self:loadNextInfo()
  until ( self.nextEventTick ~= 0)
 end



end

return M




댓글 없음:

댓글 쓰기