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 toucheslocal rect = display.newRect( 200, 200, 200, 100 )rect:setFillColor( 0, 0, 255 )-- standard multi-touch event listenerfunction 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") thenlocal dot = newTrackDot(e) -- create a tracking dotreturn true -- we handled the began phaseendreturn false -- if target is not responsible for this touch event return falseendrect: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 movedlocal function newTrackDot(e)local circle = display.newCircle( e.x, e.y, 50 ) -- create a user interface objectcircle.alpha = 0.5 -- make it less imposing-- standard multi-touch event listenerfunction 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") thendisplay.getCurrentStage():setFocus(target, e.id) -- set touch focus on this objecttarget.hasFocus = true -- remember that this object has the focusreturn true -- indicate the event was handledelseif (target.hasFocus) then -- this object is handling touchesif (e.phase == "moved") then -- move the display object with the touchtarget.x, target.y = e.x, e.yelse -- "ended" and "cancelled" phasesdisplay.getCurrentStage():setFocus(target, nil) -- remove touch focustarget.hasFocus = false -- this object no longer has the focusendreturn true -- indicate that we handled the touch and not to propagate itendreturn false -- if target is not responsible for this touch event return falseendcircle:addEventListener("touch") -- listen for touches starting on the touch layercircle:touch(e) -- pass the began phase to the tracking dotreturn circle -- return the object for useend
이 함수에서는 단 두가지 변화만 주었습니다.
- circle:touch(e)를 call 했습니다. 왜냐하면 이 circle 이 바로 그 생성된 객체이기 때문이죠. 그리고 touch 이벤트의 began
phase를 실제로recieve 하지 않은 객체이구요. 이렇게 call 함으로서 이 circle 객체가 그 touch 이벤트의 control 을 받도록 합니다.
- :touch() function의 시작부분에 그 circle을 target 으로 사용하기 위해 수정했습니다. 왜냐하면 그 e.target property는 실제 touch began이 시작한 그 "rect" 객체이기 때문입니다.
이 코드가 실행되면 작은 파란 사각형을 볼 수 있습니다. 이 사각형은 여러개의 하얀 원들을 생성해 낼 수 있습니다. 각각의 원은 가각의 touch 에 의해 움직입니다. 이 매커니즘은 모든 touch 정보를 파란 사각형에 직접 사용하면서 실제로는 multitouch input 이 일어나는 것처럼 구현할 수 있는 방법입니다.
|
'Corona SDK > Corona Doc' 카테고리의 다른 글
Pinch Zoom Rotate 구현하기 - 8/11 - (0) | 2013.02.14 |
---|---|
Pinch Zoom Rotate 구현하기 - 7/11 - (0) | 2013.02.12 |
Pinch Zoom Rotate 구현하기 - 6/11 - (0) | 2013.02.12 |
Pinch Zoom Rotate 구현하기 - 5/11 - (0) | 2013.02.09 |
Pinch Zoom Rotate 구현하기 - 4/11 - (0) | 2013.02.01 |
Pinch Zoom Rotate 구현하기 - 2/11 - (0) | 2013.01.29 |
Pinch Zoom Rotate 구현하기 - 1/11 - (0) | 2013.01.26 |
코로나에서 time, date 다루기 (0) | 2013.01.18 |
Multi-Element Physics Body 다루기 (0) | 2013.01.11 |
내 앱에 애플의 iAds 광고 달기 (0) | 2013.01.03 |