본문 바로가기

Study/Engine

[SDL Tutorial] Lesson 6 - 스프라이트(Sprite)



 안녕하신가요? 오늘은 SDL에서 스프라이트를 사용하는 방법에 대해 강의할 것입니다. 조금만 더 배우시면 게임을 만들 수 있겠군요. 아마도 말이지요 ^^

 강의에 앞서, 기존에 포스팅된 강의를 보고싶으시면 카테고리에서 Programming/SDL 을 방문해주시기 바랍니다.


6 - 1 : Sprite!

 스프라이트란 뭘까요?

사용자 삽입 이미지

출처 : Lazy Foo' Productions



 이런 이미지가 있습니다. 보통 이런 이미지를 스프라이트라고 하지요. 연관된 여러 이미지를 하나의 이미지에 담아서 쓰는 게 대부분이지요. 물론 사용자의 마음대로 해도 되겠지만, 공통된점은 여러 이미지를 하나에 모아놓은 것이지요. 편하게 쓰려면 형식을 맞춰야겠지요. 저 위의 이미지처럼 말이죠. 가령,

사용자 삽입 이미지


 이런 이미지가 있으면 처음과 끝 이미지가 다르다고 위치를 바꿔버리면 곤란하겠지요. 물론 저런 단순한 스프라이트의 경우엔 스프라이트로 할 필요도 없겠지요. 그냥 그림 하나 띄우고 위아래로 움직여주면 그만이니까요. 다만 이 경우엔 프로그래머가 귀찮아하겠지요 ^^; 어쨌든 두번째 그림의 경우엔 주로 애니메이션에 쓰이고, 첫번째 그림은 정적인 연관된 그림에 쓰입니다.

사용자 삽입 이미지


 이런식으로 말이지요. 위의 그림은 제가 한창 날아라 슈퍼보드 환상서유기를 리눅스로 포팅하는 작업에 쓰였던 것입니다. 물론 저 그림의 용도는 타일이었습니다만 ^^; 일단 대체적인 타일의 용도에 대해 알아봤습니다.


6 - 2 : 스프라이트를 프로그램에 적용시키기

사용자 삽입 이미지


 스프라이트에 대해 얘기할 때 썼던 이미지를 이용한 예제입니다. 이미지에는 4개의 점들이 한곳에 모여서 붙어있었는데, 이 점들을 창 구석에 하나씩 놓아볼 것입니다. 이번에도 소스코드 전체를 쓰진 않을 것이오니, 적절히 수정하실 분께서는,



 여기에서 지난 강의 소스코드를 받아주시기 바랍니다. 이번 강의의 완성본을 보고싶으시면 이 포스트의 맨 아래에 있는 첨부파일을 받아주시기 바랍니다.

// Surface
SDL_Surface *dots = NULL;
SDL_Surface *screen = NULL;

// 이번에 쓸 event 구조체
SDL_Event event;

// 스프라이트 이미지 내의 점 좌표를 입력할 변수 
SDL_Rect clip[ 4 ];


 dots라는 변수에 4개의 점이 담긴 스프라이트 이미지를 불러올 것입니다. 그러기 전에 전역으로 선언했습니다.

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect *clip = NULL )
{
    // 임시 사각형 선언
    SDL_Rect offset;

    // offset을 설정해준다
    offset.x = x;
    offset.y = y;

    // 화면으로 출력해준다
    SDL_BlitSurface( source, clip, destination, &offset );
}


 이번 강의에서 apply_surface에 추가된 것은 SDL_Rect라는 인자의 추가와 SDL_BlitSurface시에 SDL_Rect형으로 받은 clip을 넣어준 것입니다. 여기에서 선언시에 clip = NULL을 해주었는데, 이렇게 해두면,

apply_surface(0, 0, image, screen, NULL);


 이렇게하거나

apply_surface(0, 0, image, screen);


 을 해도 똑같은 효과가 있다는 뜻이 됩니다. 뭐 이런거야 C/C++ 배우시면서 습득하셨으리라 믿습니다.

    // clip에서 위의 왼쪽에 있는 점 좌표 
    clip[ 0 ].x = 0;
    clip[ 0 ].y = 0;
    clip[ 0 ].w = 100;
    clip[ 0 ].h = 100;
   
    // clip에서 위의 오른쪽에 있는 점 좌표 
    clip[ 1 ].x = 100;
    clip[ 1 ].y = 0;
    clip[ 1 ].w = 100;
    clip[ 1 ].h = 100;
   
    // clip에서 아래의 왼쪽에 있는 점 좌표 
    clip[ 2 ].x = 0;
    clip[ 2 ].y = 100;
    clip[ 2 ].w = 100;
    clip[ 2 ].h = 100;
   
    // clip에서 아래의 오른쪽에 있는 점 좌표
    clip[ 3 ].x = 100;
    clip[ 3 ].y = 100;
    clip[ 3 ].w = 100;
    clip[ 3 ].h = 100;


 main함수에 위의 코드를 넣어주시기 바랍니다. 아까도 보셨던

사용자 삽입 이미지


 이 그림에서의 각 점의 좌표를 배열에 넣은 것입니다. 위처럼 코드를 넣으셨다면, 각 점들은

사용자 삽입 이미지

출처 : Lazy Foo' Productions



 이런식으로 설정될 것입니다.

    // 화면을 흰색으로 칠하기 
    SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF ) );


 화면을 흰색으로 채우기 위해서 SDL_FillRect라는 함수를 사용할 것입니다. 이 함수는 지정한 화면에 사각형의 틀에 특정한 색으로 출력해줍니다. 첫번째 인자에는 그려질 곳(surface)를 넣고, 두번째에는 크기와 위치를 담은 SDL_Rect값이 들어갑니다. 여기에서는 screen의 rect값이 들어갔습니다. 세번째 인자값은 색상을 설정합니다.

    // 화면에 출력
    apply_surface( 0, 0, dots, screen, &clip[ 0 ] );
    apply_surface( 540, 0, dots, screen, &clip[ 1 ] );
    apply_surface( 0, 380, dots, screen, &clip[ 2 ] );
    apply_surface( 540, 380, dots, screen, &clip[ 3 ] );

    // 화면 갱신
    if( SDL_Flip( screen ) == -1 )
    {
        return 1;
    }


 이제 화면으로 출력을 해줍니다. 따로따로 표시되는 것을 확실하게 하기 위해서 서로 멀리 떨어져서 출력하게 좌표를 입력해두었습니다. 그리고 clip은 main함수의 시작부분에 값을 입력해두었으니 그래도 될 것입니다.

 중요한 추가부분은 모두 완료했습니다. 나머지 자잘한 것들은 스스로 바꾸실 줄 아시리라 믿습니다. 여기까지 왔는데 그정도는 하셔야지요!^^ 파일을 불러온다던가 불러온 파일을 메모리에서 해제한다던가 등등은 이제까지 계속 반복해온 일이기도 하니까요. 예제도 끝났고, 오늘의 강의는 여기까지 하겠습니다.

 오늘 했던 소스코드를 받고싶으시면,



 이 파일을 받아주시기 바랍니다.

 다음 강의는 글꼴에 대해 해보겠습니다. 우리가 설치한 SDL_ttf를 사용할 건데, 이 라이브러리에서는 한글을 지원하지 않는 것 같습니다. 언제 시간나면 Lesson 7의 외전(?)격으로 다뤄볼 생각입니다.


- Lesson 6를 마무리하며...

 전 처음에 스프라이트라는 개념을 잘 이해하지 못했던 것 같습니다. 지금이야 자주 쓰니까 너무도 당연한듯이 쓰지만, 처음 접하는 분들께는 너무도 어려울지도 모릅니다. 제 경험으로는, 프로그래밍할 때 모르면 반복해서 예제를 코딩해보는 수 밖에 없습니다. 아니면 수치를 변경해서 어떻게 동작하는지 원리를 알아가는게 무식해보여도 확실한 방법이라 생각합니다. 100번 말해봐야 한번 직접해보는게 훨씬 낫지요. 저도 열심히 노력해야할 것 같군요 ^^