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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

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

2013. 1. 26. 06:47 | Posted by 솔웅


반응형

이번주의 Corona Tutorial은 무척 깁니다.

한번에 다 포스팅 하기는 어렵구요... 그렇게 하다가 작성해 놓은 글 날렸어요... ;;


예제가 총 11개 나오던데 이 예제별로 포스팅을 하려고 합니다.

이번에는 직접 실습도 해 가면서 저 나름대로 덧 붙일게 있으면 덧 붙여서 정리하려구요.



Posted on . Written by



오늘의 guest tutorial 은 Matt Webster, a.k.a. “HoraceBury.”  가 무료로 정보를 공유합니다. Matt 은 central London 에서 Development Manager 로 일하고 있습니다. 그는 닷넷과 자바 웹 개발분야에 15년의 경력을 가지고 있습니다. 그리고 게임이나 physics-based app 을 개발하는데는 Corona 를 사용하고 있습니다. 그는 Corona Labs Ambassador이기도 한데요 London meet-ups 를 두번이나 개최했습니다. 그리고 2013년도에는 더 많은meet-up을 가질 계획입니다. Matt 의 첫번째 Corona game 은  Tiltopolis 이었습니다. 고전인 Columns 와 Tetris를 합친 게임이죠.



Preface

우선 project files을 다운 받으세요.그러면 아래 예제들을 쉽게 테스트해 보실 수 있습니다. 각각의 samplex 모듈들은 기능을 갖고 있는 mini-project 입니다. 그리고 main.lua 에서 한번에 하나씩 실행시켜 보실 수 있습니다. 필요한 구문만 코멘트를 지워서 사용하세요. 마지막 모듈은 sample11.lua 는 전체 pinch-zoom-rotate module 입니다. 이 모듈은 여러분이 앱을 개발하실 때 실제 활용하시면 아주 유용할 겁니다.



Introduction



대부분의 어플리케이션에서는 하나의 터치 포인트일 경우 이를 제대로 표현할 수 있습니다. 아주 다양한 앱들이 저마다 아주 많은 기능들을 가지고 있지만 한번에 한개의 input 만 사용할 수 있죠. 한번에 한개의 버튼을 누를 수 있고 한번에 한개의 swipe 이벤트를 다룰 수 있고 등등이요.



앵그리버드를 예로 들어보죠. 이 앱에서는 각각의 tap, drag 그리고 swipe 들이 단지 한 손가락으로 이루어 지도록 돼 있습니다. 메뉴를 살펴보는 것, settings 를 여는 것, 새를 날려버리는 것 모두 한개의 손가락으로 처리하죠. 한 손가락으로만 하게 되면 일단 간단하죠. 그리고 직관적이고 또 집중할 수 있도록 도와 줍니다. 그런데 pinch zoom 같이 두 손가락 이상으로 해야 되는 경우도 있습니다.




이 경우 규칙을 어떻게 적용해야 할까요? 한손가락을 사용할 때는 터치된 object 에 action 을 구현하고 두 손가락이 사용됐을 때는 parent display group 의 top-level 에 어떤 action을 구현해야 겠죠.


이 튜토리얼의 목적은 이 multitouch 와 관련해서 최대한 간단하게 하려면 어떻게 처리해야 되는지에 대해 여러분에게 알려드리려는 겁니다. 그리고 pinch zoom 에 대해서도 좀 더 자세하게 다룰 겁니다.




Touch Basics




이 튜토리얼을 보시는 분들은 대부분 Corona touch model 을 사용해 본 경험이 있으 실 겁니다. 그러니 그와 관련해서는 핵심적인 내용 몇가지만 언급하겠습니다.



    addEventListener() 는 특정 display 객체에 대해 사용자의 터치가 일어나는 지를 listen 하기 위해 사용됩니다.
    터치 이벤트에는 두 종류가 있습니다 : touch and tap.
    터치 이벤트에는 다음과 같은 phases 가 있습니다 : began, moved and ended..
    display object 에 터치와 tap 이벤트가 동시에 일어날 경우 tap event 보다 touch event phases 가 먼저 fire 됩니다.
    Returning true from an event function stops Corona from passing that event to any display objects beneath the object.
    multitouch를 위해 system.activate(“multitouch”) 를 사용함니다.
    터치 이벤트가 일단 시작되면 다른 touch phases들은display.getCurrentStage():setFocus().를 call 함으로서 같은 listener 에 연결 되게 됩니다.
    setFocus 는 한 object와 한 evnet 별로 call 될 수 있습니다.
    display object에 dispatchEvent()를 call 하면 별도의 원하는 event들을 만들어 낼 수 있습니다.
    dispatchEvent로 fire 된 이벤트들은 다른 display hierarchy 에 전파되지 않습니다.




The Tap Problem



위에 언급한대로 터치 이벤트에는 여러 phases들이 있습니다. 각각 디바이스에 대한 유저의 interaction 상황을 나타냅니다. 화면에 손가락을 대고, 움직이고 그리고 떼고 하는 상황들을요.


일반적인 tap 이벤트는 주어진 시간안에 — iOS employs about 350 milliseconds — 위에 언급한 이벤트 phases들을 fire 합니다. 그리고 시작과 끝 지점은 10 픽셀이하의 거리이구요.
이 시간과 거리별로 계속 해당 phases가 발생 되는 겁니다.


즉 터치이벤트와 tap 이벤트를 동시에 listening 한다면 터치 리스너 함수 내에서 이미 곧 tap 리스너 함수가 call 될 거라는 것을 알 수 있을 겁니다. 그리고 이미 tap 이벤트를 감지했다면 더는 tap 리스너를 attach 할 필요가 없습니다. 이 튜토리얼에서는 tap 이벤트는 코드를 복잡하게 만들 뿐이라서 코딩해 넣지 않을 겁니다.



Single Touch


To demonstrate the typical touch event, let’s create a display object with a standard touch listener and use it to move the display object around.
일반적인 터치 이벤트를 구현하기 위해 standard touch listener 와 display object를 생성하겠습니다. 그리고 이 display object를 움직일 수 있도록 만들겠습니다.


sample1.lua



local circle = display.newCircle( 0, 0, 50 )  -- create a user interface object
circle.alpha = 0.5  -- make it less imposing

-- standard single-touch event listener
function circle:touch(e)

   local target = e.target  -- 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)  -- 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(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





위 함수에서는 multitouch 가 아닌 일반적인 touch event를 처리합니다.
이 예제로는 아래와 같은 일을 할 겁니다.



    객체에 터치가 시작됨
    터치 후 움직임으로서 객체도 움직이게 됨
    touch 가 off 가 되면 객체는 영향을 받지 않음
    해당 터치가 한 객체를 움직이는 동안은 다른 객체는 터치의 영향을 받지 않는다.
    display object는 자신의 :touch(e) function을 갖는다. (global function이 아니라)



해당 객체에서 터치가 일어났을 때에만 영향을 받고 터치가 객체 바깥에서 일어나면 터치의 영향을 받지 않습니다. 이 기능은 hasFocus 를 세팅해서 인데요. 해당 객체는 began이 일어난 이후에 touch phase들을 accept 하게 됩니다. 또한 한번 터치가 일어나면 그 터치는 끝날때까지 해당 객체에 영향을 미치게 됩니다. 바로 setFocus 가 코로나에게 이후의 터치 진행 상황을 해당 객체에 적용하라고 일러 주는 것이거든요.


반응형