[XNA] 스프라이트를 이용한 애니메이션 구현

2012. 4. 26. 23:16IT, Smart Life

이전 XNA 관련 글 보기





Sprite-based Animation


  단일 이미지의 단순 화면 출력을 해봤으니, 이번에는 여러 장의 이미지를 연속으로 보여줌으로써 연속된 동작처럼 보이게 하는 스프라이트 애니메이션(Sprite-based Animation)을 시도해보겠습니다.


  스프라이트(sprite)는 연속된 이미지의 변화로 캐릭터 등에 애니메이션 효과를 나타낼 때 사용합니다. 

  2D 아케이드 게임 속에 등장하는 캐릭터 동작의 대부분은 스프라이트 애니메이션입니다.


  XNA에는 감히! 스프라이트 처리를 위해 준비된 별도의 클래스가 없기 때문에 스프라이트 처리르 위한 클래스를 직접 만들어야 된다고 합니다.(What!!? -_- )


  당연히, 한번만 쓰고 끝낼 기능이 아니기 때문에 별도의 클래스를 제작해둬야겠네요.

  아무튼 시키는대로 해봅니다.



  이번 프로젝트는 크게 아래와 같이 3개의 클래스와 불러들일 이미지들로 구성됩니다.

  





Program.cs  

프로그램 구동시 제일 먼저 불려와서 게임을 Run을 시킵니다.


Game1.cs

게임 화면의 크기, 배경색을 비롯한 게임 전반적인 환경 설정 및 초기 이니셜라이즈(Initialize() 함수)를 시킵니다. 실제적인 게임 진행에 필요한 것들을 정의하고, 이번 포스팅에서 사용하고자 하는 이미지를 로드(LoadContent())하고, 그리기 명령(Draw())을 포함하고 있습니다.


Sprite.cs

앞서 말했듯이, XNA 자체에서는 스프라이트 효과를 주는 함수가 지원되지 않기 때문에, sprite()함수를 별도로 만들고, Game1.cs에서 Upload된 컨텐츠(이미지)를 연속해서 불러서 그리는 Draw() 함수를 정의 해 둡니다.





Sprite.cs 코딩


  Sprite.cs 함수에 들어가 있는 핵심 내용은, 이미지 정보(이미지 텍스처의 개수, 테스처의 가로, 세로 크기)를 불러와서, i 번째 이미지를 출력하는 것입니다.


[ Sprite.cs 코드 보기 ]





  i.ToString("D4")는 숫자 i를 00XX 형식의 문자열로 바꿔주는 역할을 합니다.

  이런 변환이 필요한 이유는 Game1.cs에서 이미지를 불러올 때, 파일명이 비행0001, 비행0002, ...., 비행0015 이렇게 되어 있기 때문입니다. 읽어들이는 이미지 파일의 파일명 형식에 맞춰준 거죠.

  그리고 'Vector2 pt'는 이미지 출력 위치 좌표를 말합니다.

[ i.ToString("D4") 예시 ]







Game1.cs 코딩

  Game1 클래스에서는 Sprite를 하나 선언하고,

### csharp
Sprite sp = new Sprite();


  Sprite 클래스의 Load() 함수를 이용해서 16장의 비행00XX 이미지들을 로드합니다.

###csharp
sp.Load(Content, "비행", 15); // 16장의 이미지를 로드한다. (비행0000~비행0015)


  그리고 Sprite 클래스의 Draw() 함수를 이용해서 이미지들을 불러와서 출력하는 시간간격과 이미지의 출력 위치, 색깔 등을 정의합니다.

###csharp
sp.Draw(spriteBatch, (int)(gameTime.TotalGameTime.TotalMilliseconds / 50) % sp.Count(), new Vector2(330, 200), Color.White);

  위 코딩에서 TotalMilliseconds / (숫자) 이 부분의 숫자를 바꾸면 이미지를 그리는 시간 간격을 조절할 수 있으므로, 애니메이션 속도를 조절할 수 있습니다. Vector2( , )는 이미지를 출력할 위지(position)을 나타냅니다. 그리고 Color.(White)에서 색깔 부분을 바꾸면 이미지에 지정한 색을 입히게 됩니다.

왼쪽 부터, Color.White / Color.Aqua / Color.Pink




[ Game1.cs 코드 보기 ]





F5 : Start Debugging

  '안돌아가는 훌륭한 프로그램보다, 돌아가는 조악한 프로그램이 낫다.'라는 말이 있죠.
  아무렇게 코딩해도 좋다는 말은 아니지만, 그래도 역시 디버깅을 했을 때, 에러가 나는 것 보다 돌아가는 걸 보는 게 훨씬 기분 좋습니다. ^__^


  우선, 16장의 이미지를 그대로 다 사용한 경우입니다.
  비행기가 좌우로 반복해서 롤링(Rolling)을 하는데, 이상하게 다시 중심으로 올때, 끊기는 것 같습니다.
  소스로 사용하신 이미지들을 한장씩 보시면, 이미지 첫장과 이미지 마지막장이 거의 동일한 비행기 이미지를 나타내는데, 이때문에 애니메이션이 약간 부자연스러워 보입니다.



이미지 16장을 모두 사용한 경우의 결과



  아래는 제일 마지막 이미지(비행0015)를 삭제하고, 코딩도 15장만 불러들이도록 수정한 결과 화면입니다.

  완전히 만족할 수는 없지만, 그래도 조금 더 낫네요~ ^____^ 

  자연스럽게 연결되는 애니메이션 소스가 중요하다는 것과, 반복문을 돌릴 때, 첫 이미지와 마지막 이미지가 동일하면, 동일한 화면을 두번 그리게 되니까 조심해야 된다는 교훈을 얻었네요~




마지막 이미지를 제외한 15장의 이미지를 사용한 경우의 결과



  시간이 많이 없어 실습이 더디지만, 재밌네요 ^__^

  

  다음은 스프라이트 애니메이션을 구현하는 코드를 다른 이미지 소스에도 계속 사용할 수 있도록,

  스프라이트 매니저 클래스를 만들어 보겠습니다!! 




SPACECHILD_XNA_Proto1.zip




Reference // 톡톡튀는 XNA를 이용한 단계별 슈팅게임 만들기

톡톡튀는 XNA를 이용한 단계별 슈팅게임 만들기
국내도서>컴퓨터/인터넷
저자 : 최창수,서정만
출판 : 도서출판정일 2011.08.25
상세보기