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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형
오늘은 Sprite Sheet과 timer와 관련된 팁을 다루겠습니다.

오늘 다룰 소스는 Peach Pellen 이라는 개발자가 자기 친구가 앱을 개발한다는 얘기를듣고 도움이 될까 해서 만든 주사위놀이 샘플 코드입니다. 그리고 그 코드를 공개해서 다른 분들도 도움이 되길 바란다고 하네요.

아래 링크로 가시면 관련 글을 보실 수 있습니다.

http://techority.com/2011/11/22/rolling-the-dice/

저 싸이트로 가시면 샘플 코드를 다운 받으실 수 있구요.
아래 저도 그 코드를 올려 놓을 테니까 여기서 곧바로 다운 받으셔도 됩니다.

실행 화면은 아래와 같습니다.


오른쪽 위에 하얀 사각형을 누르면 주사위가 막 돌다가 멈춥니다.
그러면 터미널에 두 주사위의 합이 출력 됩니다.

그런데 이상한건 제가 집에서 이 소스코드를 실행 했을 때는 두 주사위가 항상 같은 숫자만 나왔거든요.

그래서 다른 숫자가 나오도록 소스를 좀 수정했습니다.
그리고 터미널뿐만 아니라 화면에도 합계가 텍스트로 표시 되도록 했구요.

그런데 회사와서 이 코드를 돌려보니까 두 주사위가 항상 같은 숫자가 나오는게 아니더라구요.

집에 있는 컴퓨터는 윈도우고 회사에 있는건 맥이라서 그런가?

하여간 아래 코드는 제가 조금 수정한 코드입니다. 다운 받은 파일에 있는 소스랑은 아주 조금 다를거예요.


--Hide the status bar => 스테이터스 바 감추기
display.setStatusBar(display.HiddenStatusBar)

--Require sprite => 스프라이트 require하기. 스프라이트는 director.lua나 movieclip.lua 처럼 별도의 파일로 제공되는게 아니라 corona sdk 에 내장된 클래스 입니다. 따로 파일을 구하실 필요가 없습니다.
require "sprite"

=> 스크린 너비와 높이 구해 놓기
_W = display.contentWidth;
_H = display.contentHeight;

--The background image => 배경화면 표시하고 합계를 표시할 텍스트 선언하고 위치 정해 줌
local bg = display.newImage( "bg.png" )
local total = display.newText("", _W/2, _H-(_H/7), native.systemFontBold, 30)

--Total sum of dice after a roll => 주사위 합계 담을 변수
local diceTotal = 0

--States whether or not the dice may be rolled => 주사위 돌리기 가능한 상태인지 아닌지 콘트롤 할 변수
local canRoll = true

--Sprite Setup => 스프라이트를 셋업 함
local diceSheet = sprite.newSpriteSheet( "dice.png", 64, 64)

주사위로 사용할 이미지는 이 이미지 입니다.
일단 이 이미지를 diceSheet이라는 이름으로 만듭니다. 이 프레임의 크기는 64X64 입니다.

local diceSet = sprite.newSpriteSet( diceSheet, 1, 6 )
sprite.add( diceSet, "dice", 1, 6, 195, 0)
sprite.add( diceSet, "dice2", 1, 6, 210, 0)

위 diceSheet를 diceSet이라는 스프라이트 세트에 담습니다. 시작하는 프레임은 1 이고 총 6개 프레임이 있습니다.
이 diceSet를 add합니다. 신택스는 아래와 같습니다.
sprite.add( spriteSet, sequenceName, startFrame, frameCount, time, [loopParam] )
첫번째는 diceSet를 dice라는 sequenceName으로 add를 하는데 시작 프레임 1이고 전체 프레임 count는 6 입니다. time은 195입니다. 이것은 195ms에 이 diceSet을 한번 돌린다는 겁니다.
두번째 줄은 dice2인데 dice와 모두 같고 이 time이 210 입니다.
두 주사위가 6개 프레임의 돌아가는 시간이 다르니까 각각 다른 프레임이 나오겠네요.
윈도우에서 항상 똑 같은 주사위 이미지가 나온게 제가 착각한 건가 본데요?
혹시 여러분 윈도우에서 한번 돌려보시구 어떻게 나오나 잘 살펴 보세요.
저도 집에 돌아간 다음에 다시 돌려 봐야 겠네요.

--First Die
local dice = sprite.newSprite( diceSet )
dice.x = 120
dice.y = 200
dice:prepare("dice")

첫번째 sprite를 dice라는 변수에 담고 화면의 위치를 정해 줍니다.
스프라이트 쉬트 사용하는 순서가 이렇게 되네요.
sprite.newSpriteSheet => sprite.newSpriteSet => sprite.add => sprite.newSprite => spriteInstance:prepare => spriteInstance:play => spriteInstance:pause
따로 정리해서 외워도 좋겠는데요.

--Second Die
local dice2 = sprite.newSprite( diceSet )
dice2.x = 200
dice2.y = 300
dice2:prepare("dice2")

두번째 스프라이트 dice2를 선언합니다.

--Roll button
local rollBtn = display.newImage("die.png")
rollBtn.x = 280
rollBtn.y = 40

=> 버튼 이미지를 표시합니다.

--End Roll Function
local function endRoll()
    dice:pause()
    showTotal();
end

첫번째 주사위 play를 중지시키고 showTotal함수를 실행합니다.

local function endRoll2()
    dice2:pause()
    showTotal();
end

두번째 주사위 play를 중지시키고 showTotal함수를 실행합니다.

function showTotal()
    diceTotal = dice.currentFrame + dice2.currentFrame
    print(diceTotal) --Print the result in the terminal
    total.text="Total : " .. diceTotal;
    canRoll = true --Allow the dice to be rolled again
end

현재 프레임 = 주사위 눈 입니다. dice와 dice2의 현재 프레임을 구해서 더하면 주사위 두 눈의 합이 됩니다.
이것을 터미널에 print하고 스크린에도 표시합니다.
canRoll은 true로 세팅해서 버튼을 누르면 주사위가 돌아갈 수 있도록 합니다.

--Roll function
local function rollDice()
    if canRoll == true then
        canRoll = false --Prevent dice from being rolled again before the current role is over
        dice:play()
        dice2:play()
        randomTime = math.random(1500, 3500)
        timer.performWithDelay(randomTime, endRoll, 1)
        randomTime2 = math.random(1500, 3500)
        timer.performWithDelay(randomTime2, endRoll2, 1)
    end
end
canRoll을 false로 해서 버튼을 눌러도 주사위가 새로 돌지 않도록 막아 놓습니다.
dice와 dice2를 play시킵니다.
랜덤값 (1.5초 ~ 3.5초)를 구해서 timer를 사용해서 그 시간만큼만 돌고 dice를 멈추게 합니다. 다음줄은 dice2를 멈추게 합니다.

rollBtn:addEventListener("tap", rollDice)

버튼에 이벤트 리스너를 달아서 누르면 rollDice가 실행 되도록 합니다.



이렇게 하면 위 그림처럼 화면에 주사위 눈의 합이 출력 됩니다.

원래 소스가 두 주사위의 눈이 각각 다르게 표시되도록 하는 거였다면 제가 수정한 코드는 괜히 수정한 거네요. 이미 원래 소스에 이런 경우를 생각해서 스프라이트에서 프레임 플레이 시간을 각각 다르게 해 준건데......

어쨌든 남의 소스를 보고 나름대로 고쳐보는게 프로그래밍 배우는데 아주 큰 도움이 됩니다.

여러분들도 이 코드를 이용해서 이것저것 고치거나 기능을 덧붙이거나 하면 빨리 실력이 늘고 이 코드도 진짜로 여러분의 코드가 되고 여러분의 자산이 될 거예요.

그럼 다음 시간에 뵐께요......
반응형