반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

Pinch Zoom Rotate 구현하기 - 3/11 -

2013. 1. 29. 21:58 | Posted by 솔웅


반응형
Posted on . Written by



The Multitouch Problem


위 코드의 장점은 multiple touche들을 쉽게 구분할 수 있다는 겁니다. 그래서 각 object들은 자신들에 할당된 touch를 잃지 않고 계속 영향을 받을 수 있는거죠. 아주 큰 장점이지만 작은 문제점도 있습니다.

"
아주 큰 장점은 setFocus 로 유저가 어떤 object를 touch 헀으면 그 object 내에서 해당 touch는 계속 유효하게 되는 겁니다. 그 object 밖으로 나가버리면 더이상 유효하지 않게 되는거죠.

작은 문제점은 다른 touch 이벤트를 receive 하게 되면 이 setFocus 는 이 display object를 stop 시킨다는 겁니다.


만약 아직 setFocus를 call 하지 않았다면 hasFocus 를 사용하는 것이 해당 object 가 그 object에서 시작하지 않은 이벤트들을 무시하도록 하는 편리한 방법입니다. 이 방법은 자주 필요한데요. 왜냐하면 유저들은 그 객체가 아니라 배경화면이나 그 객체 밖에서 시작하는 swiping 이벤트를 자주 발생시키거든요. 그 swiping 이벤트는 이 객체를 지나가게 되죠. 그래서 이 객체에서 시작되지 않은 이벤트를 무시하도록 하려고 하는 겁니다. 그리고 그 다음 드는 의문은 코로나가 어떻게 여러 객체들이 multiple touch들을 받아서 작동하도록 만드는가 입니다. 그 방법은 바로 began phase안에 tracking object를 생성하는 것입니다.


The Concept

이전에 다뤘던 코드에 약간의 변화를 주겠습니다. 우리는 began phase안에서 여러 객체들을 생성하는 하나의 object를 생성할 겁니다. 이 객체들은 각각의 touch들을 track 할 겁니다. 그리고 그 touch 가 끝나면 해당 객체를 없애도록 코딩할 겁니다. 이를 구현하기 위해 touch event의 began phse를 listen 하는 함수를 하나 만들겁니다. 그리고 moved 를 listen 하는 함수도 하나 만들거구요. 이 두개의 함수들은 target listening object와 tracking dot object들에 add 될 겁니다.


Spawning Tracking Dots




첫번째로 처음에 began phase를 handle 하게 될 객체를 생성해야 합니다. began phase에서 이 객체는 tracking dot을 생성하기 위해 function을 call 할 겁니다.



sample3.lua


system.activate("multitouch") -- turn on multitouch

 
-- create object to listen for new touches
local rect = display.newRect( 200, 200, 200, 100 )
rect:setFillColor( 0, 0, 255 )
 
-- standard multi-touch event listener
function rect:touch(e)
 
local target = e.target -- get the object which received the touch event
-- handle began phase of the touch event life cycle...
if (e.phase == "began") then
 
local dot = newTrackDot(e) -- create a tracking dot
return true -- we handled the began phase
end
 
return false -- if target is not responsible for this touch event return false
end
 
rect:addEventListener("touch") -- listen for touches starting on the touch object

간단해서 딱 보면 코드를 이해하실 수 있을 겁니다. 어떤 touch 이벤트가 일어나던지 그 began phase를 listen 할 display 객체를 생성합니다. 이 객체가 touch 이벤트의 began phase를 receive하면 새로운 display object를 생성할 함수를 call 하게 됩니다. 이 새 object는 그 객체를 생성시킨 touch를 track 하게 될 겁니다. 그 작업은 setFocus 를 call 함으로서 가능해 지죠. hasFocus 값을 세팅하지 않은 점을 잘 보세요. 왜냐하면 이 multitouch 객체들은 began phase에서만 처리되고 있거든요.



다음으로 tracking dot을 생성해야 합니다. 이 코드는 이전의 multitouch function과 거의 유사합니다.


-- creates an object to be moved
local function newTrackDot(e)
 
local circle = display.newCircle( e.x, e.y, 50 ) -- create a user interface object
circle.alpha = 0.5 -- make it less imposing
-- standard multi-touch event listener
function circle:touch(e)
 
local target = circle -- get the object which received the touch event
-- handle each phase of the touch event life cycle...
if (e.phase == "began") then
 
display.getCurrentStage():setFocus(target, e.id) -- set touch focus on this object
target.hasFocus = true -- remember that this object has the focus
return true -- indicate the event was handled
 
elseif (target.hasFocus) then -- this object is handling touches
if (e.phase == "moved") then -- move the display object with the touch
target.x, target.y = e.x, e.y
else -- "ended" and "cancelled" phases
display.getCurrentStage():setFocus(target, nil) -- remove touch focus
target.hasFocus = false -- this object no longer has the focus
end
return true -- indicate that we handled the touch and not to propagate it
end
return false -- if target is not responsible for this touch event return false
end
circle:addEventListener("touch") -- listen for touches starting on the touch layer
circle:touch(e) -- pass the began phase to the tracking dot
return circle -- return the object for use
end




이 함수에서는 단 두가지 변화만 주었습니다.

  • circle:touch(e)를 call 했습니다. 왜냐하면 이 circle 이 바로 그 생성된 객체이기 때문이죠. 그리고 touch 이벤트의 began phase를 실제로recieve 하지 않은 객체이구요. 이렇게 call 함으로서 이 circle 객체가 그 touch 이벤트의 control 을 받도록 합니다.
  • :touch() function의 시작부분에 그 circletarget 으로 사용하기 위해 수정했습니다. 왜냐하면 그 e.target property는 실제 touch began이 시작한 그 "rect" 객체이기 때문입니다.


이 코드가 실행되면 작은 파란 사각형을 볼 수 있습니다. 이 사각형은 여러개의 하얀 원들을 생성해 낼 수 있습니다. 각각의 원은 가각의 touch 에 의해 움직입니다. 이 매커니즘은 모든 touch 정보를 파란 사각형에 직접 사용하면서 실제로는 multitouch input 이 일어나는 것처럼 구현할 수 있는 방법입니다.





반응형