반응형
오늘은 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가 실행 되도록 합니다.
이렇게 하면 위 그림처럼 화면에 주사위 눈의 합이 출력 됩니다.
원래 소스가 두 주사위의 눈이 각각 다르게 표시되도록 하는 거였다면 제가 수정한 코드는 괜히 수정한 거네요. 이미 원래 소스에 이런 경우를 생각해서 스프라이트에서 프레임 플레이 시간을 각각 다르게 해 준건데......
어쨌든 남의 소스를 보고 나름대로 고쳐보는게 프로그래밍 배우는데 아주 큰 도움이 됩니다.
여러분들도 이 코드를 이용해서 이것저것 고치거나 기능을 덧붙이거나 하면 빨리 실력이 늘고 이 코드도 진짜로 여러분의 코드가 되고 여러분의 자산이 될 거예요.
그럼 다음 시간에 뵐께요......
오늘 다룰 소스는 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가 실행 되도록 합니다.
이렇게 하면 위 그림처럼 화면에 주사위 눈의 합이 출력 됩니다.
원래 소스가 두 주사위의 눈이 각각 다르게 표시되도록 하는 거였다면 제가 수정한 코드는 괜히 수정한 거네요. 이미 원래 소스에 이런 경우를 생각해서 스프라이트에서 프레임 플레이 시간을 각각 다르게 해 준건데......
어쨌든 남의 소스를 보고 나름대로 고쳐보는게 프로그래밍 배우는데 아주 큰 도움이 됩니다.
여러분들도 이 코드를 이용해서 이것저것 고치거나 기능을 덧붙이거나 하면 빨리 실력이 늘고 이 코드도 진짜로 여러분의 코드가 되고 여러분의 자산이 될 거예요.
그럼 다음 시간에 뵐께요......
반응형
'Corona SDK > Corona SDK TIPs' 카테고리의 다른 글
Modular Classes in Corona - 모듈과 클래스 이해하기 - (0) | 2011.12.08 |
---|---|
코로나로 책장 넘기는 효과 주기 (0) | 2011.12.06 |
내 코드 모듈화 하기 (modularize) (0) | 2011.12.01 |
드래그 하기 기초 (0) | 2011.11.25 |
화면 전환 클래스(director.lua) 사용하기 와 랜덤 화면 전환 (2) | 2011.11.24 |
ui 버튼이용 하기 ui.newButton (0) | 2011.11.18 |
화면에 시간 표시하기 (스탑와치) (0) | 2011.11.17 |
Screen Transitioning. (화면 전환,이동) (0) | 2011.11.16 |
앱 항상 켜 있게 하기 (system.setIdleTimer( enabled )) (0) | 2011.11.15 |
Animation Speed Control 은 movieClip보다 Sprites로 (0) | 2011.11.14 |