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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

Posted on . Written by



구글 맵이 돌아왔습니다. 우리의 Corona iOS 앱에서 오늘 사용할 수 있습니다.

12-12-12 에 진짜 세계를 뒤 흔든 건 아이폰에 새 Google Maps app이 릴리즈 된 겁니다. 별로 신통치 않은 애플 맵을 대신 할 수 있게 됐죠. 구글은 turn-by-turn direction, vector based map tiles, 개선된 인터페이스 등을 새로 선보였습니다.



The URL Scheme


먼저 URL scheme의 origin 에 대해 알아보죠. WWW(World wide Web)이 처음 선보인  1990년대로 돌아가보죠. 개발자들은 뭔가 인터넷에서 어떤 것을 참조할 필요가 있었습니다. 그래서 그 참조할 정보의 위치를 간단하게 URL( Uniform Resource Locator)을 이용해서 찾아갔죠.


인터넷 상에서 access 할 수 있는 방법은 여러가지가 있습니다. 그리고 그것들은 단지 web page나 이미지들만이 아닙니다. terminal session을 열어서 Gopher 서비스에 연결할 수도 있고 FTP 서버로부터 파일을 다운로드 받을 수도있고 이메일 메세지를 보내고 하는 것들을 인터넷으로 할 수 있습니다.


colon 전의 URL 부분을 URL scheme이라고 합니다. 그 종류는 아래와 같습니다.

  • http: — a file from a web server
  • https: — a file from an encrypted web server
  • mailto: — send an email message
  • ftp: — access a file via FTP
  • telnet: — open terminal sessions to a server


iOS 에서는 이메일 안에 있는 전화번호를 touch 해서 dialer 를 열고 전화를 걸 수가 있습니다. 이런 기능들은 아래와 같은 URL schemes 를 사용해서 구현 합니다.


  • tel: — make a phone call
  • sms: — send a text message
  • itms-apps: — opens the app store
  • music: — go to the current playing song in the music app


애플은 애플리케이션이 자기 자신만의 scheme 을 define 하도록 합니다. 그래서 다른 앱에서 그 앱을 열수 있도록 허용합니다. Corona Labs 는 1년전에 이 기능을 제공했습니다. 이와 관련 된 글을 보시려면 여기를 클릭하세요.



Google Maps URL Scheme


Maps app 에 빠르게 접근하도록 하기 위해 Google 은 여러분 앱이 접근 가능하도록 URL scheme 을 사용합니다.


comgooglemaps:


물론 URL scheme 은 URL 의 일 부분입니다. 여기에 추가로 host 이름과 호스트상의 리소스들을 가집니다. 앱이 실제로 host name 이 없고 개별 파일로 접근할 필요가 없으면 full URL 은 아래와 같습니다.

comgooglemaps://


코로나에서는 이 API 를 아래와 같이 사용하시면 됩니다.


system.openURL("comgooglemaps://")



여러분의 앱은 suspend 상태가 되고 구글 맵이 시작될 겁니다. 간단하죠? 구글 맵에서 근처 피자가게를 찾고 싶으세요? 혹은 구글 맵에서 할 수 있는 다른 것을 여러분 앱에서 directly 하고 싶으세요?


URL scheme 에 다른 추가적인 정보를 덧붙이면 여러분 앱 안에서 그런 특정 기능을 사용하도록 하실 수 있습니다.





1. Map Coordinates and Traffic View


아래의 코드가 기본 형식입니다.

system.openURL("comgooglemaps://?center=40.765819,-73.975866&zoom=14&
views=traffic")




이렇게 하면 맵을 열고 traffic 상태를 보여 줍니다. 그리고 zoom level 은 14 이고 위도 경도는 40.7N and 73.9W 인 지점이 화면 가운데에 위치할 겁니다. 이 에제는 뉴욕의 센트럴 파크의 위치를 보여 줄 겁니다.

잘 보시면 첫번째 파라미터 전에 물음표가 있는것을 알아 채셨을 겁니다. 그리고 각 파라미터 사이는 &로 구분하구요. 그러니까 이 파라미터들을 분해하면 아래와 같이 되겠죠.


?center=40.765819,-73.975866   --center map at these coordinates
&zoom=14                       --zoom to level 14
&views=traffic                 --show traffic view


2. Map “Street View”

여기에 mapmode=streetview parameter를 추가하면 street view를 보실 수 있습니다.


system.openURL("comgooglemaps://?center=40.765819,-73.975866&
zoom=14&views=traffic&mapmode=streetview")


3. Map Query


맛있는 피자를 원하세요? 그러면은 q=pizza를 다른 파라미터 전에 추가히세요.


system.openURL("comgooglemaps://?q=pizza&center=40.765819,-73.975866")


4. Driving Directions


A 지점에서 B 지점까지의 경로는 어떻게 알 수 있을 까요?


system.openURL("comgooglemaps://?saddr=Google+Inc,+8th+Avenue,+New+York,+NY&
daddr=John+F.+Kennedy+International+Airport,+Van+Wyck+Expressway,
+Jamaica,+New+York&directionsmode=transit")



딱 보면 무지 복잡해 보이죠? 근데 자세히 보면 그냥 위와 같이 파라미터를 사용했을 뿐이예요.


?saddr=...         --"s" for "starting address"
&daddr=...         --"d" for "destination address"
&directionsmode=



+ 부호는 전부 다 뭘까요? 여기서 space 를 사용하면 문제가 발생할 수 있습니다. 그 space 를 + 부호로 대신 사용하는 겁니다. 아니면 hex code %20를 사용하셔도 됩니다.

근데 진짜 + 부호를 넣어야 되면 어떻게 할까요? 그럴 때는 hex code %2B 을 사용하셔야 됩니다.


Convenience Function


이렇게 파라미터를 추가하는게 짜증나시면 URL 을 encode 하는 함수를 사용하실 수도 있습니다.



function urlencode(str)
if (str) then
str = string.gsub (str, "\n", "\r\n")
str = string.gsub (str, "([^%w ])",
function (c) return string.format ("%%%02X", string.byte(c)) end)
str = string.gsub (str, " ", "+")
end
return str
end

system.openURL("comgooglemaps://?saddr=" .. 
urlencode("Google Inc., 8th Avenue, New York, NY") ..
"?daddr=" .. urlencode("John F. Kennedy International Airport,
Van Wyck Expressway, Jamaica, NY") .. "?directionsmode=transit")



보시듯이 openURL 안에 들어가는 것들을 함수로 간단하게 encoding 할 수 있습니다.



Maps App Installed or Not Installed?






URL scheme 에서 발생할 수 있는 문제는 디바이스에 구글앱이 깔려있지 않을 경우가 되겠죠? 깔려 있지 않으면 그 앱을 열 수가 없을 테니까요. 현재의 Corona Public Release(#971) 에서는 이럴 경우 화면과 같은 에러 메세지가 뜹니다. 아니면 그냥 silent fail 되던가요. 이건 바람직한 해결 방법이 아니죠.



Corona Daily Build #986부터 system.openURL() API를 call 했을 때 true/false를 리턴하기 때문에 이에 대해 대처할 수 있습니다.




 
local didOpenGoogleMaps =
system.openURL("comgooglemaps://?daddr=San+Francisco,+CA&saddr=cupertino")
if ( didOpenGoogleMaps == false ) then --defer to Apple Maps

system.openURL("http://maps.apple.com/?daddr=San+Francisco,+CA&saddr=cupertino")
end

  

디바이스에 구글 맵이 깔려 있으면  didOpenGoogleMaps 변수(변수명은 여러분이 정하실 수 있습니다)가  true 가 될 것이고 깔려있지 않으면 false 가 될 겁니다. 이렇게 되면 target 앱이 깔려 있지 않을 경우 개발자는 특정 메세지나 특정 action 을 구현할 수 있게 되죠. 이 기능은 Daily Build #986 부터 사용 가능합니다. 유료 사용자일 경우 여기에서 다운 받으세요.


Ready to Begin?


여러분이 보셨듯이 코로나에서 구글 맵을 implementation 하는 것은 URL scheme 을 사용해서 아주 간단하게 처리하실 수 있습니다.  구글 맵이 제공하는 모든 기능을 살펴 보시려면 구글 맵 URL Scheme 웹사이트로 가셔서 보실 수 있습니다. 만약 애플 맵을 사용하시거나 구글 맵의 백업기능 지원으로 애플 맵 기능을 지원하시려면 이 문서를 참조하세요.



반응형


반응형

Posted on . Written by


처음부터 저희들의 미션은 여러분의 상상력의 자물쇠를 푸는 코로나스러운 technology 였습니다. 저희들은 여러분과 여러분의 목표를 이루는데 장애가 되는 것들을 정리하고 뻥 뚤린 길을 내드리기 위해 부단히 노력해 오고 있습니다.

이쪽 분야의 전망이 아주 밝아 지면서 back-end service 와 통합 하는 것은 극히 중요한 일이 되고 있습니다. 즉 앱을 만드는데 있어서 필수적인 요소가 되가고 있죠. 앱 개발자가 흔히 직면하는 벽중의 하나가 이런 back-end 개발이 모바일 앱 개발에서는 특히 어렵다는 겁니다.



앱 개발을 하는 모든 분들에게 그것은 넘어야 할 큰 산입니다. leaderboard, social sharing, multiplayer 게임 같은 building basic 같은 것들을 앱에 적용하려면 아주 큰 난관에 부딪힐 수 있습니다. 특히 이것을 cross-platform basis 로 개발을 한다면요.


오늘 저는 Corona Labs 와 Game Minion 이 같이 힘을 합쳤다는 것을 발표하게 되서 너무 기쁩니다. 저희들은 Corona Cloud라는 서비스를 시작할 겁니다. 이 서비스는 Game Minion의 아주 훌륭한 서비스 조합들을 기반으로해서 만들어 질 겁니다. Corona Cloud 는 여러분의 모바일 앱에서 cloud service 들을 사용하는 것에 있어서 정말 큰 변화를 보여 줄 겁니다. 저희의 목표는 cloud 로 여러분 모바일 앱의 integrate 하는 기능을 괄목할 만하게 진전시키는데 있습니다. 다른 말로 표현하자면 native app 개발과 관련해서 우리가 했던 것과 같이 이 cloud 개발도 코로나 스럽게 서비스를 할 겁니다.



우리가 Game Minion 친구들과 처음 접촉했을 때 저희들이 처음 얘기한 것 중 하나가 우리 둘이 똑 같이 개발에 대한 정열이 많다는 공통점이었습니다. 저희들은 정말 개발자들의 생활을 좀 더 효율적이고 생산적으로 어떻게 만들 수 있을까에 대해 깊이 고민을 하고 있었습니다.

또 얘기를 한 것중에 Corona SDK 의 중단없는 발전과 integration 이었고 Corona Cloud 가 아주 간단하게 앱을 개발할 수 있는 환경을 줄거라는 것이었습니다.


올해 초 how ridiculously hard it is to build something 에 대해 얘기한 적이 있습니다. 그 글에서 얘기한 대로 저는 개발자는 예술가라고 생각합니다. 여러분은 어떤 아이디어를 실재화하기 위해 엄청난 열망을 가지고 있어야 합니다. 그것을 현실화 해 내기 위해 진지하게 접근을 하고 구현을 해 내야 합니다. 그리고 마침내 여러분의 창조물을 세계와 share 할 수 있을 때 비로서 여러분은 강한 만족감을 느끼실 수 있을 겁니다.


이것은 여기 계신 모든 분들의 심장 깊은 곳에서 본능적인 feeling 으로 이미 가지고 계실 겁니다. 우리들은 incredibly 열정적이고 hard-working 이고 driven bunch 입니다. 우리의 ambitions 가 점점 커가면서 우리의 팀도 커가고 있습니다. 지난 6개월 동안 우리 팀은 거의 두배가 됐습니다. 그리고 이젠 Game Minion 의 친구들까지 팀 멤버가 됐습니다.


우리를 이 길로 이끄는 것은 우리 안에 있는 예술적인 열정입니다. Corona SDK 는 계속 혁신해 나갈 겁니다. Corona Cloud 로 변화된 모습을 보여 드릴 것입니다. 그리고 여러분 안에 있는 아티스트적인 열정을 감히 저희가 불러 일으키고 싶다고 말씀 드립니다.


P.S. Corona Cloud 는 조만간 베타버전을 내 놓을 갑니다. Sign up here, 그러면 Corona Cloud 가 준비 되면 여러분께 연락 드리겠습니다.




반응형

간단하게 Device 분별하는 예제

2012. 12. 13. 06:40 | Posted by 솔웅


반응형
Posted on . Written by



지난주의 튜토리얼을 보셨나요? 보셨다면 Corona 가 다양한 디바이스의 스크린에 어떻게 각각 맞게 object들을 display 하는지 이해하셨을 겁니다. 저희는 이런 다양한 종류의 디바이스에 맞게 작업할 수 있도록 도와주기 위한 technology 를 사용하구 있구요. 또 각 디바이스에 맞는 폰트와 Kindle Fire soft button bar 같이 디바이스 별 특징 적인 부분들도 지원합니다.


Corona는 사용하는 device에 대한 정보를 얻을 수 있도록 하는 API 를 제공합니다. 이 API 를 call 함으로서 꽤많은 정보들을 얻고 그에 따라 어떤 작업을 할 수 있게 되죠. 개발자에게 가장 중요한 가이드 중 하나가 DRY (Don’t Repeat Yourself)죠. 코딩을 중복해서 하지 말라는 얘기 입니다. 아래 예제를 볼까요?


if ( system.getInfo("model") == "iPad" or

system.getInfo("model") == "iPhone" or

system.getInfo("model") == "iPod" ) then


store.init( "apple", transactionCallback )

store.restore()

else

-- IAP isn't yet supported on Amazon or Barnes and Noble so don't start it up.

if ( system.getInfo("model") ~= "Kindle Fire" or system.getInfo("model") ~= "Nook" ) then

store.init( "google", transactionCallback )

store.restore()

end
end

---------- OR ----------

local kindlePadding = 0

if ( system.getInfo("model") == "Kindle Fire" or system.getInfo("model") == "KFJWI" ) then

kindlePadding = 20

end

healthBar.y = healthBar.y - kindlePadding




만약 이 system.getInfo(“model”)을 온 동네에서 다 쓰고 다닌다면 엄청 양이 많은 코딩을 하게 될 겁니다. Amazon 하고 Barnes & Noble 이 새로운 device를 릴리즈 했는데. 그러면 model name들이 증가하겠죠. 현재까지 5개의 다른 Kindle Fire name 들이 있구요 Nook 은 4개가 있습니다.


이런 문제를 해결하기 위해 여러분은 if 문을 써서 간단한 external module 을 만드시면 됩니다.
그러면 위의 코드는 아래처럼 줄어들 수 있겠죠.


if ( device.is_iPad ) then
...
end
 
---------- OR ----------
 
if ( device.isKindleFire ) then
...
end



이렇게 함으로서 여러분은 키보드를 덜 누르고도 코딩을 하실 수 있습니다. 안드로이드 기반의 3가지 다른 플랫폼에 대해 일을 시작하기 전에, 일반 안드로이드 device인지 아니면 Nook이나 Kindle 같은 modified Android platform 인지 먼저 구별하는게 좋을 겁니다.




Assembling the Module


모듈을 하나 만들구요 이 모듈 이름을 device.lua 로 하겠습니다. 구버전에서 사용하던 “module(…, package.seeall)” method를 사용하지 않구요  new module method 를 사용할 겁니다. 아래 처럼 시작하시면 됩니다.




-- Create a table that will contain all of our tests we are setting up.
local M = {}
 
-- Set up some defaults...
M.isApple = false
M.isAndroid = false
M.isGoogle = false
M.isKindleFire = false
M.isNook = false
M.is_iPad = false
M.isTall = false
M.isSimulator = false




이 변수들을 가지고 작업을 하실건데요. 일단 디폴트로 모든 변수들에 false를 대입했습니다. 이제 model name 을 얻고 그것이 device 인지 Corona Simulator 인지를 먼저 구분한다음에 임시로 저장해 두죠.



local model = system.getInfo("model")
 
-- Are we on the Simulator?
if ( "simulator" == system.getInfo("environment") ) then
M.isSimulator = true
end


iPhone 5 가 나왔을 때 주요 이슈는 “tall” device 가 나왔다는 것이었습니다.  일단 이전의 아이폰은  16:9 HDTV shaped screen 이 아니었죠.  그러면 일단 이와 관련해서 16:9 Android devices 에 대한 정보도 같이 retrieve 해야 합니다.  여기서 먼저 전반적인 이해를 하고 넘어가야 할 부분은요. 7인치 tablet 들은 iPhone 4S와 iPhone 5 사이에 있는 디바이스 들입니다. 여기서 일단 우리는 iPhone 3 이나 4 보다 큰 것들을 먼저 추려 낼 겁니다.

320×480 devices 들은 1.5:1 (480/320=1.5) 의 비율을 가지고 있습니다. 그러니까 그것보다 크면 일단 "tall" device" 리스트에 넣겠습니다.



if ( (display.pixelHeight/display.pixelWidth) > 1.5 ) then
M.isTall = true
end
 
-- Now identify the Apple family of devices:
if ( string.sub( model, 1, 2 ) == "iP" ) then
-- We are an iOS device of some sort
M.isApple = true
 
if ( string.sub( model, 1, 4 ) == "iPad" ) then
M.is_iPad = true
end
 
else --...(the rest of the else is below)




그 다음으로는 애플 디바이스를 보겠는데요. 모든 Apple model 들은 iP로 시작합니다. ( iPod, iPad, or iPhone). 그러니까 모델 이름의 첫 두 글자를 보면 됩니다. 만약 iP로 시작하면 이것이 iOS 에서 구동 되는 것이라는 것을 알 수 있죠. 그러면 isApple flag 를 true로 할당합니다.


그리고 그 다음에는 그것이 iPad 인지 아닌지를 알아내야 합니다. 왜냐하면 iPad 와 다른 iOS device 들은 화면 모양에 대한 layout 이 다르게 작업해야 될 수 있거든요.

안드로이드는 저희의 삶을 도전적으로 만들었습니다. 왜냐하면 안드로이드 진영엔 3개의 marketplace 가 있거든요. (Google Play, Amazon, Barnes & Noble). 각각 저마다의 룰이 있어서 그것을 따라야 합니다. Barnes & Noble 같은 경우엔 “no ads” Amazon 같은 경우엔 “no links to Google Play”같은 것들이죠. Google Play 에 맞게만 작업할 수 없는 상황입니다. 그러니까 일단 Google Play 말고 다른 것들을 구별하죠.


위에 언급했듯이 Kindle 과 Nook device 들에는 다양한 모델들이 있습니다. 아래 코드를 계속 보죠.


else
-- Not Apple, so it must be one of the Android devices
M.isAndroid = true
 
-- Let's assume we are on Google Play for the moment
M.isGoogle = true
 
-- All of the Kindles start with "K", although Corona builds before #976 returned
-- "WFJWI" instead of "KFJWI" (this is now fixed, and our clause handles it regardless)
if ( model == "Kindle Fire" or model == "WFJWI" or string.sub( model, 1, 2 ) == "KF" ) then
M.isKindleFire = true
M.isGoogle = false --revert Google Play to false
end
 
-- Are we on a Nook?
if ( string.sub( model, 1 ,4 ) == "Nook") or string.sub( model, 1, 4 ) == "BNRV" ) then
M.isNook = true
M.isGoogle = false --revert Google Play to false
end
 
end


코드를 한번 볼까요? 첫번째 if part 에서는 애플 (Apple) device 일 경우 로직을 만들었습니다. 그러니까 else문 에서는 안드로이드 기기와 관련된 로직을 만들어야 겠죠. 그래서 일단 isGoogle flag를 true로 만들어 놓고 시작했습니다.


그 다음으로는 두 파트에 걸쳐서 나머지 두 marketplace 에 대해 걸러 내겠습니다. 첫번쨰로 Kindle Fire일 경우를 보죠. 이 경우 모델 이름은  KFWFJWI로 시작합니다. 아마존이 4개의 새 Kindle Fire 모델을 릴리즈 했을 때 그 모델 이름들은 KFJWI라고 지었습니다. 처음 Kindle Fire의 모델명은 Kindle Fire였구요. 제 2세대에서는 KFOT로 지었구요. 7인치 HD 모델은 KFTT입니다. 그리고 9인치 모델은 KFJWIKFJWA이구요. (WiFi를 지원하느냐 3G -WAn- 을 지원하느냐에 따라 다릅니다.) 다행스럽게도 모든 모델들에 공통적인 것은 KF or Kindle Fire 입니다.

K로 하면 어떨까 생각 드시나요? 그래도 됩니다. 하지만 안드로이드 디바이스의 수는 질리도록 많습니다. K로만 하면 예외 상황이 발생할 확률이 아주 높습니다.

이제 디바이스가 Kindle Fire 로 확인 되면 isGooglefalse 로 하고  isKindleFire 는  true로 세팅합니다.


이제 Nook 를 체크할 차례죠. 마지막 입니다. 대부분 Barnes & Noble 은 모델 이름이 BRNV 로 시작 됩니다. Nook Color 는 Nook Color를 사용합니다.


여기까지 했으면 다음에 할 일은 앱에 이 정보를 return 하는 것입니다.


-- Return the table "M", providing access to it from where the module is "require"d
return M


Putting it to Work


이것을 앱에서 사용하시려면 프로젝트 시작부분에서 간단하게 그 모듈을 require 하시면 됩니다.


local device = require("device")


그러면 이제 여러분이 필요할 때마다 그것을 불러 와서 사용하시면 됩니다.


if ( device.isApple ) then
store.init( "apple", transactionCallback )
store.restore()
 
elseif ( device.isGoogle ) then
store.init( "google", transactionCallback )
store.restore()
 
end


이렇게 하면 디바이스 체크하는 부분의 코딩이 훨씬 잘 정리가 될 겁니다. 그러면 여러 OS와 여러 Device 에서 구별되서 돌아가도록 앱을 개발할 때 아주 용이하게 사용하실 수 있겠죠. 더군다나 이 device detection 을 external module 로 만들어 놔서 새로운 디바이스가 나왔을 떄 거기에 맞게 수정 작업하는 것도 훨씬 쉬워질 겁니다.

완성된 소스는 아래에 있습니다.



device.lua

이 모듈을 이전 시간에 다뤘던 Ultimate config.lua 와 함께 사용하세요.

현재 market 에 나와있는 모든 디바이스에 맞게 여러분의 앱을 개발하고 빌드할 수 있을겁니다.

그리고 앞으로 새로운 디바이스가 나와도 쉽게 작업을 하실 수가 있을 겁니다.

반응형


반응형


반응형


반응형
Posted on . Written by


훌륭한 앱도 하나의 아이디어에서 시작합니다. 하지만 어떻게 여러분의 아이디어를 모바일에서 시련할까요?

오늘 저희들은 Corona SDK Tech Tutorials Center를 여러분에게 소개합니다. 바로 오늘 문을 열었습니다. 여러분의 모든 테크니컬한 요구들을 가서 찾아볼 수 있습니다. “partner in crime”, “Robin to your Batman” , 찐빵의 앙꼬?? 하옇든 뭐든 아이디어를 얻으세요.

이 Tech Tutorial Center 는 guide들의 collection 입니다. 샘플 프로젝트, 팁, trick, 그리고 코로나와 관련된 광범위한 자료들이 다 모여 있습니다.

코로나의 신참이든 경력이 많든 여러분은 검증된 앱 개발 방법과 전략 그리고 가장 자주 질문되는 것들을 통해 해답을 찾는데 시간을 절감할 수 있는 방법들을 찾을 수 있을겁니다. 

뭔가 새로운것을 배우기 원하시든지 아니면 그냥 여러분의 coding skill을 발전시키기 원하시면 이곳을 활용하세요.





질문이나 제안 등이 있으시다면 혹은 리스트에 추가할 새로운 tutorial 이 있으시면 tutorials@coronalabs.com.로 연락을 주세요.




반응형


반응형
Posted on . Written by


Corona 의 철학과 어떤 일에 대한 우리의 접근법은 오랫동안 숨낳은 경험을 통해 얻게 된 정수입니다. Adobe 에서의 제 경험은 그 중 아주 큰 부분입니다. Adobe 가 게임에서 TOP 을 점유하고 있을 때, 저는 기억합니다 그 회사의 founder들에 대한 두가지 중요한 사항들을...


첫번째는 그들은 그들의 product 를 위해 헌신했습니다. 한번은 Chuck Geshke 와 그의 board member 인 Robert Sedgewick (예 바로 그 Algorithms 책들의 저자이죠) 가 왔고 우리팀과 같이 점심을 먹었습니다. Chuck 는 제 바로 오른쪽에 앉았고 그가 처음 한 일은 저에게 Illustrator 의 어떤 printer bug 에 대해 물어본 것이었습니다. 그의 공동 창업자 John Warnock 도 회사를 걷다가 아무데나 앉아서 engineer 랑 shop 에 대해 얘기하는 그런 스타일의 사람으로 유명했습니다.



두번째로는 다른 팀원과의 원할한 관계를 강조했습니다. 재능있는 인재는 다른 재능있는 인재와 일하길 원합니다. Chuck 이 자주 말하는 것 중 하나가 성공하는 가장 확실한 방법은 너 자신을 변화시키는 것이다 라는 것이었습니다. 그 의미는 뭐냐하면 다음 단계의 일을 시작하기 전에 먼저 자신부터 확실하게 기반을 다지라는 것이었습니다. 그리고 자신이 거기에 대해 이뤄 놓은 것보다 더 낳은 일을 하기 위해 그 기반을 잘 이어나갈 right person 이라는 것을 찾아야 한다고 얘기합니다. 그리고 더불어서 네가 믿을 만한 사람을 찾으라는 겁니다.



오늘 Corona engineering을 이끌어 나갈 사람을 찾았다는 얘기를 하게 되서 기쁘게 생각합니다. Perry Clarke 이 VP of Engineering 으로 우리와 한 가족이 됐습니다. Perry 는 12년간 신생기업과 큰 기업 모두에서 engineering 과 management 로 일한 경력이 있습니다. cloud 에서 desktop software 까지 그리고 Yahoo에서 Sun 까지요.





Perry 와 저는 최근 재회를 했습니다. 그가 정식으로 인터뷰를 시작하기 전에 이미 저에게 깊은 감명을 준 것은, 우리가 어떤 일을 했는지 정말로 알기 위해서 그 자신이 해킹한 코로나 앱이 있는 아이폰을 저에게 보여준 것입니다. 말할 필요도 없이 그는 그 코드를 분석하는 수고로움에 대한 두려움도 없었고 product 에 대한 강한 정열이 있었습니다.


여기 정말 흥미로운 일화가 있습니다. 10년 전에 Perry 는 Konfabulator 를 공동으로 만들었습니다. Konfabulator 은 애플의 Mac OS X의 Dashboard widget 에서 영감을 받아 데스크탑용 으로 만든 rapid aplication development platform 으로 아주 유명한 widget 이죠. 이 프로그램은 데스크 탑 애플리케이션을 정말로 쉽게 만들 수 있도록 하자는 아이디어에서 시작했습니다. 그들의 technology 위에서 수많은 indie developer 들이 앱을 만들었고 또 community 에서 활발하게 활동들을 하도록 만들었죠.




이 얘기를 듣고 뭔가 생각나지 않으세요? Wink, wink, nudge, nudge. ;-)

Perry 가 우리 Corona engineering 팀에 같이 하게 되서 저는 너무너무 기쁩니다. 그로 인해 앞으로도 간단없는 개선이 이뤄져 나가길 기대합니다. 우리 둘은 같은 철학을 가지고 있습니다. 

it’s all about setting a higher standard

저에게는 많은 계획들이 있습니다. 제안에 끓고 있는 engineer 의 피가 뭔가 더 코딩하지 않으면 못견디게 만들거든요.

Is the team really ready for more code checkins coming from yours truly? :-)



반응형


반응형
Posted on . Written by


수요일 FAQ 시간이죠. 이제 코로나에서도 안드로이드 기기의 Local Notification 을 지원하게 됐죠. 오늘은 이와 관련돼서 자주 문의 되는 질문을 다루겠습니다.


1. How do I detect that a local notification occurred.


Local notification 를 감지하는 방법에는 두가지가 있습니다. 예를 들어 앱이 running 혹은  suspended 이고 유저가 notification을 tap 했다면 여러분 앱의 notification listener 가 fire 될 겁니다. 만약 앱이 exited (applicationExit) 상태이고 notification이 fire 된다면 notification 이 앱을 open 하고 launchArgs.notification parameter 를 set 할 겁니다. 여러분은 코드 내에서 그 notification parameter 를 set 하시고 notification 리스너를 call 하셔야 합니다. (왜냐하면 앱이 시작할 때 이것을 자동으로 call 하지 않거든요.)


local launchArgs = ...      -- at the top of your program code

local function notificationListener( event )
    -- Handle Local Notification here
end


여러분 앱이 유저가 notification event를 touching 해서 앱이 시작했는지 여부를 알아낼 수 있는 코드가 아래에 있습니다.


 if launchArgs and launchArgs.notification then
     -- Need to call the notification listener since it won’t get called if the
     --the app was already closed.
     notificationListener( launchArgs.notification )
 end


notification listener 에서 event.applicationState는 유저에 의해 norification 이 involve 됐을 경우 앱의 상태를 나타냅니다. “active”는 앱이 running 될 때 notification 이 fire 된 것을 의미합니다. 그리고 “inactive”는 notification 이 앱이 suspended 혹은 closed 됐을 때 fire 됐음을 의미합니다.





2. How do I detect that a user ignored a local notification?


답은 그렇게 할 수 없다 입니다. 만약 유저가 notification을 delete (or ignores) 했다면 notification listener 는 call 이 되지 않을 겁니다. 그리고 여러분의 앱은 그게 fire 되지 않으니까 그게 ignored 됐는지도 알 수 없습니다. (여러분 앱은 계속 notification schedule 을 track 할 겁니다. 그리고 notification 이 fire 되면 그 때 알겁니다.)


3. What are the differences between local notifications in iOS and Android?


iOS와 Android 의 가장 큰 다른 점은 “badge.” 입니다. 그건 iOS device 에서 앱 아이콘에 표시되는 숫자인데요 notification 이 fire 되면 표시됩니다. 일지 않은 메세지의 갯수를 표시하게 되죠. 그 값과 의미는 앱에 의해 정의됩니다. 안드로이드는 이 badge number 를 이용하지 않습니다.


4. How do I update the badge number in iOS?


badge number 는 notification 이 fire 됐을 때 세팅됩니다. 혹은 아래 코드를 사용해서 update 할 수도 있는데요. 이 코드는 현재의 badge 값을 읽어서 숫자를 증가시키는 겁니다.


local badge = native.getProperty( "applicationIconBadgeNumber" )
badge = badge + 1
native.setProperty( "applicationIconBadgeNumber", badge )



이렇게 함으로서 notification이 fire 됐을 때 badge number를 무엇으로 할 건지 정할 수 있습니다. 일반적으로 각 notification 에 대해 badge number 를 increment 하죠. 이 badge number 를 clear 하시려면 native.setProperty 를 call 해서 badge 값을 0으로 하시면 됩니다.


5. Is there any examples using Local Notifications?


최근에 릴리즈된 CoronaSDK (build 971) 에 Local Notification 에 대한 sample 앱이 있습니다. 이 샘플은 이 local notification을 사용할 때 활용할 수 있는 많은 기능들이 있습니다.


오늘은 여기까지 입니다. 유익한 시간 되었길 바랍니다.



반응형


반응형
Posted on . Written by


오늘의 튜토리얼은 Corona Labs Developer Relations team의 Rob Miracle 님이 제공해주셨습니다. Rob은 18개월간 코로나 개발자로 활동하였고 10개가 넘는 앱을 릴리즈 했습니다.



모바일 앱을 개발할 때 가장 많이 떠오르는 생각 중 하나가 "어떻게 이 다양한 디바이스들을 모두 다 지원할 수 있을까?" 입니다. iOS 쪽만 하더라도 3가지 종류의 기기들이 있고 또 거기에다가 다양한 해상도가 있습니다. 여기다가 안드로이드까지 더하면 미치기 일보 직전까지 가죠.



어떤 화면은 넓고 어떤 화면은 좁고 그렇습니다. 그걸 제대로 디바이스에 맞게 하려면 일일이 맞춰줘야 하는데요. 코로나는 Dynamic Scaling라는것을 사용해서 그 작업을 쉽게 도와드립니다. 이 Dynamic Scaling로 각각의 스크린에 따라 세팅을 하시면 코로나가 자동으로 각각의 해상도 화면에 맞게 텍스트와 그래픽을 맞춰 드립니다. 여러분이 설정한 기준에 따라 upward 할 수도 있고 downward 할 수도 있습니다. 그리고 scale up을 하기 위해 필요할 떄는 substitute higher resolution images도 할 수 있습니다. 이것은 여러분의 프로젝트 폴더 안에 있는 config.lua라는 Lua 파일로 구현할 수 있습니다.



고민해야 하는 해상도가 아주 많습니다. 각 디바이스에 대해 같은 scale 을 사용하면 편하겠죠.  320×480의 아이폰 3GS 에 있던지 1536×2048의 Retina iPad 에 있던지 (0,0)이라는 위치는 top-left corner  입니다. 그리고 (320,480) 는vertical portrait mode 에서는 bottom-right corner이죠. 화면의 중심은 (160,240)입니다. 3GS 같이 낮은 해상도 기기 - native 화면 해상도가 320×480- 에서 각 point는 한 픽셀을 말합니다. 그리고 Retina iPad 같은 경우엔 각 point는  4픽셀 입니다. 이걸 일일이 계산할 생각은 하실 필요 없습니다. 코로나가 다 계산해 드릴겁니다.





Basic Screen Shapes


너비와 높이가 360×570인 이미지가 있다고 가정해 봅시다. 우리는 실제 화면보다 더 큰 배경이미지를 만들겁니다. 왜냐구요?  그 이미지를 여러 디바이스에서 다 사용할 거거든요. 안쪽 사각셩( inner rectangle)은 320×480 block 입니다. 아마 이미지의 맨 가장자리 부분은 화면 밖으로 나갈 겁니다. 이것을 iPhone 5 나 대부분의 안드로이드 폰 같은 tall device 에서는 이 이미지의 full height를  이용할 겁니다. 그 경우에도 왼쪽과 오른쪽 가장자리는 화면 밖으로 나가게 될 겁니다. 여러분이 좀 더 정사각형에 가까운 iPad 를 가지고 있다면 그 이미지는 위와 아래쪽 가장자리가 잘리고 왼쪽과 오른쪽은 모두 다(full width) 보일 겁니다. 이렇게 밖으로 나가는 부분은 “bleed area” 라고 합니다. 일반 인쇄를 할 때 종이 여백에 잉크가 번질 수도 있는 그런 여분의 공간을 말할 때 그 말을 사용합니다.



이제 어떻게 background 가 사용되는지 이해하고 직접 볼 수 있습니다. 바로 config.lua file 에 셋업하시면 됩니다. 이 파일은 standard Corona Lua file 이기 때문에 아래 사항을 구현하기 위해 몇가지 API 를 사용할 수 있습니다.


  • read the pixel width/height of the device. 디바이스 너비 높이 얻기
  • use math for various calculations. 다양한 계산을 위해 math 사용하기
  • read the device model number. 디바이스 모델 번호 얻기
  • perform string manipulations. string manipulation 사용하기
  • use conditional “if-then-else” logic. if 문 사용하기


iPad Configuration


우리가 할 첫번째 작업은 앱이 실행되는 기기가 아이패드일 경우에 대한 코딩입니다. 아래 Corona API 로 모델 number 를 얻을 수 있습니다.


system.getInfo("model")



실제 지금 아이패드에서 실행하면 string iPad를 결과 값으로 얻으실 겁니다. 그런데 아마 애플은 조만간 이것을 바꿀 수도 있습니다.  iPad Retina 뭐 이런걸로요. 그러니까 if 문을 사용해서 이런 경우에도 대비를 해 두는게 낫겠죠.


if ( string.sub( system.getInfo("model"), 1, 4 ) == "iPad" ) then
   application =
   {
      content =
      {
         width = 360,
         height = 480,
         scale = "letterBox",
         xAlign = "center",
         yAlign = "center",
         imageSuffix =
         {
            ["@2x"] = 1.5,
            ["@4x"] = 3.0,
         },
      },
   }


코로나는 루아의 string.sub() 함수를 사용합니다. 디바이스 모델을 읽은 뒤 앞의 4글자만 취하게 되죠. 그러니까 애플이 iPad 뒤에 무엇을 넣던지 이 로직에서는 상관이 없겠죠. 이 경우 얻은 글자가 iPad이면 content table을 작성할 건데요. width and height parameters 들은 각각 360 and 480 으로 합니다. 여기서 너비를 360으로 하는 이유는 우리가 사용하는 샘플 이미지의 너비가 360 픽셀이기 때문입니다. 우리는 이 이미지를 아이패드 스크린에 맞게 이미지를 늘릴겁니다. 코로나는 기본으로 portrait 을 사용합니다. 만약 여러분 앱이 landscape 모드를 사용한다면 그 이미지를 portrait orientation 을 가정해서 거기에 맞게 너비와 높이를 정해야 합니다. 그러면 코로나가 자동으로 알아서 기기를 세웠을 때와 뉘었을 때에 맞게 알아서 이미지를 돌려 줍니다.



너비가 360 이니까 이제 높이를 계산해야죠. 이 높이도 iPad 의 화면에 딱 맞게 해야 합니다. iPad 스크린은 768X1024 입니다. 그리고 Retina iPad 인 경우는 1536X2048 이죠. (정확히 두배입니다. 그러니까 그 비율은 정확히 같은 겁니다.) 우선 첫번쨰로 1024를 768로 나눕니다. 그 결과는 1.33 이 됩니다. 그리고 높이를 얻기 위해 360X1.33을 합니다. 그러면 480이 되겠죠.



1024 / 768 = 1.33  --screen ratio (height:width)
1.33 x 360 = 480


iPhone5 Configuration


elseif
( string.sub( system.getInfo("model"), 1, 2 ) ==
"iP" and display.pixelHeight > 960 ) then
   application =
   {
      content =
      {
         width = 320,
         height = 568,
         scale = "letterBox",
         xAlign = "center",
         yAlign = "center",
         imageSuffix =
         {
            ["@2x"] = 1.5,
            ["@4x"] = 3.0,
         },
      },
   }


아이폰의 경우는 모델 string 에서 첫 두글자만 취하겠습니다. iPad 하고 iPod Touch 둘 다 iP 로 시작하는데 왜 그렇게 하냐구요? 그래서 이것 말고 디바이스의 pixelHeight 를 구할 거거든요. (이 pixelHeight 프로퍼티는 Corona build #971 에서부터 지원했습니다. 그러니까 그 아래 버전을 사용하시는 분은 그 상위 버전을 download 하세요.)  만약 그 pixel heignt 가 960 보다 크다면 그 디바이스는 iPhone 5 가 되는 겁니다. (아니면 iPod Touch 최신버전이던가요.)  그 디바이스의 해상도는 640 X 1136 이니까 이것을 320 pixel로 그 비율을 맞춘다면 320×568 이 됩니다.

그래서 너비와 높이늘 320×568 로 해 주시면 됩니다.


위 계산대로 하면 배경 이미지의 높이가 iPhone 5 의 높이에 딱 맞게 표시 될 겁니다. iPhone 5의 실제 해성도는 640X1136 이구요 우리 이미지의 안쪽 사각형 (inner rectangle" 이 너비가 320 이니까 이걸 가지고 아래처럼 간단히 계산하면 그 비율에 맞는 높이를 구할 수 있습니다.



320 / 640 = 0.5  --inner rectangle width / device pixel width = factor
1136 × 0.5 = 568  --device pixel height × factor = config.lua 'height' setting



우리가 가지고 있는 샘플 배경 이미지의 높이는 570 입니다. 그러니까 iPhone 5 화면에서는 위와 아래쪽에 각각 1pixel 씩 화면 밖으로 나갈 겁니다.


iPhone 3,4 and Older iPod Touch



elseif
( string.sub( system.getInfo("model"), 1, 2 ) == "iP" ) then
   application =
   {
      content =
      {
         width = 320,
         height = 480,
         scale = "letterBox",
         xAlign = "center",
         yAlign = "center",
         imageSuffix =
         {
            ["@2x"] = 1.5,
            ["@4x"] = 3.0,
         },
      },
   }


위쪽에서 이미 iPhone 5 를 사용했으니까 다음 else if 문에서 모델이 iP 로 시작하는 스트링을 얻는다면 그것은 이전 버전의 iPhone 이나 iPod Touch 가 될 겁니다. 해상도는 320X480 과 640X960 이렇게 두 종류가 있죠. 이 경우에는 우리가 가지고 있는 이미지의 inner rectangle 인 320X480 을 사용할 수 있습니다.



Android, Kindle Fire, and Nook


마지막으로 우리는 16:9 인 안드로이드 디바이스와 5:3 인 NOOK 과 Kindle Fire 디바이스를 따로 작성해야 합니다. 16:9 device 들은 그 비율이 1.777:1 이 됩니다. Nook 과 Kindle Fire 는 1024X600 에 가깝구요 그 비율은 1.7:1 이 됩니다. 그러니까 이 경우 화면 크기 비율을 계산하기 위해 pixelHeight and pixelWidth를 사용할 수 있겠죠. 만약 그것이 1.72 보다 크면 iPhone 5 와 비슷한 16:9 로 계산하면 될 겁니다.  만약 그렇지 않으면 그 기기에 맞도록 너비와 높이를 세팅해야 겠죠.


elseif ( display.pixelHeight / display.pixelWidth > 1.72 ) then
   application =
   {
      content =
      {
         width = 320,
         height = 570,
         scale = "letterBox",
         xAlign = "center",
         yAlign = "center",
         imageSuffix =
         {
            ["@2x"] = 1.5,
            ["@4x"] = 3.0,
         },
      },
   }

else
   application =
   {
      content =
      {
         width = 320,
         height = 512,
         scale = "letterBox",
         xAlign = "center",
         yAlign = "center",
         imageSuffix =
         {
            ["@2x"] = 1.5,
            ["@4x"] = 3.0,
         },
      },
   }

end



Important Notes


여기에 완성된 파일이 있습니다. 이 파일만 사용하시면 현재까지 나온 대부분의 디바이스들이 cover 될 겁니다. 아래 사항들을 기억해 두세요.


  • On some devices parts of the background will be off screen, so don’t put anything “critical” in the bleed areas.
  • Objects positioned using fixed numbers like player.x = 64 and player.y = 64 will always be 64 points away from the top and left edges, but based on the device will be closer or further away from center.  Likewise, objects placed using the right and bottom edges will stay the prescribed distance away from those edges (player.x = display.contentWidth-64 will stay 64 points away from the right edge) but they will move closer or further from the center too. Objects positioned based on a center coordinate (player.x = display.contentCenterX+100) will stay in the same relative position regardless of the screen shape.


Dynamic Image Selection


각 configuration block 에는 아래와 같이 imageSuffix table 이 있습니다.


imageSuffix =
{
   ["@2x"] = 1.5,
   ["@4x"] = 3.0,
},


만약 코로나를 처음 접해 보신다면 이 방법이 바로 코로나 SDK 가 Dynamic Image Selection을 지원하는 부분이라는 점을 알고 계시면 됩니다. 예를 들어 여러분이 Retina iPad 와 iPhone 3GS 에 같은 이미지를 사용하지 않고 해상도를 충분히 지원해 주는 그런 이미지를 별도로 사용하고 싶으실 수 있을 겁니다. 그러면 이 image sets 를 일반 디바이스와 Retina/HD 디바이스에 맺게 각각 다르게 세팅하시면 그 디바이스 해상도에 맞게 작업하신 이미지를 자동으로 바꿔서 display 할 수 있습니다.



imageSuffix table 은 두개의 부분으로 구성돼 있습니다.



["@2x"] =        --append this suffix to all images designed for those device(s)
(decimal value)  --scale factor that Corona uses to pick the proper assets



첫번째 값은 여러분이 이름을 정해 주시면 됩니다. 두번째 값은 아래 공식에 의해 계산된 값입니다.


device width / config.lua 'width' = scale factor



만약 특정 디바이스의 scale factor가 이 숫자보다 크다면 코로나는 그 asset 을 사용할 겁니다.

아래와 같이 세팅하시면 될 겁니다.



["@2x"] = 2.0
["@4x"] = 4.0



저희들이 계산한 아래 예제들을 참조하세요.




600 / 320 = 1.875  --Kindle Fire & Nook 640 / 320 = 2.0   --iPhone 5 768 / 360 = 2.13   --iPad 800 / 320 = 2.5   --Kindle Fire HD / Nexus7 1200 / 320 = 3.75  --Kindle Fire HD 8.9 1536 / 360 = 4.26   --Retina iPad



만약 여러분이 4.0 으로 세팅했다면 이것은 Retina iPad 에만 적용 되고 Kindle Fire HD 8.9 이하에는 적용되지 않을 겁니다. 즉 Retina iPad 전용 이미지가 되는 것이죠.

그런데 대개 Kindle Fire HD 8.9 와 Retina iPad 에는 같은 이미지를 사용해도 문제가 없습니다.

그래서 다운 받은 configuration file 에는 아래와 같이 세팅 돼 있을 겁니다.



["@2x"] = 1.5,
["@4x"] = 3.0,



이렇게 하면 해당 “@4x” image 는 Retina iPad, Kindle Fire HD 8.9, and the Nexus 10 같은 고 해상도 디바이스용 이미지를 별도로 사용할 때 유용할 수 있습니다. 그 이외의 디바이스들은 “@2x” images 를 사용할 겁니다.


끝으로 중요한 것 한가지 더 언급해 드린다면 배경을 display 하기 위해 display.newImageRect() 를 사용하시라는 겁니다.



local
background = display.newImageRect( "background.png", 360, 570 )


끝의 두 숫자 360과 570 은 1X 에 근거한 이미지의 너비와 높이 입니다. 샘플 파일에서는 lowest resolution target device 가 original Kindle Fire 와 NOOK Color 로 돼 있습니다. 이 디바이스들과 “@2x” bracket 에 속하는 다른 디바이스들은 코로나에서 720X1140 을 사용할 거고 “@4x” version 에서는 1440X2280 을 사용할 겁니다. 이런 작업들은 코로나가 알아서 할 거니까 별로 크게 신경 안 쓰셔도 됩니다.


In Summary…


이 튜토리얼은 약간 detail 한 부분까지 설명 했습니다. 코로나를 처음 접해 보시는 분들에게는 좀 더 간단히 설명해 드릴 필요가 있을 텐데요. 위에 저희가 샘플 파일을 다운로두 받을 수 있도록 했으니 그 config.lua file 을 받으셔서 잘 분석해 보시고 또 실제로 적용해 보시면 이해하시는데 도움이 되실 겁니다.  아직 다운 받지 않으신 분들을 위해서 여기 다운 받으실 링크를 다시 알려 드릴께요.



반응형

'Corona SDK > Corona Doc' 카테고리의 다른 글

Multi-Element Physics Body 다루기  (0) 2013.01.11
내 앱에 애플의 iAds 광고 달기  (0) 2013.01.03
코로나의 Holiday Gifts : Android Push Notification 등 등  (0) 2012.12.30
iOS 에 구글 맵이 돌아왔다. (Corona의 구글 맵 지원 기능 소개)  (2) 2012.12.19
간단하게 Device 분별하는 예제  (0) 2012.12.13
physics engine (물리엔진)의 새로운 기능 event.contact 소개  (0) 2012.11.29
새 위젯 사용하기 Part 1  (0) 2012.11.08
Blend Modes 사용해서 Creative Effects 내기  (1) 2012.11.01
원근감을 주는 parallax scrolling 구현하기  (0) 2012.10.18
Sprite 로 애니메이션 표현하기와 그 methods 들  (0) 2012.10.11


반응형

Posted on

. Written by


여러분들 중 특히 캘리포니아에 사시는 분들은 앱 privacy policies 과 관련해 요구되는 것에 대한 recent news story에 대해 들어보신 적이 있으실 겁니다. 만약 들어보시지 못하셨다면 잘 들여다 보셔야 합니다.


여러분이 어디에 계시든 여러분들은 이 privacy policy 에 입각해서 어떤 정보들을 수집하는지 그걸로 무엇을 할지에 대해 설명해야 합니다. 


다시 한번 강조드리는데 여러분들도 이와 관련해서 유념하셔야 하셔야 되구요. 그와 관련된 정보를 Corona Labs 에서 얻으실 수 있습니다. 저희들은 몇달전에 “Privacy Policy for App Users” 를 업로드 했습니다. 이 문서는 여러분과 여러분 앱의 유저들에게 우리들이 어떤 정보들을 capture 하는지에 대해 알려드리기 위한 겁니다.



만약 여러분이 여러분 앱에 이 privacy policy 를 넣으시기로 하셨다면 이 문서를 기반으로 여러분에 맞게 약간만 변형해서 사용하실 수 있을 겁니다. 


끝으로 이와 관련한 캘리포니아에서 요구하는 것은 아직 확실하지는 않습니다.  그리고 이 privacy policy 의 형식과 정보에 대해서도 확실하게 나온것은 없습니다. 그냥 저희들이 만든것을 여러분에게 guideline으로 제공하니 활용하시기 바랍니다. 질문이 있으시면 언제든지 물어보세요. 단 저희들은 변호사가 아니라서 법적인 조언까지는 못해드립니다.:)



감사합니다.






반응형


반응형

Posted on . Written by


오늘의 튜토리얼은 코로나의 physics contact에 대해 소개해 드리려고 합니다. 이 기능은 physics engine 에 최근에 implement 됐습니다. 개략적으로 말하자면 physics contact 는 막 일어나려는 특정 collision (충돌) 을 말하는 겁니다.

개발자들에겐 아마도 physics pre-collision이 친숙할텐데요. 아마도 이 physics contact 하고 뭐가 다른지 의문이 드실 겁니다. physics contact 는 대부분의 경우 pre-collision event 중에 사용됩니다. 그럼에도 이 두가지는 중요한 차이점이 있습니다.



Pre-collision Event


두 object 사이의 pre-collision (or any collision) 이 일어날 경우 Corona는 Lua ID에 의해 각각의 object 에 접근할 수 있도록 합니다. 이 방법을 통해 어떤 object (객체) 에 어떤 action 을 구현할 수 있을 겁니다. 예를 들어 dl pre-collision에서 한 object 를 센서로 바꿔서 다른 object 가 이 object를 통과할 수 있도록 만들 수도 있구요 아니면 둘 중 하나는 터지도록 만들 수도 있을 겁니다.  또는 여기에 force를 더 줄 수도 있고 혹은 다른 많은 action 들을 부여할 수 있습니다. 이 기능은 Corona 에서 오래 전부터 제공해 왔죠. 그런데 여기에는 몇가지 제한이 있었습니다. 그리고 physics contact로 그 제한을 해결할 수 있게 됐습니다.



One-Sided Platforms


2D side-view games 에서 자주 요구되어지는 것 중 하나가 “one-sided platform” 입니다. (수퍼 마리오를 비롯해 다른 수 많은 2D platform games 에서 이 기능이 사용되고 있습니다.) character 가 platform 아래에서 점프를 할 수 있고 이 platform 을 통과 할 수도 있죠. 그리고 그 platform 위에 사뿐히 착지하게 됩니다. 코로나에서는 이전에 점프할 때 character를 sensor 로 바꿔서 해결했습니다. 그리고 그 platform 위에서 character 는 다시 일반적인 object로 전환 됐죠.

대부분의 경우 이 방법으로 해결이 가능했습니다. 그런데 한가지 중요한 문제점이 있었죠. 만약에 enemy “goomba” 가 platform 위에서 걸어가고 있는 경우에는 어떻게 될까요? 이 character 가 그 enemy “goomba” 하고 부딪힐 때도 여전히 sensor 인 상태가 되죠. 그러다가 platform 위로 올라가게 되는 순간 두 object 의 충돌이 인식되서 “bounce” 가 일어나지 않는 등의 문제가 생길 수 있습니다.






Introducing the Physics Contact


위 문제는 새로 도입된 physics contact로 해결 할 수 있습니다. 위에서 언급한대로 특정 reference 에 대해 막 일어나려고 하는 충돌의 경우 알 수가 있습니다. pre-collision event listener 가 사용되고 있는 사이에 physics contact 와 4개의 properties에 접근할 수 있습니다. 이전에는 ㅇ접근할 수 없었던 것이죠.

one-sided platform 예제를 한번 더 생각해 볼까요. character 가 점프하고 아래쪽에서 platform 에 충돌 했을 때 코로나는 character 의 머리와 platform의 밑부분이 충돌하려고 한다는 것을 알 수가 있습니다. physics contact를 사용해서 곧 일어날 temporary access를 알아채서 코로나에게 여러분이 하고 싶은 일을 하라고 얘기할 수 있습니다. 혹은 이것을 완전히 무시하라고 얘기할 수도 있죠.


아래에 pre-collision event listener를 사용해서 어떻게 physics contact에 어떻게 접근하는지에 대한 예제가 있습니다.


function character:preCollision( event )
   print( event.contact ) --"event.contact" is the physics contact "userdata"
   --the following properties of the collision can be accessed; the last three are settable!
   print( event.contact.isTouching ) --read-only: are the two objects touching?
   print( event.contact.isEnabled ) --'true' or 'false'; will the collision resolve?
   print( event.contact.bounce ) --get/set the bounce factor of the collision
   print( event.contact.friction ) --get/set the friction factor of the collision

end
character:addEventListener( "preCollision" )


physics contact 는 collision-specific properties 를 제공합니다. (이전에 traditional listener events 에서는 접근할 수 없었던 것들이죠.)  간단한 condition 로직을 사용하셔서 (if문 같은) 해당 충돌을 완전 무시하거나 선택할 수 있습니다. 혹은 특정 충돌에 대해 bounce/friction factor(s)등에 변화를 줄 수 있죠. 해당 객체에 적용한 bounce/friction  을 override 하시면 됩니다.


one-sided platform 을 위해서는 physics contact 메소드를 사용하는 것이 훨씬 좋습니다. 처음에 플랫폼의 프로퍼티를 “pass through” (or any other term)로 설정하고 그 다음에 conditional logic (if 문 같은)을 사용해서 코로나에게 만약 그 플랫폼이 “passthru” type 이면 해당 충돌을 무시하라고 얘기하실 수 있습니다. 아래 예제에서 처럼요.


local platform = display.newImage( "platform.png" )
platform.collType = "passthru"
physics.addBody( platform, "static", { bounce=0.0, friction=0.3 } )

function character:preCollision( event )

   local collideObject = event.other
   if ( collideObject.collType == "passthru" ) then
      event.contact.isEnabled = false --disable this specific collision!
   end
end

 

physics contact 충돌하는 두 객체의 reference 는 아닙니다. 다만 충돌 그 자체의 reference 입니다.그 충돌을 다시 적용시키기 위해 override 하실 수 있습니다. physics contact properties 를 세팅하면 두 객체 모두에 이 프로퍼티가 계속 적용되는 것이 아닙니다. 코로나는 그 특정 충돌에 대해서만 해당 프로퍼티를 사용할 겁니다.  그리고 나서는 그 프로퍼티를 무시합니다. 예를 들어 physics contact 의 “bounce” factor 를 바꾼다면 두 객체의 core bounce 에 대해서는 set/reset을 하지 않습니다.


코로나에서 physics contact (and its properties)는 어떤 타입의 충돌 리스너에서든지 가리지 않고 사용할 수 있습니다.(pre-, post-, or standard). 대부분의 경우 pre-collision를 많이 사용하죠. 왜냐하면 프로퍼티에 접근하고 세팅하고 하는 작업은 그 충돌이 일어나기 전에 필요한 거니까요.




Other Possibilities


physics contact 를 사용해야 하는  one-sided platform 이외의 경우를 한번 볼까요. 핀볼 게임 아시죠? 이 게임을 위해서 아래와 같은 conditional logic(if문 등)을 사용하실 수 있을 겁니다.


  • Silver balls collide with red bumper for extreme bounce (set physics contact bounce to 1)
  • Silver balls collide with blue bumper for no bounce (set physics contact bounce to 0)
  • Gold balls collide with red bumper for no bounce (opposite of the first case)
  • Gold balls collide with blue bumper for medium bounce



See it in Action


“one-sided platform” method를 사용하신 경우롤 보시려면 demo project를 다운 받아서 참조하세요.






In Summary…


새로만든 physics contact는 네가지 새로운 프로퍼티들을 제공합니다.


  • event.contact.isTouching — read only: are the two objects touching?
  • event.contact.isEnabled — read/write: ‘true’ or ‘false’; should the collision resolve?
  • event.contact.bounce — read/write: get or set the bounce factor of the collision
  • event.contact.friction — read/write: get or set the friction factor of the collision


특정 상황에서 이 프로퍼티들은 기본적인 충돌 이벤트와 충돌 필터들을 사용해서 이전에는 구현할 수 없었던 정교한 콘트롤을 할 수 있도록 해 줍니다. 이 프로퍼티들을 다음 physics-based project에서 사용해 보세요.


질문이나 의견이 있으시면 저 위 본문 시작하는 제목에 걸린 링크를 클릭하세요.

원문페이지기 있는데요. 거기다가 댓글로 질문 하시면 됩니다.


영어로 하셔야 되는데요.


영어가 어려우시면 이 글 밑에 댓글로 달아 주세요.

제가 여건이 되는대로 대신 질문 전달하고 답변 받으면 이 블로그에 공유해 드릴께요.



반응형