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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형
어제 애플(Apple)이 아이폰을 발표했는데 iPhone 5 가 아니라 iPhone 4S 였군요. 새로워진 것도 별로 없고... 안드로이드 진영에선 이미 다 구현 한 것들이구.
실망이 이만 저만이 아니겠는데요. 잡스 없는 애플이 이제 내리막 길로 가는 것은 아닌지......
우리나라의 삼성과 LG 에는 아주 좋은 기회가 될 듯 합니다.
1년 넘는 기간 동안 그정도 밖에 준비 못했다니..... 애플 완전 실망...

오늘은 코로나 SDK (Corona SDK) 에서 다각형 그리기 부터 하겠습니다.

코로나에서는 벡터 객체를 사용해서 다각형을 그립니다. 벡터 객체는 DisplayObject의 특별한 타입 입니다.
우선 사각형, 모서리가 둥근 사각형, 원 그리는 신택스를 보겠습니다.

display.newRect( [parentGroup,] left, top, width, height )
parentGroup은 옵션이구요. 이건 나중에 볼께요. 우선 좌측과 상단 값을 넣어서 좌상단 꼭지점의 위치를 정하고 너비와 높이 값을 주어서 사각형을 선언합니다. 여기서 색을 지정하는 건 없네요. 메소드를 사용해서 색을 지정할까요? 잠시후에 보죠.

display.newRoundedRect( [parentGroup,] left, top, width, height, cornerRadius )
모서리가 둥근 사각형은 위의 사각형과 같구요. 다만 맨 마지막에 모서리에 그릴 곡선의 반지름 값을 넣으면 됩니다.

display.newCircle( [parentGroup,] xCenter, yCenter, radius )
원은 원 중심의 x,y 값을 넣고 반지름 값을 넣습니다.
   
strokeWidth (테두리선)는 아래와 같이 파라미터를 사용해서 정해 줍니다.
object.strokeWidth = 픽셀
색 지정은 아래와 같이 메소드를 사용합니다.
object:setFillColor(r,g,b[,a]) , object:setStrokeColor(r,g,b[,a])
a는 알파값(투명도) 로 옵션 입니다. 들어갈 값은 0~255 사이에 있는 수입니다.

라인 그리기는 display.newLine(x1,y1,x2,y2) 을 사용합니다.
그리고 라인과 라인을 연결하면 다각형을 만들 수 있는데요. 이것은 object:append()를 사용합니다.

아래 샘플 코드를 작성하고 실행 해 볼까요.
 local star = display.newLine( 0,-110, 27,-35 )
  star:append( 105,-35, 43,16, 65,90, 0,45, -65,90, -43,15, -105,-35, -27,-35, 0,-110 )
  star:setColor( 255, 102, 102, 255 )
  star.width = 3


별을 그리는 코드인데요.
별 모양이 왼쪽 위에 반만 나와 있죠?
이 라인 위치와 색 그리고 width 등은 여러분들이 바꾸면서 익혀 보세요.
남의 소스를 자기 맘대로 막 고치면서 이해도 더 잘 되고 실력도 더 많이 늘더라구요.

아래는 코로나에서 제공하는 샘플 코드인데요. (Graphics/PolyLines)
한번 실행해 보세요.
--
-- Abstract: PolyLines sample app, demonstrating how to draw shapes using line segments
-- Version: 1.0
-- Sample code is MIT licensed, see http://developer.anscamobile.com/code/license
-- Copyright (C) 2010 ANSCA Inc. All Rights Reserved.
-- Example of shape drawing function
local function newStar()
    -- need initial segment to start
    local star = display.newLine( 0,-110, 27,-35 )
    -- further segments can be added later
    star:append( 105,-35, 43,16, 65,90, 0,45, -65,90, -43,15, -105,-35, -27,-35, 0,-110 )
    -- default color and width (can also be modified later)
    star:setColor( 255, 255, 255, 255 )
    star.width = 3
    return star
end

-- Create stars with random color and position
local stars = {}

for i = 1, 20 do
    local myStar = newStar()
   
    myStar:setColor( math.random(255), math.random(255), math.random(255), math.random(200) + 55 )
    myStar.width = math.random(10)
   
    myStar.x = math.random( display.contentWidth )
    myStar.y = math.random( display.contentHeight )
    myStar.rotation = math.random(360)
   
    myStar.xScale = math.random(150)/100 + 0.5
    myStar.yScale = myStar.xScale
   
    myStar:setReferencePoint( display.CenterReferencePoint )

    local dr = math.random( 1, 4 )
    myStar.dr = dr
    if ( math.random() < 0.5 ) then
        myStar.dr = -dr
    end

    table.insert( stars, myStar )
end

function stars:enterFrame( event )

    for i,v in ipairs( self ) do
        v.rotation = v.rotation + v.dr
    end
end

Runtime:addEventListener( "enterFrame", stars )


저는 사용하던 소스에 위 소스를 덧 붙였더니 위 화면같이 나옵니다.
지금 까지 배운 걸로도 이 소스를 충분히 분석할 수 있을 것 같은데요.
나중에 샘플 코드 분석할 때 시간 되면 이 소스도 함 자세히 분석해 보죠.
오늘은 Text, Group, Stage 등 앞으로 나갈 진도가 더 있어서 계속 진도 나가겠습니다.

TEXT
우리가 작성한 소스에 이미 Text 사용하는게 있는데요.
local textObj = display.newText("A short string", 0,0, nil, 26);
display.newText 를 사용하고 그 안에 텍스트와 x,y 좌표 그리고 폰트(여기선 nil), 글자 사이즈 이렇게 들어갑니다.
현재 사용하고 있는 폰트를 알아내시려면 native.getFontNames() 함수를 사용합니다.
디폴트 폰트는 native.systemFont , native.systemFontBold 입니다.
object.size - 텍스트 사이즈를 정합니다. (=숫자 를 덧붙이시면 됩니다.)
object.setTextColor(r,g,b[,a]) -  텍스트 칼라를 지정합니다.
파라미터는 . 를 사용하고 메소드는 : 를 사용하는건 이제 아시겠죠?
값을 대입 시키는 것도 대부분 파라미터는 = 숫자 , 문자 등등 을 사용하고 메소드는 () 안에 인수값을 넣구요.

원하는 폰트를 사용하시려면 우선 폰트 파일 (.ttf) 이 있어야 되고 이것을 building.settings 파일에 아래와 같이 세팅해 줘야 합니다.
settings =
{
        iphone =
        {
                plist =
                {
                        UIAppFonts =
                        {
                                "Harrowprint.ttf"
                        }
                },
        },
}
이것은 아이폰 일 경우만 해당되고 안드로이드용은 이 build.settings 파일에 세팅을 하지 않아도 됩니다.

Groups

이  Group 객체도 DisplayObject의 특별한 타입 중 하나입니다.
display.newGroup() 으로 그룹을 생성합니다. 그리고 이 그룹에 객체들을 insert 하고 각 객체들에 대한 접근은 테이블(배열) 에서 접근하는 것처럼 index 1번 부터 시작합니다.
그룹 생성 및 인서트는 아래와 같이 합니다.
 local group = display.newGroup()
  group:insert( rect1 ) -- assume rect1 is an existing display object
  group:insert( rect2 ) -- assume rect2 is an existing display object

만약 그룹 2개를 생성하고 한 객체를 두군데 모두 삽입했다면 코로나가 알아서 마지막 insert문만 적용하도록 만듭니다.
local txt=display.newText('Hello',0,0)
local g1=display.newGroup()
local g2=display.newGroup()
             
-- Insert text object into g1
g1:insert(txt)              
-- Insert same text object into g2
g2:insert(txt)
 
print("g1[1]: " .. tostring(g1[1])) -- prints nil
print("g2[1]: " .. tostring(g2[1])) -- prints textObject    

그룹을 없애려면 remove를 사용합니다. group:remove(indexOrChild)

이 그룹은 여러 객체를 하나의 객체처럼 사용할 때 편리합니다.

Stage

스테이지도 GroupObject의 특별한 타입 중 하나입니다.
스테이지는 모든 display 객체들의 root group입니다.
현재의 스테이지는 아래와 같이 접근 할 수 있습니다.
display.getCurrentState()

다른 Display함수들을 보면 아래와 같은 것들이 있습니다.
display.captureScreen(saveToAlbum) 화면을 캡쳐해서 이미지로 만듭니다. saveToAlbum 이 true이면 그 이미지를 디바이스(핸드폰) 의 앨범에 저장합니다.
시뮬레이터일 경우에는 데스크탑 컴퓨터에 저장합니다.

display.save(displayObject,filename[,baseDirectory])
해당 객체를 JPEG 이미지로 filename에서 지정한 이름으로 바꿔 줍니다.

display.setStatusBar(mode) mode가 display.HidenStatusBar이면 아이폰의 스테이터스 바가 화면에 나오지 않습니다. 관련된 argument들엔 다음과 같은 것들이 있습니다.

    * display.HiddenStatusBar
    * display.DefaultStatusBar
    * display.TranslucentStatusBar
    * display.DarkStatusBar

Size 관련된 프로퍼티들엔 아래와 같은 것들이 있습니다.
display.contentWidth - 스크린 너비가 픽셀단위로 나타납니다. config.lua에서 픽셀 말고 다른 것으로 설정해 놨으면 그 값이 나타납니다.
display.contentHeight - 스크린 높이가 나타납니다.
display.viewableContentWidth - 다이나믹 스케일 모드일 때 유용하게 사용할 수 있습니다. 해당 객체의 너비를 나타냅니다.
display.viewableContentHeight - 해당 객체의 높이를 나타냅니다.
display.statusBarHeight - 상태 바의 높이를 픽셀로 나타냅니다. iOS에서만 적용됩니다.

Display Object 대 Table

DisplayObject와 Table은 유사한 점이 많습니다. 다른 점은 Display Object의 메타테이블을 세팅할 수 없다는 겁니다.
내부적으로 코로나의 DisplayObject는 native C++객체를 사용합니다.

오늘은 여기까지 알아봤구요.

다음 시간에 Display Object 와 Stage에 대해 좀 더 자세히 예제와 함께 알아보겠습니다.

감사합니다.
반응형


반응형
오늘은 텍스트와 이미지, 라인, 다각형 같은 모양들 표시하는 방법에 대해 공부하겠습니다.

display.setStatusBar( display.HiddenStatusBar )
local textObj = display.newText("A short string", 0,0, nil, 14);
textObj:setReferencePoint(display.CenterLeftReferencePoint);
textObj.x = 20;

textObj.text = "This string has several more characters than before..."

textObj.text = "This is third sentence."
textObj:setReferencePoint(display.CenterLeftReferencePoint);
textObj.x = 20

우선 첫번째 줄은 아이폰에서 status bar 없애는 거구요.
다음줄 보맨 textObj 변수에 "A short string"이란 텍스트를 담고 위치는 0,0 폰트는 nil로 설정해서 그냥 디폴트가 나오도록 하고 글자 사이즈는 14포인트로 정했습니다.
다음은 textObj에 setReferencePoint를 적용하고 x 좌표를 20으로 했습니다.

그리고 textObj.text 를 이용해서 다른 문구를 적용했습니다.
그리고 다음줄은 또 다른 문구를 적용했구요.

화면에는 위와 같이 맨 마지막 적용된 값이 표시됩니다.

화면에 표시되는 모든 것은 DisplayObjects가 만듭니다. 즉 화면에 표시되는 모든 것은 이 DisplayObjects의 인스턴스 입니다.
사각형, 원, 이미지, 텍스트 같은 모든 것들은 다 DisplayObject를 사용해 표시할 수 있습니다.
이걸 기초로 애니메이션을 만든다던가 터치를 하면 다른 객체를 표시한다던가 하는 일들을 하게 됩니다.
이 DisplayObject는 특별한 함수인 생성자(constructor)를 호출함으로서 생성할 수 있습니다. 직접적으로 생성하지는 않습니다.
예를 들어 display.newRect()는 Vector Object를 생성하게 됩니다.

이러한 display object들은 아래와 같은 프로퍼티들과 메소드들을 사용할 수 있습니다.
프로퍼티들은 . 로 접근 할 수 있습니다.
예를 들어 아까 작성했던 텍스트에 투명도를 주려면
textObj.alpha=0.5 를 주면 됩니다.
자주 사용되는 프로퍼티 몇개를 살펴 보면요.
object.inVisible = true or false
object.height , object.width, object.length 객체 크기와 길이 등을 구할 수 있습니다.
object.isHitTestable 객체가 보이지 않을 때에도 hit 이벤트를 받을 수 있도록 합니다. (true 일 경우)
object.rotation = 숫자 -> 해당 객체를 로테이션 시킵니다.

위 화면은 아까 작성했던 코드에 아래 몇줄을 더 한 겁니다.
textObj.alpha=0.8
oHeight = textObj.height
print("Height = " .. oHeight)
textObj.rotation = 45

object.x, object.y 객체의 x,y 좌표
좀 더 자세한 사항은 아래 페이지를 참고 하세요.
http://developer.anscamobile.com/content/display-objects

다음은 메소드를 살펴 봅니다.
메소드는 : 를 이용해서 접근 할 수 있습니다.

object:rotate() 현재의 로테이션에 ()안에 있는 로테이션 각도를 추가해서 적용합니다.
예를 들어 아까 소스에 textObj:rotate(-25) 를 하면 45-25=20 이니까 20도의 기울기가 나오게 됩니다.
파라미터를 쓰게 되면 (textObj.rotation = -25) 그냥 -25도로 기울기가 표시 됩니다.
object:scale(sx,sy) 객체의 길이와 높이를 세팅합니다.
object:setReferencePoint(referencePoint) 기준점을 정합니다.
reference Point 종류는 아래와 같습니다.
    * display.CenterReferencePoint
    * display.TopLeftReferencePoint
    * display.TopCenterReferencePoint
    * display.TopRightReferencePoint
    * display.CenterRightReferencePoint
    * display.BottomRightReferencePoint
    * display.BottomCenterReferencePoint
    * display.BottomLeftReferencePoint
    * display.CenterLeftReferencePoint

예를 들어 처음의 예제에서 referncePoint를 CenterLeftReferncePoint를 사용했습니다. 그리고 text길이가 다르게 세팅을 했고 x포인트를 20으로 늘렸습니다.
이 레퍼런스 포인트를 어떻게 설정하느냐에 따라 해당 객체의 길이가 달라질 때 화면에 표시되는 위치가 다르게 보일 수가 있습니다.

object:translate(deltaX,deltaY) 현재 위치에서 deltaX,deltaY만큼 이동시킵니다.
object:removeSelf() 객체를 없앱니다. 이는 메모리 할당을 풀어주게 됩니다.


*** 이미지 Images
 Bitmap 이미지 객체도  DisplayObject의 한 타입입니다.

display.newImage(filename[,baseDirectory][,left,top])

저는 이미지테스트 할 때 아래 이미지를 사용하겠습니다.

이름은 endinggreen.png입니다.
이번에 Corona로 만든 간단한 게임에 사용했던 이미지 입니다.
제가 이미지 디자인한건 아니고 동료 디자이너가 디자인 했죠. 저는 개발만 했습니다.
잠깐 홍보 하자면 안드로이드는 아래 링크로 볼 수 있습니다.
https://market.android.com/details?id=nowbyte.corona.multipingpong&feature=search_result
저희 회사에서 제가 만든 앱들을 보려면 아래 링크로 가시면 보실 수 있구요.
https://market.android.com/search?q=effilonNY&so=1&c=apps
대부분이 게임이라서 한국에서는 볼 수 있을 지 모르겠습니다.
아이폰 앱 스토어는 아래 링크로 보실 수 있구요.
http://itunes.apple.com/us/app/multi-player-ping-pong/id466527438?ls=1&mt=8
이것도 게임 카테고리에 들어 있어서 한국에서는 보실 수 있을 지 모르겠습니다.
예전 강좌에 있던 대로 config.lua 파일에서 아이폰 (iPhone) 해상도 (resolution) 인 320 X 480 으로 하고 scale = "letterbox" 로 했기 때문에 안드로이드 폰의 모든 기기 (갤럭시S, 갤럭시S2, 드로이드, 넥서스 원 (NexusOne), 갤럭시 탭) 에서 사용할 수 있습니다. 새로나온 갤럭시 탭이나 이번에 나온 아마존의 킨들 파이어 (Kindle fire)에서는 테스트 해 보지 않았지만 여기서도 돌아갈 겁니다.
그리고 애플 쪽 디바이스은 아이폰, 아이폰 4 , iPod Touch, iPad 에서 다 돌아갑니다. 그리고 오늘 발표 될 iPhone 5 에서도 제대로 나올겁니다.

코로나 SDK (Corona SDK) 의 장점은 Box2D를 사용한 강력한 물리엔진 (Physics Engine)과 한번 개발해서 애플의 아이폰, 아이패드 디바이스와 안드로이드의 모든 모바일 폰 과 태블릿 (갤럭시 탭, 모토로라의 줌 (XOOM), 아이리버의 아이리버 탭 그리고 아마존의 Kindle fire 까지) 에서 사용할 수 있고 해상도도 간편하게 적용할 수 있다는 것에 있습니다.

일단 제가 개발한 앱과 코로나 SDK에 대한 홍보는 여기서 마치구요.
코로나에서 이미지 디스플레이 하는 것을 보도록 하겠습니다.

아까까지 사용했던 소스에 아래 두 줄을 덧 붙이겠습니다.

myImage = display.newImage( "endinggreen.png", 10, 150 )
myImage2 = display.newImage( "endinggreen.png" )


보시는 대로 이미지는 display.newImage 생성자(constructor)를 사용해서 그립니다.
이미지 이름만 파라미터로 넣어도 되고 x,y 좌표도 같이 넣어도 됩니다.
코로나에서는 PNG와 JPEG파일을 지원한다고 나옵니다.
제 기억엔 GIF도 나왔던 것 같은데요.. 잘 모르겠네요. GIF는 나오고 GIF 애니메이션은 지원이 안 되서 그냥 정지된 이미지 하나만 나온 것 같은데요... 궁금하시면 한번 해 보세요.
이미지 크기가 맥시멈을 넘어서면 autoscale됩니다. iPhone 3G 의 경우 1024  X 1024 , iPhone 3GS, iPad 의 경우는 2048X2048 이 맥시멈 사이즈 입니다.

이전 코드에 아래 세줄을 넣어 보세요.
myDynamicImage = display.newImageRect( "endinggreen.png", 60, 200 )
myDynamicImage.x =260
myDynamicImage.y =300

newImageRect 는 이렇게 이미지의 width,height를 다이나믹하게 설정할 때 사용합니다.
이 다이나믹 이미지 해상도(Dynamic Image Resolution) 과 configuring 에 대해 좀 더 자세히 보시려면 아래 링크를 참조하세요.
http://developer.anscamobile.com/content/configuring-projects#Dynamic_Image_Resolution

오늘은 이렇게 텍스트와 이미지 표시하는 법과 displayObject 에서 사용되는 파라미터와 메소드들에 대해 알아봤습니다.

다음 시간엔 사각형, 원 그리고 다각형 그리는 법과 색깔 넣는 법, 글자 폰트 지정하는 법과 새로운 폰트 사용하는 법, Group 사용법 (display.newGroup), stage 객체에 대해 알아보겠습니다.

이 모든 것들이 Display Object 의 객체(인스턴스) 들입니다.

그리고 간단히 Display Object 와 테이블에 대한 기술적인 분석에 대해서도 다룰 거구요.

뭐 별거는 아니지만 오늘 사용했던 코드 전체는 아래와 같습니다.
display.setStatusBar( display.HiddenStatusBar )
-- A text object is created and is aligned left at point x=20
local textObj = display.newText("A short string", 0,0, nil, 26);
textObj:setReferencePoint(display.CenterLeftReferencePoint);
textObj.x = 20;

 
-- Later, the textObj.text property is assigned a new string value of different length,
-- causing the object's width to change, but not its reference point.
-- Consequently, the text is no longer aligned left at point x =20
textObj.text = "This string has several more characters than before..."
 
-- Work-around:
-- Reset the text object's reference point and x position
-- after you update its text property:
textObj.text = "This is third sentence."
textObj:setReferencePoint(display.CenterLeftReferencePoint);
textObj.x = 20
textObj.alpha=0.8
oHeight = textObj.height
print("Height = " .. oHeight)
textObj.rotation = 45
textObj:rotate(-25)

myImage = display.newImage( "endinggreen.png", 10, 150 )
myImage2 = display.newImage( "endinggreen.png" )
myDynamicImage = display.newImageRect( "endinggreen.png", 100, 100 )
myDynamicImage.x =260
myDynamicImage.y =300


그럼 다음 시간에 뵙겠습니다.
반응형


반응형
오늘은 화면에 점수 표시하는 샘플코드를 공부할 겁니다.

이 파일이 전체 소스 파일입니다.
웹 싸이트는 http://techority.com/2011/01/26/how-to-add-a-score-to-your-iphone-app/ 입니다.
이 싸이트로 가면 유튜브 동영상도 있습니다.

이 소스를 보면서 제 식으로 공부 해 보겠습니다.


이 소스를 실행하면 위 화면처럼 나옵니다.
화면을 Tapping 하면 1 포인트씩 숫자가 올라갑니다.

우선 main.lua부터 보겠습니다.

--[[
Related files are score.lua, 1 through 9.png, scorebg.png and space.png
--]]
display.setStatusBar( display.HiddenStatusBar )
local background = display.newImage ("background.png")

score = require ("score")

local border = 5

local scoreInfo = score.getInfo()

score.init({
x = 40,
y = 5}
)
score.setScore(0)

local function addtoit (event)
if event.phase == "ended" then
score.setScore (score.getScore()+1)
end
end
background:addEventListener("touch", addtoit)

처음에 아이폰의 StatusBar를 없앱니다. (원래 소스에는 없는데 그냥 제가 추가 했습니다. 이게 보기에 더 편하더라구요.)
두번째는 백그라운드 이미지를 display 합니다.

세번째는 score.lua 소스를 require (implement) 합니다.
그 다음은 border를 5로 설정합니다.(이 border는 뭐 하는건지 모르겠습니다. 그냥 쓸데없이 있는거 같네요.)

그 다음엔 아까 require했던 score.lua에 있는 getInfo() 함수를 scoreInfo 변수에 담습니다. 이 getInfo() 함수는 이따 score.lua 파일을 살펴 볼 때 어떤 기능인지 공부하겠습니다.

그 다음은 score.lua에 있는 init() 함수에 x,y 파라미터를 넣어서 실행시킵니다.
그리고 setScore()함수에 파라미터 값을 0으로 해서 보냅니다.

로컬 함수 addtoit(event) 함수를 만듭니다.
그 내용은 이벤트가 끝나면 score.lua의 setScore함수에 이전 점수 +1 을 한 파라미터 값을 넣어서 부릅니다.

맨 마지막으로 background 에 touch 리스너를 달구요. 이 이벤트가 일어났을 경우 addtoit() 함수를 실행시킵니다.

지금까지 main.lua의 코드를 분석해 봤습니다.
이제 score.lua 파일을 분석해 보겠습니다.

-- A sample score keeping display
-- This updates a display for a numeric score
-- Example usage:
--    Place the score at 50,50
--         score.init( { x = 50, y = 50 } )
--    Update the score to current value + 10:
--        score.setScore( score.getScore() + 10 )

module(..., package.seeall)
 
-- Init images. This creates a map of characters to the names of their corresponding images.
 local numbers = {
    [string.byte("0")] = "0.png",
    [string.byte("1")] = "1.png",
    [string.byte("2")] = "2.png",
    [string.byte("3")] = "3.png",
    [string.byte("4")] = "4.png",
    [string.byte("5")] = "5.png",
    [string.byte("6")] = "6.png",
    [string.byte("7")] = "7.png",
    [string.byte("8")] = "8.png",
    [string.byte("9")] = "9.png",
    [string.byte(" ")] = "space.png",
}

-- score components
local theScoreGroup = display.newGroup()
local theBackground = display.newImage( "scorebg.png" )
local theBackgroundBorder = 10

theScoreGroup:insert( theBackground )

local numbersGroup = display.newGroup()
theScoreGroup:insert( numbersGroup )

-- the current score
local theScore = 0

-- the location of the score image

-- initialize the score
--         params.x <= X location of the score
--         params.y <= Y location of the score
function init( params )
    theScoreGroup.x = params.x
    theScoreGroup.y = params.y
    setScore( 0 )
end

-- retrieve score panel info
--        result.x <= current panel x
--        result.y <= current panel y
--        result.xmax <= current panel x max
--        result.ymax <= current panel y max
--        result.contentWidth <= panel width
--        result.contentHeight <= panel height
--        result.score <= current score
function getInfo()
    return {
        x = theScoreGroup.x,
        y = theScoreGroup.y,
        xmax = theScoreGroup.x + theScoreGroup.contentWidth,
        ymax = theScoreGroup.y + theScoreGroup.contentHeight,
        contentWidth = theScoreGroup.contentWidth,
        contentHeight = theScoreGroup.contentHeight,
        score = theScore
    }
end

-- update display of the current score.
-- this is called by setScore, so normally this should not be called
function update()
    -- remove old numerals
    theScoreGroup:remove(2)

    local numbersGroup = display.newGroup()
    theScoreGroup:insert( numbersGroup )

    -- go through the score, right to left
    local scoreStr = tostring( theScore )

    local scoreLen = string.len( scoreStr )
    local i = scoreLen   

    -- starting location is on the right. notice the digits will be centered on the background
    local x = theScoreGroup.contentWidth - theBackgroundBorder
    local y = theScoreGroup.contentHeight / 2
   
    while i > 0 do
        -- fetch the digit
        local c = string.byte( scoreStr, i )
        local digitPath = numbers[c]
        local characterImage = display.newImage( digitPath )

        -- put it in the score group
        numbersGroup:insert( characterImage )
       
        -- place the digit
        characterImage.x = x - characterImage.width / 2
        characterImage.y = y
        x = x - characterImage.width
        --
        i = i - 1
    end
end

-- get current score
function getScore()
    return theScore
end

-- set score to value
--    score <= score value
function setScore( score )
    theScore = score
   
    update()
end

score.lua 파일을 보겠습니다.
score.lua 파일 처음에 module(..., package.seeall) 를 넣습니다. 이러면 이 파일은 모듈로 사용될 수 있습니다.
이것을 했기 때문에 main.lua에서 require("score") 를 할 수 있고 이것을 변수 score에 담아서 score.(score.lua에 있는 함수) 방법으로 score.lua 내의 함수를 main.lua에서 사용할 수 있습니다.

그 다음 numbers 라는 테이블 변수에 0~9 의 이미지 파일을 담습니다.

그 다음은 display.newGroup()으로 객체들을 담을 그룹을 만듭니다.
그리고 score를 표시할 백그라운드 이미지를 넣고 theBackgroundBorder 변수에 10을 담습니다.

아까 만들었던  theScoreGroup에 백그라운드 이미지(theBackground)를 insert 합니다.
보시면 아까 theScoreGroup 말고 또다른 Group인 numberGroup을 만듭니다.
그리고 이 numberGrooup 자체를 처음의 theScoreGroup에 insert 합니다.

다음 줄에서 theScore 변수를 0으로 선언합니다. 처음 0점부터 시작하게 됩니다.
이제 함수가 나오네요. 아까 main.lua에서 불렀던 init(params) 함수가 나옵니다.

여기서는 theScoreGroup.x와 y를 전달받은 파라미터 값으로 넣고 setScore()함수에 0을 던져 줍니다.
아까 main에서 x=40, y=5 으로 보냈기 때문에 그 위치에 theScoreGroup의 객체들이 display 될 겁니다.

다음은 getInfo() 함수입니다. main함수에서는 이 함수에서 세팅된 값을 scoreInfo 변수에 담았었습니다.
getInfo() 함수에서는 7개의 값을 return합니다.
Lua (Corona) 에서는 복수개의 값을 return 할 수 있습니다.
theScoreGrooup,x , y 값과 ymax,ymax, contentWidth,contentHeight, score 등의 값을 return합니다.

다음은 update() 함수입니다.
처음엔 이전 score를 없앱니다.
그 다음은 numbersGroup이라는 그룹을 만들고 이를 통째로 theScoreGroup에 넣습니다.
다음줄은 theScore를 String 값으로 변환해서 scoreStr 변수에 담습니다.
Score가 한자리 수 인지 두자리 수인지 세자리 수인지 에 대한 정보를 담는 변수도 있네요.
scoreLen변수에 scoreStr 의 length를 담습니다.
local x, y는 점수가 표시되는 위치 입니다. 한자리 수일때 두자리 수일때 표시되는 위치가 조금씩 다르겠죠?

그 다음 while 문에서 어떤 점수 이미지를 어디에 뿌려줄지 계산하는 로직이 있습니다.
이미지를 출력하고 그 이미지를 numbersGroup에 담습니다.
그리고 나서 이미지의 x,y 좌표를 설정하구요.
이 while 문은 scoreLen 만큼 돌아갈 겁니다.

다음 함수는 getScore() 함수인데 여기서는 theScore를 리턴해 줍니다.

그리고 setScore() 함수에서는 theScore 함수에 score 값을 넣어 준 후 update() 함수를 실행시킵니다.

여기 까지 하면 scoring 샘플이 모두 완성된거구요.
이걸 실행 한 후 background를 누르면 점수가 1씩 증가하게 될 겁니다.

이 소스를 가지고 있으면 나중에 게임 개발할 때 아주 유용하게 사용할 수 있을 겁니다.

그럼.........

반응형