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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

비트맵 마스크 사용하기

2012. 6. 2. 03:35 | Posted by 솔웅


반응형

How to Use Bitmap Masks

Posted by Jonathan Beebe

이번주 튜도리얼은 많은 프로젝트에서 꾸준히 애용되고 있는 기능이지만 한편으로는 특별한 use-case로 인해 여러분이 잘 모를 수 도 있는 기능을 다뤄볼까 합니다. 이 기능은 bitmap masking 인데요, graphics.newMask() 함수를 사용해서 구현합니다.

아마 bitmap masking이 무엇인지 잘 모를수도 있습니다. 또 어떻게 유용하게 사용될지에 대해서 알지 못할수도 있구요. 그러신 분들은 이번 강좌를 잘 보세요. 분명히 아주 유용한 툴일테니까요. Bitmap mask는 약간 tricky 한 방법으로 문제를 해결하는데 사용될 수 있습니다.

    - 이미지의 투명한 부분에는 touch 이벤트가 안 먹게 하기 (아주 많이 쓰이는 케이스 입니다)
    - 특정한 모양으로 이미지를 Clip 하기 (예를들어 스크롤 뷰 위젯에서 전체 스크린 내의 일부 sub-section 부분을 clip 하기 위해 bitmap mask 를 이용할 수 있습니다.)
    - solid background가 있는 이미지에 transparency 주기


위에 보시듯이 masking의 주요 목적은 이미지의 일 부분을 숨기는 겁니다. (혹은 전체 display 그룹의 일 부분을 숨길수도 있구요.) 즉 이미지를 masking 하는 겁니다. 그러려면 masking 할 이미지도 있어야 합니다. mask라는 단어를 사용하는 이유가 그냥 이미지나 그룹에 덮어씌우는 기능을 하기 때문입니다.





What a mask looks like

아래에 과일 이미지가 있습니다. (fruit.png) 그리고 bitmap mask image 가 있습니다. (fruit-mask.png) 이 두개의 이미지를 사용할 겁니다. 회색으로 서양의 체스판 모양으로 돼 있는 부분은 이미지의 투명한 부분입니다.





오른쪽의 bitmap mask의 검은 부분이 투명한 부분이 될 겁니다. 그리고 흰 부분은 이 mask가 정확하게 apply 됐을 때 보여지게 될 원래 source 이미지가 들어갈 부분입니다. 이 mask로 사용될 이미지에는 어떤 특별한 제약이 있는것이 아닙니다. 아무 이미지나 사용하실 수 있습니다.

What’s the point?

위 두개의 이미지를 사용할 건데 뭘 하려는 것일까요? mask 이미지에 있는 검은 색은 이미 source image에서 투명하게 돼 있는 부분인데요. 이 튜토리얼에서 다룰 것은 bitmap masking을 사용해서 특정 부분을 투명하게 만드는것 말고 투명한 부분에서는 touch 이벤트가 안 먹도록 만드는 방법을 알려 드릴 겁니다.

투명한 부분이 있는 이미지라도 touch listener를 달면 전체 이미지에서 이 touch 이벤트가 먹힐겁니다. 오직 저 사과만 터치했을 때 어떤 이벤트가 발생하도록 하려면 어떻게 해야 할까요? 그렇게 하려면 이 bitmap mask를 사용해야 합니다. 또 예를 들어 어떤 이미지가 있는데 그 이미지의 일 부분에만 터치가 먹히게 하고 싶을 때도 이 방법을 사용할 수 있습니다. 이미지내에 투명한 부분이 없을때도 말이죠.

Bitmap mask requirements

mask로 사용할 이미지를 만들때는 아래와 같아야 합니다.

   1. width와 height가 4의 배수여야 합니다.
   2. 적어도 3px의 검은테두리가 있어야 합니다.


위의 가이드라인을 따르지 않는다면 예상한 대로 masking이 일어나지 않을 것이고 이것을 debug 하는 것도 힘들겁니다. 추가적으로 고려해야 할 사항들을 아시려면 Bitmap Mask documentation 을 읽어 보세요.

Applying the mask

mask를 적용하려면 graphics.newMask()를 사용해서 새로운 mask를 만들어야 합니다. 그리고 object:setMask() 메소드를 사용해서 객체나 그룹에 apply 합니다.

local mask = graphics.newMask( "fruit-mask.png" )

local fruit = display.newImage( "fruit.png" )
fruit.x, fruit.y = display.contentCenterX, display.contentCenterY

-- apply mask to object
fruit:setMask( mask )


위의 코드를 보시면 우선 mask를 생성하고 display object를 만들고 그 마스크를 display object에 apply 했습니다. 이렇게만 하면 약간의 문제가 생길겁니다. 디폴트로 객체의 적용 좌표는 0,0 이 됩니다. (좌상단이 되겠죠) 그리고 mask는 중앙을 기준으로 하는 reference point가 적용 되면 아래와 같은 모양으로 object:setMask()가 적용 될 겁니다.





mask 가 적용될 객체의 정 중앙에 제대로 덮이길 원하시면 객체의 maskX와 maskY 프로퍼티를 수정해 줘야 합니다.

fruit.maskX = fruit.contentWidth*0.5
fruit.maskY = fruit.contentHeight*0.5


마스크는 대상 객체의 0,0 지점에 위치한다는 것을 꼭 기억해 두세요. 위의 코드를 추가하고 나면 아래와 같이 될 겁니다.



결과적으로 모바일 화면에는 아래와 같이 나오게 됩니다.



자 겉으로 보기에는 그냥 display.newImage() 해서 원래 배경이 투명한 이미지를 display 한것과 다를것이 없습니다. 만약 원래 배경색이 투명하지 않았다면 겉모습이 투명하게 바뀌었을 테니까 뭔가 변화가 있다고 느껴지겠죠. 어쨌든 위에 사용한 원래 이미지 파일에는 배경이 투명하게 이미 돼 있었습니다. 그러니까 위 예제가 유용하게 사용되려면 투명한 부분을 un-touchable 하게 만들어야 쓸모가 있게 되겠죠.

다행스럽게도 이미지가 이렇게 한번 mask 되고 나면 다음 사용법은 아주 쉽습니다. 그냥 간단하게 object.isHitTestMasked 프로프티를 true로 세팅하면 투명해진 부분에 touch 이벤트가 안 먹히게 할 수 있습니다.

fruit.isHitTestMasked = true

이제 여러분이 이 fruit 객체에 touch 리스너를 달게 되면 전체 256X256 이미지가 다 touchable 되는것이 아니라 투명하지 않은 부분만 touchable 될 겁니다. 이 예제의 경우엔 아주 정확하게 과일 부분에 터치할 경우에만 touch 이벤트가 적용 되겠죠.

Dynamic Content Scaling


bitmap mask는 dinamic content scaling을 지원하지 않습니다. 그렇다고 해서 방법이 전혀 없는 것도 아닙니다. 구현하시려면 high resolution asset를 로드해서 object.maskScaleX와 object.maskScaleY 프로퍼티를 원하는 크기에 맞게 세팅해 주세면 됩니다.

예를 들어, retina display에 맞춰서 개발을 하고 있고 아주 super-sharp 하게 되도록 mask를 사용하고 싶으시면 fruit-mask.png와 fruit-mask@2x.png 두개를 준비하세요. (원본보다 두배 크기의 이미지를 준비하시면 됩니다.) 그리고 mask를 생성할 때 (graphics.newMask()) @2x asset을 사용하시면 됩니다. 그리고 나서 fruit.maskScaleX 와 fruit.maskScaleY 를 display.contentScaleX와 display.contentScaleY로 세팅하세요.

아래 예제가 있습니다.

local mask = graphics.newMask( "fruit-mask@2x.png" )

local fruit = display.newImage( "fruit.png" )
fruit.x, fruit.y = display.contentCenterX, display.contentCenterY

-- apply mask to object
fruit:setMask( mask )
fruit.maskScaleX = display.contentScaleX
fruit.maskScaleY = display.contentScaleY
fruit.maskX = fruit.contentWidth*0.5
fruit.maskY = fruit.contentHeight*0.5


이런 방식을 사용하면 좀 더 다양한 해상도에 맞도록 이미지들을 준비하면 좀 더 super-sharp 하게 이 mask를 사용할 수 있겠죠. 물론 각각 다른 high resolution 이미지를 사용해야 겠죠. 같은 방법으로 안드로이드 디바이스들도 이렇게 적용하실 수 있습니다.

그리고 mask는 전체 display group 객체에도 apply 될 수 있다는 것을 기억해 두세요.

Removing a mask

객체에서 mask를 제거하고 싶으시면 간단하게 object:setMask(nil)을 해 주시면 됩니다. 또한 변수를 nil로 선언해도 이 mask를 제거하실 수 있습니다.

fruit:setMask( nil )
mask = nil


이 bitmap mask에 대한 또 다른 예제도 보실 수 있습니다. 다운로드 받으신 Corona SDK의 Flashlight 샘플을 한번 보세요. 경로는 /SampleCode/Graphics/Flashlight 폴더 입니다. 이 bitmap mask로 어떤 다른 좋은 효과를 줄 수 있을까요?

반응형

Corona Roadmap

2012. 5. 26. 22:46 | Posted by 솔웅


반응형

Corona Roadmap

Posted by Walter

제가 좋아하는 말이 있습니다. Dwight D. Eisenhower  대통령의 말인데요. "계획은 아무런 소용이 없다. 하지만 계획을 세우것은 반드시 필요하다."

다른 말로 계획을 세우는 과정이 중요하다는 겁니다. 그리고 상황이 변하면 여러분의 계획도 변할 수 있어야 되는 것이죠.

그 마음가짐으로 여러분과 우리의 로드맵을 나누고 싶습니다. 우리의 계획중의 하나라는 것을 알아 주세요. 아직  외부로 밝힐 수 없는 top secret 들도 있습니다.

우리는 high level 로드맵과 core feature 로드맵으로 로드맵을 두 분야로 나누었습니다.



High-level Roadmap

첫번째로 high-level 로드맵에 대해 얘기하겠습니다:

    Q2
        SDK (next public release)
        Enterprise
        Level Editor
    Q3
        Mac Apps


여러분이 보시듯이 우리는 많은 해야할 일들을 가지고 있습니다. 아주 바쁜 스케줄의 연속입니다. 우리는 새로운 무료 공개버전 작업은 거의 다 마무리 했습니다. Enterprise와 Level Editor는 그 뒤를 이어서 곧바로 진행할 겁니다.

여기까지의 작업을 마치면 Mac Apps에 대한 작업들을 끝낼 수 있습니다. 물론 이 것이 좀 더 일찍 release 될거라고 저희들이 약속했던 것을 기억합니다. 하지만 그동안 많은 infrastructure 들이 바뀌었습니다. 64비트가 그 중에 한 개 인데요. 그 작업들을 하는데 고려해야할 그러한 새로운 변화들이 많이 있었습니다.


여러분들 중에 Enterprise가 뭔지 궁금해 하시는 분들도 계실 겁니다. 그건 아주 흥미로운 새로운 상품입니다. 여기에 대해서 앞으로 다른 글을 통해 좀 더 자세하게 얘기하겠습니다. 그리고 이것이 SDK 개발자들에게 어떤 이로운 점들을 제공할지에 대해서도 말씀 드리겠습니다.



Core Feature Roadmap

이제 본격적인 얘기 입니다. 어떤 기능들이 추가 core로 선보이게 될까요?

우리는 이것을 2-on-2 cycles 로 분류를 했습니다. 간단히 풀면 Cycle 1은 6월과 7월이고 Cycle 2 는 7월과 8월입니다.

첫번째 기간에는 안드로이드도 아이폰이랑 동등하게 지원하고 Documentation을 완료하려고 합니다. 하지만 Push Notification은 Cycle 1에 포함되지 않았습니다. 왜냐하면 안드로이드에서 이것을 구현하는것은 iOS보다 훨씬 복잡하거든요. Cycle 1에는 낮게 열린 과일을 따는 걸로 포커스를 잡았습니다. 그래서 Push 는 Cycle 2로 옮겼습니다.

우리가 한번 리듬을 잡으면 각 cycle마다 얼마나 낳은 기능들을 넣을지에 대해 좀 더 잘 감을 잡을 겁니다. 그 때까지 아래처럼 각 cycle 안에 stretch goals 를 두어서 추가 기능을 확장할 여지를 두었습니다.

[Cycle 1]

    Android
        WebView
        VideoView
        Intent filtering
        MapView
    Documentation for each daily-build
    Stretch Goals
        LPEG
        Page Transition Effects
        Physics Improvements, fixes and update to Box2D 2.2.1
        Widget Improvements

[Cycle2]

    Android
        Push Notification
    iOS
        Maps (breadcrumbs, directions, multiple pins)
        Add image to photo library
    Stretch Goals
        TBD


추가적으로 우리의 할일 목록에 아주 많은 일들을 가지고 있습니다. 그리고 그것들을 완료하고 싶습니다. 여기 포럼에 확정된 리스트를 올렸습니다. 여러분들이 추가 됐으면 좋을 기능들이 있으면 포럼에 올려 주세요. 여기에 댓글을 달아 주셔도 됩니다.

지난주에 말했듯이 조금 더 일이 진행 된 다음에 이 확정된 리스트에 대해서 얘기 할 기회가 있을겁니다. 여러분의 top 3 기능을 투표를 통해 받을 계획입니다. 그리고 여러분이 만들고자 하는 case, 기능, 앱에 대해서 많이 알려주시고 물어봐 주세요. 그러면 우리들이 기능들을 추가하는데 많은 도움이 될 수 있을 것 같습니다.

* * *

아주 많은 일들이 진행됩니다.

여느 계획과 마찬가지로 이것은 현재 우리가 생각하고 있는 것들의 snapshot 입니다. Eisenhower 을 말 처럼 우리는 그 계획들을 계속 바꾸고 있습니다. 우리는 계획을 세우는데 많은 시간을 보내고 있습니다. 그렇게 함으로서 그것들을 적정한 시점에 수용해서 선보일 수 있습니다.


반응형


반응형

Guest Post: 18 Years to Our First App

Steve Bullock은 Adveractive Inc.의 창립자이다. 그리고 퍼즐이나 단어게임으로 좋아하는 NOOK 앱인 Word Winder를 공동 개발하기도 있다. Word Winder는 월요일 App of the Week에 선정되기도 했다. 단지 release 된지 2주 만이다. 이 게임은 NOOK Apps의 board와 game 카테고리에서 1위를 기록하고 있다. Steve와 그의 훌륭한 팀의 성공에 축하를 드린다.

Eighteen Years to Our First App

어떤 사람들은 여기 North Carolina에서 우리를 조금 느리다고 생각합니다. 1994년도에 창립된 (1995년에 첫 게임) 우리의 작은 회사는 지난주 첫번째 앱을 release 했습니다. 게임 이름은 Word Winder 입니다. 솔직히 우리는 진짜로 느리지는 않습니다. 우리는 그냥 남부지방 기질대로 느릿느릿 여유있게 갈 뿐입니다. 





The Path We’ve Taken

저는 1994년도에 Adveractive 를 설립했고 당시 1명의 직원을 두었습니다. Rich Stewart 죠. 저는 초창기 멀티미디어에 푹 빠졌었습니다. (Myst, Passage to Vietnam, 7th Guest 같은) 그리고 interactive advertising 과 관련 된 crazy idea를 갖게 됐습니다. 그래서 회사 이름이 약간 독특합니다. 그리고나서 1995년도에 다음과 같은 일들이 일어납니다. 인터넷이 저를 완전히 뻑 가게 했고 (9600 baud modem 사용), 간단한 게임을 만드는 법을 배우게 됐고 shockwave라고 하는 funky 한 브라우저 플러그인의 beta tester 로 초대 됐습니다. 그리고 게임 개발자가 될 수 밖에 없는 운명은 잠시 봉인 됐었습니다. 그로부터 몇년동안 Adveractive는 거의 사라질뻔하기도 하고 굶어 죽을 뻔하기도 했습니다. 그러면서도 재밌었습니다. 많은 친구들을 만나게 됐고 온라인 상에서 세계적으로 활동을 했고 casual game들을 다운로드 받았습니다. -아직까지 앱은 없었죠.

The Loves We Have Had

우리는 3년동안 3개의 개발 환경과 결혼했었습니다. 결혼이라는 표현을 썼는데요. 한번 특정 SDK에 여러분과 여러분 그룹을 던져 넣으면 서로 많이 의존하게 되고 아주 사랑에 빠지게 되고 excite 하게 되면서 감탄과 존경도 하게 됩니다. 그러다가 실망하게 되는 순간이 오고 또 어려움이 오고 문제점이 생겨서 때로는 혼자서 또 때로는 같이 그 문제들을 풀어야 되는 상황이 오죠.

First Love

첫번째 사랑은 (virtual 적으로) Macromedia Director  였습니다. Shockwave라는 알을 낳는 애였죠. 우리는 Macromedia Director 를 개척하는 개척자였습니다. 아마 지금 코로나를 사랑했던 것 만큼 그 때 디렉터를 사랑했었습니다. Director/Shockwave는 2000년대까지 저와 저의 회사를 도왔고 저도 그녀를 도왔습니다. 우리는 아주 열심히 일하는 부부였죠.

Second Love

Flash 가 나오면서 첫사랑은 멀어져갔죠. 플래시는 아주 이뻤습니다. 하지만 1990년대에는 그렇지는 않았습니다. 그녀는 자랐습니다. 저는 플래시와 그렇게 깊이 사랑에 빠지지는 않았습니다. 하지만 그녀는 디렉터를 옆으로 밀어제치고 2001년부터 지금까지 저희 집에와서 밥을 차려주고 있어요. 저는 프로그램을 존경하고 또 좋은 제품을 만들 수 있도록 개발 환경을 제공하는 사람들을 아주 존경합니다. 그들은 프로페셔널 입니다. 하지만 저는 디렉터나 코로나에 대한 열정처럼 자주 흥분하는 스타일은 아닙니다.

New Love

지금 저는 다시 사랑에 빠졌습니다. 수년간 저희는 앱은 만들고 싶어했지만 그 길을 찾기 위해 온라인상에서 많은 수고를 해야만 했습니다. 지난 여름 우리는 드디어 모바일과 태블릿 앱의 세계로 느릿느릿 진입하기 시작했습니다. 한가지 의문을 가지고요. "이제 누구랑 결혼하지? 혹은 우리의 second partner랑 이 일을 해야 할까?" 새로운 파트너가 될 수 있는 상대방들과 몇번의 충분한 데이트를 하고 난 후 우리는 Corona를 선택했습니다. 그리고 후회는 없습니다. 지금 현재 다른 온라인 작업을 하느라고 우리는 아직 Flash를 사용하고 있지만 Corona는 우리의 미래입니다.

이 새 결혼 후 9개월이 지나서 새로운 파트너가 perfect 하지는 않다는 것을 깨달았습니다. 하지만 우리가 코로나와 사랑에 빠질 수 있었던 이유들은 이렇습니다.

    - 우리는 Jonathan, Peach, Tom, Carlos (지금 실종상태입니다), Walter, Joshua 그리고 (웹 게임이 아주 어렸을 때 알게 됐던) 여러 친구들의 헌신과 열정을 보면서 아주 excite 해 졌습니다. 그리고 이 좋은 친구들이 그들의 제품을 사랑하고 있다는 것이 보였습니다.

    - 코로나는 아주 강력합니다. 보기에는 아주 간단해 보이면서도 Word Winder 의 경우 제대로 작동하게 하기 위해 수천, 수만의 소스 코드 line 들이 있습니다. 이 앱 안에는 서로 다른 로직과 서로 다른 레이아웃 그리고 각각의 플레이 메카니즘을 갖고 있는 6개의 별개의 게임이 있습니다. 게다가 auto-save, 광범위한 help 제공, 특정한 부분에서의 first-time tip들 같은 세세한 많은 부분들까지 신경을 썼습니다. 유저들이 처음 접하고 사용하기 편하게 도와드리기 위해서죠. 그러한 작업을 하기 위해 수 많은 코딩이 필요했고 강력하면서도 flexible 한 development platform이 있어야 했습니다.

   - Word Winder's 개발을 Ansca로 하기로 결정하고 나서 3~4가지 기술적인 이슈들이 있었습니다. 이 이슈들에 대해서 Corona 엔진에서 어떻게 그러한 작업들이 진행되는지 빠르고 정확하고 자세한 설명을 받을 수 있었습니다. 몇가지 이슈는 아직은 우리가 구현할 수 없는 것입니다. 하지만 그럼에도 불구하고 정말 좋은 개발 툴이라는 것이 충분히 설명됐고 충분히 이해했습니다.

   - 우리는 이 게임을 마케팅 전략적인 이유로 NOOK에 먼저 발표했습니다. 하지만 사실 우리는 이 앱을 NOOK 이전에 iPad 에 맞게 개발했었습니다. 지금 우리는 iOS, Kindle Fire 그리고 안드로이드 버전의 Word Winder를 개발하고 있고 이번 여름에 발표할 예정입니다. 코로나는 이런 cross-plagform 작업을 정말로 우아하게 처리할 수 있도록 해 줍니다.




The First New Child (and maybe the best ever?)

Word Winder는 best game 이 될 겁니다. 지금까지 보지 못한 intellectual 한 부분이 있습니다. 지난주 몇몇 store (Barnes & Noble 등 등)에 physical board game version으로 launch 됐습니다. 그리고 올 여름 광범위한 시장에서 사용이 가능하도록 만들 겁니다. 그러기 위해서 우리는 다음달에 NOOK 이외에도 여러 곳에 porting 할 계획입니다.

Word Winder 는 USA Today와 다른 많은 daily online 게임과 puzzle books에 소개 된적이 있는 Jumble™ games (Newspaper sydication 과 온라인상에 있는) 의 저자인 David L. Hoyt 의 작품(두뇌의 소산)입니다.  Adveractive는 David와 2006년 같이 Pat Sajak 게임을 작업을 한 이래로 파트너로 일하고 있습니다. 우리는 Divid의 모든 온라인 게임을 작업했습니다. 지난 여름 Word Winder에 대한 핵심 게임 play에 대해 의논하기 위해 천재적인 game inventor Graeme Thomson, David와 같이 모여서 작업을 했었습니다. 이 게임은 아주 simple 합니다. 단 한줄로도 설명 될 수 있죠.

Win the game by being the first player to connect opposite sides of the game board with words that form a continuous winding line of letters.
계속해서 구불구불한 줄을 만드는 글자과 함께 game 화면의 반대편까지 도달하면 이기는 겁니다.


이 게임을 만든 우리 세사람 (David, Graeme 그리고 I)는 얼마나 많은 word game player들로부터 "내가 사용해본 게임중에 최고다"라는 말을 들었는지 다 말씀 드릴 수도 없습니다. 이 말을 들었을 때 우리는 smile 하고 고개를 끄떡였죠. '당근하지' 라고 생각하면서요 ^^ 그리고 들으면서 아주 기분이 좋았습니다.

코로나에게 이렇게 Word Winder 에 대해 횡설수설하게 설명할 수 있는 기회를 주셔서 감사의 말씀을 드립니다. 우리는 3번째 사랑의 관계에 빠졌습니다. 그리고 우리의 word game 작업에 아주 열심히 임하고 있습니다.

-Steve Bullock, Adveractive Inc.

반응형

FAQ Wednesday #6

2012. 5. 25. 10:23 | Posted by 솔웅


반응형
FAQ Wednesday #6

Posted by

또 다른 FAQ를 다룰 수요일 입니다. 아래 5개의 질문과 답변이 있습니다.

Question 1

어떻게 Corona window를 데스크탑으로 다시 가지고 올 수 있죠?

Answer

윈도우 시스템을 사용할 때 발생할 수 있는 일입니다. 만약 external display 를 사용하고 있는데 프로그램이 display 없이 restart 했을 경우에 일어나죠. 프로그램이 hang 된 것이 아닙니다. 그냥 존재하지 않는 display에 표시하려고 하는 겁니다. Corona Windows Simulator에서 일어날 수 있습니다. (맥에서는 발생하지 않습니다.) 아래 윈도우로 다시 되돌릴 수 있는 방법이 있습니다.

- task bar에 있는 Corona Simulator tab에서 오른쪽 마우스를 누릅니다.
- move 를 클릭합니다.
- 화살펴 키를 누르세요.
- 없어진 window 가 display 에 보일 때까지 옮겨 주세요.
- move를 stop 하려면 Left click을 하세요.


이렇게 하시면 됩니다. 나중에는 윈도우에서 이런 상황이 발생하지 않도록 만들어지기를 바랍니다.

Question 2

Game Center에 제 최고 점수를 세팅했는데 없어졌어요. 왜죠?

Answer

최고점수를 세팅하거나 Achievement를 unlocking 하는 것을 Game Center 서버를 통해 전파하는데는 시간이 좀 걸립니다. 이 의미는 set 된 다음에 곧바로 새 점수나 achievement가 보이지 않는다는 얘기죠. gameNetwork.show API를 사용해서 새로운 정보를 return 받는데는 24시간 정도 걸릴 수 있다는 것을 예전에도 알려드린 바 있습니다. 최고 점수나 achievement unlock 을 하고 gameNetwork.request를 사용해서 loadScore 나 loadAchievement를 하는 것은 몇시간이 걸리지는 않습니다. 그냥 몇초 정도 걸릴겁니다. 단지 그것이 세팅되고 난 후 곧바로 그 정보가 count 되지는 않습니다. 곧바로 display 되어야 한다면 그 정보는 local에 저장되는것이 맞습니다.


Question 3

제 앱은 GameCenter에 대해 gameNetwork.init API를 사용합니다. Game center 로그인창을 띄우기 위해서죠. 유저가 로그인을 하지 않고 Cancel을 누를경우 제 앱에서는 이 후에 유저에게 다시는 sign in 하라는 메세지를 띄우지 않습니다. 이 Sign-in dialog 창(로그인 창)을 어떻게 하면 다시 띄울 수 있죠?

Answer

만약 유저가 게임센터 로그인창에서 Cancel을 누른다면 게임센터 initCallBall 은 event.data = false 라는 값을 return 할 겁니다. 로그인이 실패했다는 것을 알리는 것이죠. 유저기 앱에서 force quit 을 하지 않는 이상 혹은 native iOS Game Center 앱을 사용해서 다시 로그인을 하지 않는 이상 이 로그인 창을 다시 불러오는 방법은 없습니다. Note: false status를 받은 이후에 gameNetwork.init을 부르면 로그인 창이 다시 뜨지 않습니다.

성공적으로 로그인 하거나 앱이 resume 되고 유저가 계속 Game Center에 로그인 된 상태에서 initCallback은 event.data = true를 return 합니다. 이 true status를 받은 이후에 여러분의 앱은 다른 gameNetwork API를 call 해야 합니다.

이 behavior는 Corona에만 해당 되는 것은 아닙니다. Game Center의 흐름이 그렇습니다. 그리고 로그인 창이 다시 뜨지 않는것이 맞다고 생각합니다. 유저가 cancel을 했다는 것은 그 앱에서 Game Center를 사용하고 싶어하지 않는 다는 의미이기 때문입니다.

Question 4

왜 나는 안드로이드 디바이스에서 어떤 파일들은 access 할 수 없죠?

Answer

Corona에서 File access는 OS 에 근거해서 작동합니다. platform에 의존하는 것이죠. iOS 디바이스에서는 여러분은 Resource directory(main.lua 가 있는 곳)에서 file들을 access 할 수 있습니다. 그리고 Documents와 Temporary directory에서도 접근할 수 있습니다. 안드로이드에서는 Resource directory 접근에 제한이 있습니다. 왜냐하면 그건 실제 디렉토리가 아니기 때문이죠. 파일들은 zip 파일로 enclose 됩니다. 코로나는 audio와 image API를 사용해서 이미지와 오디오를 직접 로딩할 수 있도록 합니다. 하지만 file I/O API를 이용해서 Resource 파일에 접근하는데는 제한이 있습니다. 이 때문에 안드로이드에서는 Resource directory 나 그 subdirectory에 있는 파일에 접근하기 위해 Lua File System(LFS)를 사용할 수 없습니다. 안드로이드에서 Document와 Temporary directory에있는 파일과 서브디렉토리 접근은 가능합니다.

디렉토리를 생성하고 없애기 위해 LFS를 사용할 때 유념해야 할 부분들이 있습니다. 첫번째로 파일이다 디렉토리에 접근할 때 full path string을 사용하셔야 합니다. (system.pathForFile을 이용해서) 그리고 lfs.chdir이나 lfs.currentDir API를 사용하시면 안됩니다. 현재의 디렉토리 개념은 platform 별로 다릅니다.

Resource Directory는 platform 에 의존하는 것이죠. 이 디렉토리 안에 파일이나 서브디렉토리를 만들거나 작성할 수 없습니다.

Corona 파일 접근은 플랫폼의 파일 시스템 sandbox에 따라 제한을 받습니다. sandbox 는 OS와 다른 앱의 파일들로부터 독립적인 그 앱의 공간을 위한 제한을 둡니다.

서브디렉토리를 add 하는 것은 여러분 app 개발 하는데 필요할 겁니다. 하지만 거기에는 제한사항들이 있다는 것 (위에서 언급한 안드로이드 제한 등) 그리고 어떤 기능은 미래의 플랫폼에서는 implement 되지 않을 수도 있다는 것을 염두에 두셔야 합니다. 거기에 대한 대비책은 여러분의 파일이나 디렉토리를 최대한 simple하게 유지하셔서 미래의 변화에도 영향이 없도록 하는 방법이 있을 겁니다.

LFS는 Daily Build #2012.805 부터 implement 됐습니다. 좀 더 많은 정보는 여기를 보세요.

Question 5

어떻게 audoi stream 파일을 처음부터 restart 할 수 있죠?

Answer

Audio stream (audio.loadStream으로 audio를 로드 한 것)은 항상 남은 부분부터 play 합니다. 만약 다시 streaming 할 필요가 있으시면 audio.rewind나 audio.seek(0) 을 이용해서 오디오를 처음부터 다시 시작하도록 하실 수 있습니다.

여기까지가 오늘의 questions 입니다. 즐겁고 유익한 시간이 되셨기를 바랍니다.

반응형

Handling Corona System Events

2012. 5. 22. 11:06 | Posted by 솔웅


반응형

Handling Corona System Events

어플리케이션을 개발 할 때 유저가 다양하게 여러분의 앱을 다루게 되는데 그에 대해 어떤 동작을 할 수 있도록 기능을 구현하는것은 아주 중요합니다. 또한 유저가 의도했던 안했던 다양한 system 에 대해 반응하는 것도 아주 중요합니다.


예를 들어 만약에 여러분의 앱을 사용하고 있는 중간에 유저에게 전화가 걸려온다던가 혹은 유저가 home 버튼을 누를 수도 있겠죠, 이 경우엔 여러분의 앱은 background에서 작동하고 있을겁니다. suspended나 paused 상태가 되서 말이죠.). 이렇게 suspended 된 상황에서 유저가 다시 앱으로 돌아왔을 때나 앱을 완전히 exit 했을 때도 발생할 수 있습니다.


코로나에서는 이러한 모든 것들을 system 이벤트에서 처리합니다. 오늘은 이 system 이벤트에 대해서 다룰겁니다.





Event Listener

여러분의 코로나 앱에서 system event 모니터링을 시작하기에 앞서 listener 함수를 set up 해야 합니다. 그리고 system 이벤트 리스너 를 add 하셔야 합니다. 만약 여러분이 코로나의 events 와 친하지 않으시다면 The Corona Event Model Explained document 를 먼저 보시고 다음 진도를 나가시라고 권해드립니다.

아래 코드는 event listener를 어떻게 set up 하는지를 보여드립니다. 그리고 글로벌 Runtime object를 add 합니다.  (이 object는 유일하게 system 이벤트를 listen 할 수 있는 object 입니다.)

local function onSystemEvent( event )

    -- Test for different event types here

end
Runtime:addEventListener( "system", onSystemEvent )

applicationStart


local function onSystemEvent( event )
    if event.type == "applicationStart" then

        do_something()

    end
end


위의 샘플코드는 여러분의 system event listener에서 applicationStart 이벤트를 어떻게 테스트 하는지 보여드립니다.

main.lua 가 가동되고 앱이 시작될 때 이 applicationStart 이벤트를 받습니다.

applicationExit

local function onSystemEvent( event )
    if event.type == "applicationExit" then

        do_something()

    end
end


applicationexit 시스템 이벤트는 앱이 끝나기 바로 직전에 dispatch됩니다. (suspending 이 아니라 완전히 끝날 때 입니다.) 이것은 유저가 끝낼 수도 있고 어떤 이유에서인가 시스템이 끝낼수도 있습니다. (메모리 부족 등)

이 이벤트는 앱이 끝나기 직전에 데이터를 저장하고 디비 연결을 끊는 일을 해야 할 때 많이 사용됩니다.

applicationSuspend

local function onSystemEvent( event )
    if event.type == "applicationSuspend" then

        do_something()

    end
end


앱이 실행중에 전화가 온다던가 아니면 유저가 switch out 시킨다던가 또는 유저가 power 버튼을 눌러서 디바이스를 sleep 상태로 돌릴때 여러분의 앱은 suspend 상태로 됩니다. (끝나지는 않은 상태입니다.)

suspended state로 가기 직전에 applicationSuspend 이벤트가 dispatch 됩니다. 이 이벤트를 이용해서 게임을 pause 시키는 일 등을 하실 수 있습니다. (그러면 다시 앱으로 돌아올 때 유저는 이 pause 화면을 볼 수 있을 있겠죠.) 그리고 필요하면 시간을 mark 할 수도 있고 timer나 transision 들을 pause나 stop 시킬 수도 있습니다.

applicationResume

local function onSystemEvent( event )
    if event.type == "applicationResume" then

        do_something()

    end
end


suspended 되기 전에 무엇인가를 할 수 있듯이 앱이 다시 돌아올 때도 무엇인가를 할 수 있습니다. 이렇게 앱이 다시 돌아오자마자 applicationResume 이벤트가 dispatch 됩니다.

Putting it all together

local function onSystemEvent( event )
    if event.type == "applicationStart" then

        -- this block executed when application launches (after main.lua)

    elseif event.type == "applicationExit" then

        -- this block executed just prior to the app quitting
        -- OS closes least recently used app, user explicitly quits, etc.

    elseif event.type == "applicationSuspend" then

        -- this block executed when app goes into "suspend" state
        -- e.g. user receives phone call, presses home button, etc.

    elseif event.type == "applicationResume" then

        -- this block executed when app resumes from "suspend" state
        -- e.g. user goes back into app (while it is still running in bg)

    end
end
Runtime:addEventListener( "system", onSystemEvent )


위 예제는 system event listener 의 기본 골간입니다. 이 예제를 탬플릿으로 사용하셔서 이용하시면 편하실 겁니다. 저 안에 어떤 동작을 넣을 지는 여러분 필요에 따라 구현하셔야겠죠.

이 기능들이 모든 앱에서 반드시 사용되어야 하는 것은 아니지만 많은 경우에 이 기능을 이용하면 아주 훌륭한 앱이 되도록 구현할 수 있을 겁니다.

여러분의 앱을 release 하시기 전에 내 앱이 suspended mode로 됐을 때 내 앱은 어떻게 해야 할까? 다시 돌아올 때는 무엇을 할까? 를 한번 생각 해 보세요. 여러분 앱이 훨씬 수준있는 앱이 될 수 있을 겁니다.



반응형

수요일의 FAQ 5 번째 시간

2012. 5. 21. 06:58 | Posted by 솔웅


반응형

FAQ Wednesday #5


Question 1

Lua File System(LFS)를 추가하셨죠? /Documents directory 에서 파일 리스트를 얻으려면 어떻게 해야하죠?

Answer

Lua File System은 Corona build 2012.805 에서부터 추가됐습니다. 여기에서 튜토리얼을 읽어보실 수 있습니다.

LFS는 subdirectory도 만들고 지우고 접근할 수 있게 됐습니다. 구현은 디렉토리의 path를 담은 string을 만드는게 key 입니다. iOS와 Android에서는 3개의 main directory들이 있습니다. Resource, Temporary 그리고 Documents 가 그것입니다. 이것들은 Corona constant들을 사용해서 접근하게 됩니다. userdata constants들은 LFS에서 사용될 수  있으려면 string으로 변환 될 필요가 있습니다. system.pathForFile 는 userdata constant 로 변환 됩니다. (string 타입으로). 여러분은 base directory와 함께 파일이나 디렉토리명을 명시해주시면 됩니다. 그러면 그것은 전체 경로를 return 하게 됩니다.

local path = system.pathForFile( "data", system.DocumentsDirectory )

위 코드는 다음과 같은 string을 return 할 겁니다. “/var/mobile/Applications//Documents/data”



아래에 file들 리스트를 LFS로 어떻게 출력되게 하는지에 대한 코드가 있습니다.


local lfs = require "lfs"

-- Print the files in the path
--
local function printDir( path )
    print( "\nFiles in path: " .. tostring( path ) )
 
    local pathType = ""
 
    -- Check to see if path exists
    if path and lfs.attributes( path ) then
        pathType = lfs.attributes( path ).mode
    end
 
    if pathType == "directory" then
        for file in lfs.dir( path ) do
            local str

            -- Skip the current and up-one directories
            if "." ~= file and ".." ~= file then
                str = file

                local fileAtr = lfs.attributes( path .. "/" .. file )
                if fileAtr then
                    str = str .. " --> (" .. fileAtr.mode .. ")"
                else
                    str = str .. " --> (none)"
                end

                print( str )
            end
        end
    else
        str = "Path is not a directory!"
        print( str )
    end
end


그리고 아래는 /Documents directory와 /Documents/data subdirectory 를 어떻게 불러서 출력하는지를 보여 줍니다. (만약 존재한다면)

path = system.pathForFile( nil, system.DocumentsDirectory)
printDir( path )
path = system.pathForFile( data, system.DocumentsDirectory)
printDir( path )


위 코드는 파일 이름들을 출력하는 대신 table(배열)에 담아서 활용할 수도 있을 겁니다.


Question 2


Resource 디렉토리의 파일에 접근을 시도할 때 warning과 error를 하나씩 받았습니다. 이거 버그인가요?


Answer

system.pathForFile 를 사용하고 베이스 디렉토리가 system.ResourceDirectory 일때  코로나는 file이 존재하는지 살펴보고 그 path에 대해 nil 값이 받아지면 warning 메세지를 발생시킵니다. 그런데 이것은 filename 파라미터가 실제로 디렉토리 이름이면 작동하지 않습니다. 이것을 이용해서 다음과 같은 트릭을 쓰기도 합니다. 

local path = system.pathForFile( nil, system.ResourceDirectory )


이렇게 하면 warning 메세지를 발생하지 않습니다. 그리고 Resource directory를 가리키는 string을 return 하죠. 이 Resource directory 밑에 subdirectory 의 경로를 생성할 필요가 있으면 다음과 같이 이것을 append 하시면 됩니다.

path = system.pathForFile( nil, system.ResourceDirectory)
printDir( path )
path = system.pathForFile( nil, system.ResourceDirectory) .."/".."data"
printDir( path )

Note : system.ResourceDirectory는 안드로이드에서는 Resource directory가 실제 file system의 일부분이 아니기 때문에 작동하지 않습니다.

그리고 Resource directory는 read-only 디렉토리라서 write 할 수 없다는 것도 기억하세요.


Question 3

single touch app에 Multitouch 세팅하기

Answer

이건 질문은 아니지만 하나의 tip으로서 알려드립니다. 코로나에서 디폴트는 multitouch off 입니다. 이 말은 touch listener 가 있다면 한번에 하나의 touch 이벤트를 받는 다는 말입니다. 만약에 유저가 스크린을 터치하고 있는데 다른 손가락으로 버튼을 tap 한다거나 다른 객체를 move 하면 아무 일도 일어나지 않습니다. 왜냐하면 이미 다른 touch 가 active 돼 있기 때문이죠. 이것은 landscape 모드에서 유저가 손가락을 스크린에 대고 있느라고 자주 발생할 수 있는 현상이죠.

해결 방법은 여러분 코드에 아래와 같이 구현하는 겁니다.

system.activate( "multitouch" )

이렇게 하면 스크린에 손가락으로 하는 모든 touch에 touch event를 발생할 겁니다. touch 리스너를 걸어놓은 객체를 터치하지 않는 이상 아무일도 발생하지 않을 겁니다. 그리고 리스너가 있는 객체를 터치하면 동작이 일어나구요. 그렇게 되면 좀 더 user friendly 한 앱이 될 겁니다.


Question 4

iOS에서 앱 아이콘의 badge number를 어떻게 clear 하게 할 수 있을까요?


Answer


Local Notification은 해당 Notification이 일어나면 앱의 아이콘에 badge number를 세팅할 겁니다.(그것은 뭔가 pending 된게 있다는 것을 알리기 위함이죠.) 하지만 이것을 어떻게 clear 시킬 수 있을 까요? 해답은 native.setProperty API에 있습니다.

native.setProperty( "ApplicationBadgeIconNumber", 0 )

이렇게 하면 앱 아이콘에 있는 badge number를 없앨 수 있습니다.

아래 badge를 clears 시키는 Local Notification code 예제가 있습니다.

display.newText( "Setting Local Notification ...", 10, 30 )

-- Options for iOS
local options = {
   alert = "Wake up!",
   badge = 1,
   sound = "alarm.caf",
   custom = { foo = "bar" }
}

-- schedule using UTC (Coordinated Universal Time) time + 60 seconds
local utcTime = os.date( "!*t", os.time() + 60 )
local notification = system.scheduleNotification( utcTime, options )

-- Local Notification listener
local notificationListener = function( event )
   display.newText( "Notification Received " ..  event.badge, 10, 70 )
   native.setProperty( "applicationIconBadgeNumber", 0 )
end

Runtime:addEventListener( "notification", notificationListener )

Note: badge number 가 증가하거나 감소하는것에 대해서 badge 관련된 부분의 documentation에 설명 돼 있습니다. 이것은 애플의 documentation에서 인용한 겁니다. 그리고 그 의미는 여러분이 코드 내에서 그 badge number를 증가시키거나 감소시킬 수 있다는 것이죠. 코드 내에서 여러분이 명시한 badge number는 icon 에 display 되게 됩니다. 이 badge number 를 0으로 세팅하면 badge를 clear(remove) 하게 됩니다.

Local이나 Push Notification은 아직까지 iOS에서만 가능합니다.

Question 5

유저가 스크린을 터치하지 않고 있으면 device가 sleep 모드로 가는데 제가 만든 게임을 하는 동안에는 그 현상이 안 일어났으면 좋겠습니다. 가능한가요?


Answer

Yes, and the solution is one of the “system” APIs that works on both iOS and Android (but not in the simulators).

가능합니다. system API를 이용하시면 iOS와 Android 모두에서 가능합니다. (시뮬레이터에서는 안 됩니다.)

system.setIdleTimer( false )  -- disable device sleep mode

idle timer를 false로 해서 디바이스가 sleep 모드로 가지 않도록 합니다. true로 가면 sleep 모드로 가게 됩니다. 디폴트는 true 입니다. 이것을 false로 하면 디바이스의 배터리가 더 빨리 닳을 수가 있다는 것을 감안해서 사용하시기 바랍니다.

여기까지가 오늘의 Question들 입니다. 여러분에게 유용한 정보가 되었기를 바랍니다.

감사합니다.


반응형


반응형

스페인에서 Corona SDK 대사로 활동하고 있는 Tomas라는 친구가 전 세계적인 Corona 연맹 결성을 제안했습니다. 좀 황당하게 들렸지만 글을 읽어보니 열정이 느껴지네요. ^^



Spain’s Corona Ambassador and owner of Inkubica Labs, Tomas Martinez Buero, is calling on developers around the world to form a Corona Alliance. The Spanish chapter’s first Corona SDK Meetup will be taking place on May 31 in Madrid – don’t forget to register if you’re in the area!


스페인의 코로나 명예대사이자 Inkubica Labs의 owner인 Tomas Martinez Buero는 전세계적으로 코로나 연맹을 결성할 것을 제의했습니다. Spanish 쪽의 첫번째 Corona SDK Meetup이 5월 31일 마드리드에서 열릴겁니다. 근처에 사시는 분은 꼭 register하시는 것을 잊지 마세요.





Inkubica Labs is a software “gamification” company that is constantly improving its platform for edutainment apps, interactive books and serious games. The demand for these kind of apps is so big that we are looking for studios and independent Corona SDK developers worldwide to create a Corona Alliance!


Inkubica Labs은 edutainment apps, interactive books와 게임등을 꾸준히 개발하면서 성장해가는 software “gamification” company 입니다. 이런 종류의 앱들에 대한 수요는 아주 많습니다. 그래서 우리는 전세계적인 개별 코로나 SDK 개발자들이 참여하는 Corona 연맹을 만들기를 원합니다.


Inkubica Labs is the dream of two entrepreneurial Computer Sciences engineers, my partner Oscar Cuenca and I, who think that intelligent production of software can change the world. The name of Inkubica has two meanings: the broader one, that is related to the fact that we incubate business projects based on software, and the more specific one, associated with what we are doing now, “raising the INK into the third dimension.” (We help publishers produce interactive books and edutainment apps around the world.)


Inkubica Labs는 두 기업가 마인드를 가진 컴퓨터 공학들의 꿈입니다. 제 파트너인 Oscar Cuenca와 저는 intelligent 한 소프트웨어 제품이 세상을 변하게 할 수 있다고 생각합니다. Inkubica라는 이름은 두가지 의미가 있습니다. 하나는 더 넓게 라는 의미이고 이것은 소프트웨어분야를 바탕으로 비지니스 프로젝트를 incubate 하겠다는 것과 관련이 있구요. 두번째는 좀 더 specific 한 이란 뜻으로 지금 현재 저희가 하고 있는 “raising the INK into the third dimension.” (잉크를 3차원으로 끌어올리자... 라고 해석하면 될까요???;;)와 관련 돼 있습니다. (우리는 전 세계적으로 interactive book이나 edutainment app 들을 만들어내는 publisher들을 도와주고 있습니다.)


The Inkubica Labs team has very solid experience developing many kinds of software. In 1999, we programed our first mobile applications, starting with WAP when it wasn’t available for mobile! At that time, we were visionaries but we came too early. In 2001, we were expecting to see many mobile devices using 3G with WAP, and we were not the only ones to fail in these predictions. Now, we don’t need to be visionaries to know that this is a big time for mobile apps. And in regards to tablets, that’s a whole new world we didn´t predict 13 years ago!


Inkubica Labs 팀은 다양한 종류의 소프트웨어를 개발한 경험을 가지고 있습니다. 1999년에 우리는 첫번째 모바일 애플리케이션을 프로그래밍 했습니다. WAP을 사용한다는 개념이었는데요. 당시에는 이것이 모부일쪽에 사용되지 않을 때였습니다. 당시 우리는 공상가였을 뿐이지만 그것이 현실화 되는 것은 생각보다 빨리 왔습니다. 2001년 WAP과 함께 3G를 사용하는 많은 모바일 디바이스를 기대했었습니다. 지금은 여러분이 아시다시피 모바일앱이 더이상 공상이 아니라 실제로 큰 시장이 돼 버렸습니다. 그리고 태블릿쪽은 13년전에 우리가 상상하지도 못했던 분야입니다.


So here we are, in our second opportunity to be successful with mobile (and now with tablets too). The first thing we decided was to chose the right partners. After evaluating several tools, frameworks, platforms, etc. we fell in love with Corona SDK, not only because it enables us to code once and have the apps ready for iOS and Android, but also because we found very powerful APIs that help us do complex things very fast. And speed is the key of this market!


이제 우리는 모바일로 두번째 성공할 기회를 맞고 있습니다.(뿐만아니라 태블릿도 있죠.) 첫번째로 우리는 좋은 파트너를 골라야겠다고 결심했습니다. 여러 툴들과 프레임워크들과 플랫폼 등등에대한 검토 결과 Corona SDK 와 사랑에 빠지게 됐습니다. 한번 코딩해서 iOS와 안드로이드에 동시에 빌드할 수 있다는 이유만이 아닙니다. 아주 복잡한 것을 쉽고 빠르게 구현하게 해 주는 아주 powerful한 API도 중요한 이유입니다. 속도(빠른 대응)은 시장에서 가장 중요한 요소입니다.


We want to keep moving with the support and improvements of Ansca Mobile – developing apps with geolocalization, augmented reality, simulations, and QR codes and are very interested in forming a Corona Alliance. The main publishers of the Spanish and Portuguese speaking world have headquarters in Spain, with offices in Brazil, Mexico, Argentina, Chile, Colombia, Portugal, and Peru. Let’s join forces and go for them together! You don’t need to speak Spanish or Portuguese to work with us, but we do ask that you can communicate in English. :-)


우리는 Ansca Mobile의 지원과 꾸준한 성능향상과 함께 나갈겁니다. developing apps with geolocalization, augmented reality, simulations, and QR codes 들은 Corona 연맹의 주요 관심사항들 입니다. 스페인어와 포르투갈어를 사용하는 세계의 헤드쿼터는 스페인에 있습니다. 그리고 지부 사부실은 브라질과 멕시코, 아르헨티나, 칠레, 콜롬비아, 포르투갈 그리고 페루에 있습니다. 들어오셔서 같이 합시다. 우리와 같이 일하기 위해 꼭 스페인어와 포르투갈어를 사용하실 필요가 없습니다. 그런경우 영어로 소통할 수도 있습니다.


If you are interested, just send me an mail to tomas.martinez@inkubica.com.

On May 31, we will be hosting the first Corona SDK Meeting in Spain! Please join us and register here.


관심 있으시면  tomas.martinez@inkubica.com로 메일을 보내주세요. 5월 31일 우리는 첫번째 corona SDK Meeting을 스페인에서 가질 예정입니다. 함께 하시려면  here에 등록해 주세요.


Tomas Martinez Buero, Inkubica Labs


Madrid, Spain


반응형


반응형

새로 아파트에 들어왔습니다.
그동안 Holiday Inn 에서 출퇴근하다 10일에 이사를 했어요.

새로 인터넷을 신청했는데 17일에나 설치를 해 준다네요.

인터넷 쓸 일이 있어서 집 근처 스타벅스에 와서 인터넷 사용하고 있습니다.


==========================

My Favorite Corona App - Twitter Contest

by ANSCA Inc on Tuesday, May 8, 2012 at 2:15pm ·


We couldn't get enough of all the Twitter love from last week's contest, and this week we're going to up the ante!


지난주 열화와 같은 참여와 성원에 감사드립니다. 이번주도 금주의 콘테스트로 여러분을 찾아 뵙습니다.

 

Tweet us your FAVORITE Corona-built app for a chance to win a 3-month subscription to (or extension of) a Corona Pro license. We'll select two (2) lucky winners at random. If you need some inspiration for great Corona-made apps, check out our showcase: http://developer.anscamobile.com/showcase/Browse_All


Corona로 만든 앱 중에 여러분이 가장 좋아하는 앱을 저희에게 트윗해 주세요. 당첨되신 분께는 코로나 SDK 3개월 무료 이용 권한을 드립니다. (기존 회원은 3개월 연장 시켜 드릴거구요.) 랜덤하게 두분을 추첨할 겁니다. 코로나로 만든 앱이 어떤 것이 있는지 알고 싶으신 분들은 저의 홈페이지의 showcase를 들러 주세요.

http://developer.anscamobile.com/showcase/Browse_All

 





The rules are simple:


규칙은 간단합니다.

  1. Follow @ansca on Twitter.  트위터에서 @ansca를 팔로우하세요.
  2. Like us on Facebook: www.facebook.com/ansca . Facebook에서도 등록해 주세요.
  3. Tweet us your very favorite Corona-made app . 여러분이 좋아하는 코로나로 만든 앱을 트윗해 주세요.

Last day to enter the contest is Sunday, May 13 at 11:59pm PT.


마감일은 미국 태평양 시간(PT)으로 5월 13일 11:59PM 까지 입니다.


Happy tweeting and good luck!


===============================================


여러분들도 많이 참여하시고 행운도 얻으세요...




반응형

FAQ Wednesday #4 - Corona SDK -

2012. 5. 10. 08:51 | Posted by 솔웅


반응형

FAQ Wednesday #4

수요일입니다. FAQ 시간이죠. 아래에 자주 질문되는 5가지 문답이 있습니다. (FAQ)

Question 1

함수를 만들 때 가끔 함수 이름이 nil 이라는 에러 메세지를 가끔 보게 됩니다. 그것을 바로잡기 위해 이렇게 저렇게 코딩을 바꾸는데요. 함수 생성과 관련해서 올바른 방법은 뭔가요?

Answer

일반적으로 Lua 는 변수가 Local 일 경우에 변수에 forward references 를 요구합니다. 이 의미는 변수가 사용될 수 있게 하기 전에 변수가 정의 될 필요가 있습니다. 아래 예제를 보세요.


local function getTax( num )
    return num * 0.0825
end


print( getTax( 99.95 ) )

위의 코드는 정상적으로 동작할 겁니다. 왜냐하면 getTax가 먼저 정의 됐기 때문이죠.

print( getTax( 99.95 ) )

local function getTax( num )

    return num * 0.0825
end


The above doesn’t work because getTax is unknown and returns with a “nil” error. If you always define your variables or functions first (before being called), you won’t have any problems, but sometimes you can’t avoid it. Here is how you can fix 

위와 같이 하면 에러가 날겁니다. 왜냐하면 getTax가 아직 정의 되지 않았는데 print를 하니까 nil 에러가 날겁니다. 먼저 변수나 함수를 정의하면 (call 되기 전에) 문제는 없을겁니다. 그런데 좀 예외적인 경우도 있습니다.

local getTax -- forward reference

local function printTax()

    print( getTax( 99.95 ) )
end

function getTax( num )

    return num * 0.0825
end

printTax()

이 경우에는 작동합니다. 우선 변수 getTx가 먼저 정의 됐구요. 그 다음에 getTax 함수가 정의 되기 전에 이 getTax 함수를 call 했습니다. 그리고 나서 getTax 함수를 만들었습니다. 이 경우는 getTax는 함수이기 때문에 printTax 함수 안에서 이 getTax를 call 하는 경우는 getTax 함수가 이미 정의되고 값이 할당 된 후이기 때문에 제대로 작동합니다.

자주 하는 실수는 아래와 같은 경우가 있습니다.

local getTax -- forward reference

local function printTax()

    print( getTax( 99.95 ) )
end

local function getTax( num )

    return num * 0.0825
end

printTax()

이렇게 하면 nil 에러가 발생합니다. 그 이유는 getTax 함수가 local 로 선언됐기 때문입니다. 이미 getTax 변수를 local로 선언했습니다. 그러고 나서 함수 앞에 또 한번 local 을 붙인다면 Lua 는 새로운 local 변수를 정의하게 됩니다. 그래서 원래의 getTax 변수는 nil이 되 버리는 거죠. 직접 이 코드에 local을 붙였다 뺐다 하고 함수 선언의 위치를 여기 저기 바꾸면서 한번 테스트 해 보시면 많은 도움이 될 겁니다.

모든 변수를 global로 선언하면 이런 문제는 발생하지 않겠죠. global로 선언하려면 그냥 local 글자를 빼면 됩니다. 이렇게 global로 몇개의 변수를 선언하는 건 괜찮을 겁니다. 하지만 변수가 무수히 많거나 퍼포먼스가 문제가 된다면 이 방법은 추천하고 싶지 않습니다. 그리고 많은 변수들과 함께 모듈을 로딩하는 경우에도 추천하지 않습니다.

변수와 관련되서는 더 많은 부분을 보실 수 있습니다. Lua 5.1 Reference Manual을 보시기 바랍니다.

Question 2

native.webPopup으로 웹사이트에 접근 했을 때 어떻게 HTTP status code를 얻을 수 있을까요?

Answer

HTTP Status Code 는 웹서버에서 return 되구요 이것은 HTTP request가 성공적으로 동작했는지 아닌지를 알 수 있도록 해 줍니다. 아래 흔히 받을 수 있는 status code들이 있습니다.

  • 200 OK
  • 301 Moved Permanenly
  • 404 Not Found
  • 500 Internal Server Error

이것과 관련된 좀 더 많은 정보는 여기로 가서 확인하세요.

코로나에서는 native.wevPopupnative.webView은 HTTP status code를 제공하지 않습니다. 다만 network.request에서는 제공합니다. (현재까지의 버전에서는요.). wepPopup이나 webView 의 event.isError는 서버에 연결되지 않았을 때 발생하는 겁니다. 서버에는 접속했는데 404에러 (page not found) 가 났다면 isError는 발생하지 않습니다. 이 HTTP Status Code를 받으시려면 웹페이지에 처음 접속할 때 network.request를 사용하셔야 합니다.

아래 그 예제가 있습니다.

local function loadWebPage()
    native.showWebPopup(10, 10, 300, 300, url )
end

local function networkListener( event )

    if( event.isError ) then
        print( "Network error: ", event.response )
    else
        print( "Status Code: " .. event.status )
        if event.status == 200 then
            print( "Loading web page ..." )
            loadWebPage()
        else
            print( "Web page not loaded!" )
        end
    end
end

network.request( url, "GET", networkListener )

이 코드는 웹 페이지에 접근할 때 먼저 network.request를 call 합니다. status가 200이라면 loadWebPage가 call 될 겁니다. 그리고 페이지는 native.webPopup을 이용해 로드 될 겁니다.

Note: native.webBiew는 iOS에서 native.webPopup 대신에 사용하려고 만든 겁니다. 이 메소드가 웹페이지를 표시할 때 사용하시기를 추천합니다. 이 API도 조만간에 안드로이드, 맥, 윈도우에서도 사용할 수 있도록 하겠습니다.

Question 3

내가 빌드 할 때 Ansca가 저의 소스를 보나요? 제 소스를 빌드하기 위해 정보가 당신의 서버에 전달할 때 어떻게 보안이 유지 되나요?

Answer

온라인 빌드가 일어날 때 우리의 서버는 절대 여러분의 raw source code를 보지 않습니다. 마찬가지로 여러분의 프로젝트 이미지, 사운드 또는 다른 asset들도 보지를 않습니다. Lua script는 우리 서버로 보내지기 전에 미리 bytecodes로 컴파일 됩니다. 서버에는 이 컴파일된 데이터를 처리할 코로나 엔진이 있습니다. 이 서버에서도 그 컴파일 된 파일을 절대 저장하거나 모아두지 않습니다.

Question 4

제가 API 페이지 (댓글란)에 버그 report를 했습니다. 그런데 왜 고쳐지지가 않죠?

Answer

API 페이지의 댓글란은 버그를 report 하거나 질문을 하는 곳이 아닙니다. 이 부분은 API documentation의 에러나 빠진 정보에 대해 report 하는 부분입니다.

만약에 API의 버그를 발견하셨다고 생각하시면 bug report를 해 주세요. 링크는 Forum과 Documentation 페이지의 윗쪽에 링크가 있습니다. 그리고 보내실 때는 되도록 자세히 적어서 보내 주세요. build number, 디바이스, OS 정보까지 포함해서요.

그리고 버그가 발생하는 경우의 전체 코드(config 파일등을 포함해서) 를 보내주시는 것이 중요합니다. 단지 코드 몇줄만 넣고 이 부분이 잘 안 된다고 설명만 하신다면 우리의 to do 리스트의 우선 순위에서 멀리 밀려날 겁니다. 저희는 아주 많은 버그 레포트를 받습니다. 이것을 가지고 샘플 테스트 케이스를 만들어서 문제점을 테스트 하는 것은 시간이 걸리는 일 입니다. 가끔 config.lua 파일이나 build.settings가 없어서 문제점을 찾지 못할 때도 있습니다. 버그가 여러분 문제를 해결하는데 중요한 부분이라면 그 전체 파일을 보내주시고 그 버그를 보려면 어떻게 해야 하는지에 대한 설명을 같이 보내 주세요.

저희는 지금 새로운 documentation system 을 만들고 있습니다. 그리고 곧 발표하게 될 겁니다. 이 새로운 시스템은 댓글란이 없습니다. 그 때는 API 관련 질문은 포럼이나 bug report를 이용하셔야 됩니다.

Question 5

제 코드를 디버그 하려고 print 구문을 넣었습니다. 그런데 nil 에러가 많이 나요. 이 에러를 피할 수 있는 방법이 있나요?

Answer

아마 아래 코드처럼 해서 그런 문제가 발생할 겁니다.

print( "lineNumber = " .. lineNumber )

scoping problem이나 이전에 set  때문에 lineNumber가 nil 이라면  print 구문은 이렇게 나올 겁니다. “attempt to concatenate ‘lineNumber’ (a nil value)”.

이걸 해결 하려면 두 변수를 분리하기 위해 , 를 사용하실 수 있습니다.

print( "lineNumber = " , lineNumber )

이 경우에 concatenation error를 피할 수 있습니다. 그런데 이렇게 하면 lineNumber 값을 print 하기 전에 원하지 않는 공간이 생길 겁니다.

“tostring”. 또 다른 방법으로는 tostring을 사용하는 방법이 있습니다.

print( "lineNumber = " .. tostring( lineNumber ) )

이렇게 하면 해당 값이 string으로 변환 됩니다. number, string , table, display object 등을 가리지 않고 심지어 그 값이 nil이라도 string으로 변환되죠.  이렇게 하면 print error 없이 print 구문을 사용할 수 있도록 해 줍니다.

여기까지가 오늘의 질문들 입니다. 여러분께 많은 도움이 됐기를 바랍니다.


반응형


반응형

지난주 화요일 첫출근을 해서 개발환경 세팅하고 새로운 것들 세팅하면서 보냈어요.

주말엔 볼일이 있어서 뉴저지 까지 다녀오고..


주말도 장거리 여행으로 시간을 모두 보냈네요.


지난 주 Corona SDK 관련 정리할 것들 하나도 정리 못했는데... 벌써 일요일 밤이 됐어요.


지금 정리할 시간은 없고 공부할 것들 메모를 해 놔야 겠어요. 나중에 시간이 되면 차근차근 공부 하려구요.




1. 새로운 Lua File System 이 곧 선보일 거라는 소식입니다.

2. Coder/s Deilemma 라는 제목이 관심이 가서 한번 정리해 두고 싶네요.

3. 모바일 Ads 회사인 inneractive 사가 프로모션을 하네요. 당선작은 선물이 Kindle Fire 라니까 한번 응모해 보고 싶군요.

4. Game Engine Dating Guide 라는 글도 관심이 갑니다. 도움이 많이 될 것 같아요.

5. 수요일의 FAQ 가 이번주에도 나왔습니다. 반드시 정리하고 넘어가야 할 사항이죠!

6. Blast Monkeys 라는 앱을 개발한 개발자가 성공스토리를 강의하는 내용입니다.



7. Property Call Back Tutorial 입니다.




정리해 두고 싶은게 너무 많군요.

새로 join 한 프로젝트에서 사용하는 테크닉도 Research 해야 하고.


하나하나 해 나가다 보면 다 되겠죠 뭐...


다시 신나는 월요일이 시작 됩니다......

반응형