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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

코로나 애니메이션 Sprite Sheets.

2011. 10. 8. 20:53 | Posted by 솔웅


반응형
이 Sprite Sheets 는 조금 독특한 것 같습니다.
이전에 플래시 같은데서 썼던 개념인지 어떤지 모르겠지만.
여러 동작을 표현한 하나의 이미지 파일을 불러와서 특정 구역을 지정하면.
코로나는 그 특정구역별로 하나씩 이미지로 인식합니다.
그리고 그것을 Frame 단위로 display 하면서 애니메이션 효과를 냅니다.

글로만 쓰니까 잘 모르겠죠?

이렇게 하나의 이미지파일에 여러 동작을 그려 넣습니다.
개발자는 Sprite Sheets를 이용해서 저 하나하나별로 구역을 나눕니다.
그러면 코로나는 그 개별 구역을 개별 이미지로 인식해서 애니메이션을 연출합니다.

이렇게 하면 하나의 이미지 파일을 불러오니까 메모리 절약 효과도 있겠네요.
Loading 시간도 줄일 수 있겠구요.
그 외에 어떤 장점이 있는지 (MovieClips와 비교해서) 한번 알아보죠.

Corona 는 두가지 형태의 Sprite Sheets 를 제공합니다.
사이즈와 포지션이 일정한 것과 사이즈와 포지션이 일정하지 않은 것이 있습니다.

위에 있는 이미지는 uniformly-sized 프레임 입니다. (이 이미지는 코로나 샘플 파일의 sprites 폴더에 보면 있습니다.)

두번째는 외부 데이터 파일에서 그 크기와 위치를 지정하는 건데요. 이건 ZwoptexTexturePacker 같은 툴을 이용해서 만듭니다.

이 그림은 위에서 말한 샘플 코드 sprites 폴더 아래 있습니다. 그리고 외부 데이터 파일은 uma.lua 이름으로 있습니다.

코로나는 애니메이트 된 캐릭터에 대한 순서나 거꾸로 움직이기 등의 메소드를 제공하는 constructor들을 제공합니다. 이것은 frame-base 가 아니라 time-base로 주로 이용 됩니다.
샘플 코드 중 JungleScene 샘플 을 보시면 퓨마의 움직임하고 사람의 움직임이 약간 다릅니다. 정확히 속도가요.  이것은 두 객체가 다른 frame rate 으로 움직이기 때문입니다.


위에서 말한대로 이 JungleScene은 uniformly-sized frames를 사용했고 HorseAnimation 은 non-uniformly sized and positioned 방법을 사용했습니다.

혹시 다음에 시간 되면 이 샘플 소스들도 자세히 살펴 보도록 하겠습니다.
우선은 이 Sprite Sheets에 대한 진도를 계속 나가겠습니다.
주의 할 점은 이미지 사이즈가 디바이스의 맥시멈 사이즈를 넘으면 그림이 표시 되지 않습니다.
이 정보는 system.getinfo("maxTextureSize")를 통해서 얻을 수 있습니다.

이 sprite 효과를 사용하려면 아래와 같이 합니다.
require "sprite"
그리고 sprite.newSpriteSheet , sprite.newSpriteSheetFromData 이 두 함수는 새로운 sprite sheets를 생성합니다.

spriteSheet = sprite.newSpriteSheet("image.png", fromeWidth, fromeHeight)
이 코드는 uniformly-sized frames sprite sheet를 생성합니다.
spriteSheet = sprite.newSpriteSheetFromData("image.png", spriteData)
이 코드는 외부 파일에서 지정한 frame size와 포지션을 적용할 때 이용합니다.

외부 데이터 파일은 아래와 같은 형식으로 돼 있습니다.
-- test.lua
module (...)
 
function getSpriteSheetData()
 
        local sheet = {
                frames = {
                        {
                        name = "01.png",
                        spriteColorRect = { x = 38, y = 38, width = 50, height = 50 },
                        textureRect = { x = 2, y = 70, width = 50, height = 50 },
                        spriteSourceSize = { width = 128, height = 128 },
                        spriteTrimmed = true,
                        textureRotated = false
                        },
 
                        {
                        name = "02.png",
                        spriteColorRect = { x = 38, y = 36, width = 50, height = 52 }, 
                        textureRect = { x = 2, y = 242, width = 50, height = 52 }, 
                        spriteSourceSize = { width = 128, height = 128 }, 
                        spriteTrimmed = true,
                        textureRotated = false
                        },
                }
        }
        return sheet
end

위 소스는 이미지 파일을 두개의 이미지로 나누는데요. 위치와 사이즈 등을 설정하도록 돼 있습니다.

이 파일 (test.lua) 을 이용하려면 아래와 같이 합니다.
local sprite = require("sprite")
-- In this case, test.lua is exported from Zwoptex
local test = require("test.lua")
-- Method defined by test.lua that returns table data defining the sprites
local spriteData = test.getSpriteSheetData()
-- Load the sprite sheet in test.png using the sprite definitions from spriteData
local spriteSheet = sprite.newSpriteSheetFromData( "test.png", spriteData )

이 경우 밑에 두 줄은 아래와 같이 합칠 수도 있습니다.
local spriteSheet = sprite.newSpriteSheetFromData( "test.png", test.getSpriteSheetData() )

하나의 기본 이미지에 여러 캐릭터들이 들어 있을 때 관련 된 캐릭터들만 따로 세팅을 할 수 있습니다.
spriteSet = sprite.newSpriteSet(spriteSheet, startFrame, frameCount)

sprite에 추가 할 수도 있습니다.
sprite.add(spriteSet, "startFlying", startFrame,frameCount, time,[loopCount])

sprite sheet를 없애고 메모리에서 release시키려면 아래와 같이 합니다.
sprite.Sheet:dispose()
이 경우 removeSelf()도 불려 집니다.

======= o ========== o ========== o ========== o ========= o ===

si = sprite.newSprite( spriteSet )
sprite의 새로운 인스턴스를 만듭니다. 스프라이트는 Display Object입니다. 스프라이트는 한번에 하나의 애니메이션 시퀀스를 플레이 합니다.

si:prepare([sequence])
현재 플레이 되고 있는 애니메이션 시퀀스를 정지합니다. 현재 시퀀스를 바꿀수도 있고 첫번째 시퀀스의 프레임으로 갈 수도 있습니다.

si:play()
애니메이션 시퀀스를 플레이 합니다.현재의 프레임에서 시작합니다.
 
si:pause()
애니메이션을 정지시킵니다. 맨 마지막 display됐던 프레임이 남아 있게 됩니다.
 
si:addEventListener("sprite", listener)
스프라이트 인스턴스 애니메이션이 이벤트를 일으켰을 때 리스너에 통보 합니다.

이벤트는 리스너에게 다음과 같은 필드들을 전달합니다.

event.sprite
이벤트를 발생한 스프라이트; event.sprite.sequence 같이 현재 스프라이트의 프로퍼티들에 접근 할 수도 있습니다.

event.phase
phase는 다음과 같은 요소들이 있습니다.

"end" - 플레이를 멈춘다.
"loop" - 순차적으로 아니면 거꾸로 스프라이트를 루핑합니다.
"next" - 스프라이트의 다음 프레임이 플레이 됩니다.

======= o ========== o ========== o ========== o ========= o ===

여기까지 코로나의 Sprite Sheets로 애니메이션을 구현하는 방법에 대해 알아봤습니다.
근데 뭔가 어렵고 불편한 것 같은 느낌이 드네요.
뭔가 숙달이 안 되서 그런건가?

한번 다양한 방법으로 실습을 해 봐야겠습니다.
샘플을 보던지... 내가 직접 만들던지... 어쨌든 그래야 정확하게 내것이 되겠는데요.

일단 다음 주제는 데이터와 파일 단원에 들어가겠습니다.
SQLite (DB) 와 파일 (file) control도 하게 될 텐데요.

이 주제로 강좌를 진행하다가 sprite sheet 직접 실습해보고 sprite sheet 사용  방법을 알기 쉽게 한번 더 다룰께요.

그럼.......
반응형