'콘솔 게임 프로그래밍'에 해당되는 글 20건


신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

Tag MFC, 소스
출처 : http://romancia.egloos.com/3798728

비쥬얼 아츠쪽에서 만든 avg32기반 게임을 PSP에서 플레이할 수 있는 프로그램입니다.
시험해본결과 3.XX커널에서는 실행이 안되는듯 하지만 백업차원에서 작성해봅니다.
사실 Kanon과 AIR가 PSP로 정식 발매되었기 때문에 큰 의미가 없기도 합니다.
그외 avg32기반의 유명한 게임은 소레치루와 sense off정도군요.

준비물

1.0, 1.5커널이 사용 가능한 PSP

waffle for PSP 프로그램
waffle-psp-050725.zip2005년 7월 25일자 파일입니다.

waffle-040116_psp.zip유저모드로 새로 나온 파일입니다.

avg32기반으로 제작된 게임

일본어 트루타입 폰트

데이터 컨버터 avgcnv07.zip
AVC(변환정의) 파일 avc020803.zip
출처 : http://waffle.bunkasha.co.jp/zau/#WAFFLE

변환법

게임을 인스톨합니다.

데이터 컨버터를 실행시킨 후에 AVC파일중 게임의 제목을 선택한후 게임이 설치된 폴더를 지정하면 데이터를 변환합니다.
게임이 CD-DA를 사용한다면 mp3로 변환하여 track_xx.mp3형식으로 파일명을 지정해줍니다.

설치법

MS0:/PSP/GAME/에 AVG32폴더를 만들어 설치합니다.
주의할점은 GAME150폴더에 설치하면 안됩니다. 또한 폴더명이 다르면 안되는듯 합니다.

일본어 트루타입폰트를 default.ttf로 바꾸어서 avg32폴더에 넣어줍니다.

게임 폴더 설치는 다음과같이 두가지 방법이 있습니다.
[폴더구성]
/PSP/GAME/AVG32
     + BOOT.PBP

     + DEFAULT.TTF
     + WLK2xx.AVD

     + WLK2xx.SAV
     + WLK2xxCD/
       + track_xx.mp3
       + SE_xx.mp3

[또 다른 폴더 구성]
/PSP/GAME/AVG32
    + BOOT.PBP

    + DEFAULT.TTF

    + _AIR/

       + WLK2xx.AVD

       + WLK2xx.SAV
       + WLK2xxCD/
        + track_xx.mp3
둘중 마음에 드는방법으로 하시고 실행이 안되면 다른 방법으로 바꾸어 보세요.

CD-DA를 mp3로 변환한 파일은 WLK2xxCD폴더에 넣으시면 됩니다.

게임 설치된 폴더내에 효과음 파일이 있다면 같은 폴더에 넣어주시면 됩니다.

설치가 다되었으면 실행하시면 됩니다.
신고

'콘솔 게임 프로그래밍 > PSP' 카테고리의 다른 글

와플 for PSP  (0) 2008.09.21
onscripter for PSP  (0) 2008.09.20
Devkit으로 PSP 컴파일하기  (0) 2008.06.12
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소


출처 : http://romancia.egloos.com/3789570


PSP상에서 nscripter엔진 기반의 게임을 실행할 수 있는 프로그램입니다.

준비물

1.0이나 1.5커널이 실행 가능한 PSP

nscripter엔진으로 제작된 게임

예를 들면 이런거(...)

onscripter for PSP 실행파일
onscripter-20080110_psp.zip
2008년 1월 10일에 배포된 파일이며 현재도 가끔씩 업데이트되고 있습니다.
출처는 http://www.geocities.jp/stm_torm/ons/psp.html

C&D Tools Win GUI
onscripter-tools_win.zip
출처는 http://www.geocities.jp/stm_torm/ons/tool.html

일본어 트루타입폰트 파일

추가 준비물

사운드 파일 인코딩 프로그램

%단위로 지정 가능한 그림파일 해상도 일괄 변환 프로그램

일본어가 사용 가능하고 텍스트의 일괄변환이 가능한 편집프로그램

sar혹은 nsa파일 압축 프로그램
nsaarc.exe

nscript.dat파일을 역변환할 수 있는 프로그램
NSDEC.exe

단순변환법

게임을 하드에 인스톨합니다.(경로에 한글이 들어가지 않게 해주세요.)

C&D Tools Win GUI의 압축을 풀어 GUI.EXE파일을 실행합니다.
Input file에 arc.sar파일을 지정합니다.
그러면 Output file이 자동으로 지정됩니다.
파일의 변환이니 Convert에 그대로 체크해두세요.
게임의 해상도와 변환될 해상도를 계산하여 Percentage resize에 지정합니다.
(원본 해상도가 800*600이고 출력될 해상도가 360*270이면 45%입니다.)
소수점 세자리까지 지정 가능하다네요.

변환 가능한 해상도
320x240 : 360x270 : 384x288 : 480x360 : 640x480

360*270을 추천합니다.

용량을 낮추고 싶으시면 BMP to JPEG 옵션에 체크하세요.(확장자는 바꾸지 않으므로 스크립트 수정이 불필요합니다.)
WIDTH even에 체크하시면 출력된 파일의 해상도를 강제적으로 짝수로 맞춥니다. 그림의 어긋나는 현상을 약간 막을 수 있습니다.
JPEG quality에서 화질을 설정합니다. 손실이 적은 80~100을 추천
Start를 누르면 arc_c.sar파일로 변환되어 출력됩니다.
COMDLG32.OCX가 없다고 메시지가 나올경우에는 구글 검색등으로 파일을 구해서 c:\windows\system32 폴더(xp의경우)에 설치해주세요.

그 외에 게임폴더에 이미지가 있는경우 리사이즈해 주세요.

단순설치법

onscripter for PSP파일을 ms0:/PSP/GAME/ 에 폴더를 만들어 복사합니다.

변환된 sar나 nas 파일을 원본 파일명 (ex:arc.sar)으로 바꾸어 복사합니다.

nscript.dat나 0.txt~*.txt파일을 복사합니다.

일본어 트루타입 폰트를 default.ttf로 이름을 바꾸어 복사합니다.

CD-DA를 사용하는 게임의 경우 ogg, mp3, wav로 변환하여 cd라는 이름의 폴더를 만들어 Track02.*** 형식으로 파일명을 바꾸어 복사합니다.

ons.ini파일을 열어서 설정합니다.
RESOLUTION부분만 바꾸어 주셔도 큰 문제는 없을겁니다.

실행
실행결과

심화 변환방법

게임을 하드에 인스톨합니다.

arc.sar등의 파일을 임의의 폴더에 복사한후 GUI.EXE파일을 실행하여 Decode를 선택하여 압축을 풉니다.

이미지 일괄변환 프로그램으로 파일의 해상도를 축소합니다.
용량을 줄이고 싶으시면 jpg파일로 변환하셔도 됩니다.
(원본이 800*600이고 출력 대상이 360*270일 경우 45%로 지정하면 됩니다.)

압축 해제된 사운드 파일을 인코딩 프로그램으로 음질을 낮추거나, 형식을 변환하는게 가능합니다.

변환이 완료되었으면, 파일을 한 폴더에 넣은 상태에서 nsaarc.exe를 실행하여 nsa파일로 압축합니다.
(랙을 줄이려면 사운드파일은 놔두고 그림파일만 압축하셔도 됩니다.)

nscript.dat파일을 nsdec.exe와 같은 폴더에 놓고 nsdec.exe를 실행하면 변환하여 result.txt파일로 나옵니다.

일본어 텍스트 편집기로 result.txt파일을 열어서 파일 변환에 따라 수정합니다.

BMP를 JPG로 변환했을경우 
.bmp > .jpg

BGM의 MIDI를 MP3 or OGG로 변환했을경우
.mid > .mp3or .ogg
playonce " > bgmonce "
play " > bgm "
playstop
> stop

SE의 WAVE를 OGG로 변환했을 경우
.wav > .ogg
wave " > dwave 1,"
waveloop " > dwaveloop 1,"
wavestop >dwavestop 

그 외에 게임폴더에 그림파일이 있을경우 해상도를 변환해 주세요.

심화 설치법

onscripter설치파일을 MS0:/PSP/GAME에 폴더를 만들어 복사합니다.

그림,음악파일을 압축한 arc.nas를 폴더에 복사합니다.

사운드 파일을 nsa에 같이 압축하지 않았다면 폴더 그대로 복사합니다.

result.txt를 0.txt로 파일명을 바꾸어 복사합니다.

일본어 트루타입폰트를 default.ttf로 파일명을 바꾸어 복사합니다.

CD-DA를 사용하는 게임의 경우 ogg, mp3, wav로 변환하여 cd라는 이름의 폴더를 만들어 Track02.*** 형식으로 파일명을 바꾸어 복사합니다.

ons.ini파일을 열어서 설정합니다.
RESOLUTION부분만 바꾸셔도 문제는 없으실겁니다.

실행.

조작법

○:RETURN
×:SPACE
□:CTRL (Skip)
△:ESC (Menu etc...)
L:O (1Page on/off)
R:S (Skip on/off)
START :A (Automode on/off)
SELECT: 0 (Change Speed 2->3->1->2...)
●↑:k (Wheel up)
●↓:j (Wheel down)
http://www.geocities.jp/stm_torm/ons/ons.html를 참고했습니다.
더이상은 물어보셔도 저는 몰라요.
주제별 벨리에는 일부러 안보냅니다.
신고

'콘솔 게임 프로그래밍 > PSP' 카테고리의 다른 글

와플 for PSP  (0) 2008.09.21
onscripter for PSP  (0) 2008.09.20
Devkit으로 PSP 컴파일하기  (0) 2008.06.12
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

음... 아마 이번만 하면.. 솔직히 왠만한 간단한 게임 만들면서 NDS 에 관한 내부 구조 및 코딩방법은 파악이 될듯 싶네요

게임 사운드... 게임을 구성하는데 중요한 요소이지만, 게임 프로그래밍을 배우는 사람들에게 있어서 무시하기 쉬운 부분이기도 합니다.

일단 사운드는.. 함수 자체가 출력.. (방법 정의 ex ) loop 로 돌릴꺼야(배경음), 한번 출력하고 말꺼냐(효과음)) 정도이다 보니, 그래픽을 다루는것에 비해 상당히 간단하죠..
그래서 인지 PAlib 에서도 sound 예제는 상당히 대충 대충.. orz

사운드 삽입하는건 어렵지 않지만 그 방법이 좀 만만치 않습니다. (이거 삽질에 2일 걸렸던..)
일단 기존에 하던거에서 사운드를 출력해서 뭔가... 뭔가.. 좀 있는 느낌을 줘봅시다.

일단 switch 라는 프로그램을 다운로드 합시다.
http://www.palib.info/wiki/doku.php?id=day7ko 에 소개되있는.. 이 라이브러리 제작자가 추천하는 프로그램입니다.
실제 다운로드는 http://www.nch.com.au/switch/ 여기서 합니다.
일단 설치하면.... 아래와 같은게 뜹니다..

사용자 삽입 이미지
자기네 회사꺼 다른 프로그램 더 설치할꺼냐 하는데.. wavepad 는 사운드 편집기로 쓸만합니다.. 나머지는;;; 선택적..

설치가 끝나면 아래와 같은 switch 프로그램이 뜹니다.
사용자 삽입 이미지

이제 NDS에 넣을 음악을 고릅니다.
저는... 몇일전 일본에 가서 겨우 구한 미즈키 나나의 Starcamp 앨범안의 3번 트랙 Dancing in the velvet moon 를 넣어 보겠습니다.
사용자 삽입 이미지

mp3 파일이든 wav 파일이든 만든뒤 switch에 Add Files 버튼으로 추가합니다.
그리고 아래의 Output Format 을 .raw 로, Encoder options... 를 그림과 같이 설정하고 컨버팅 합니다.
사용자 삽입 이미지


컨버팅을 한 뒤 결과물을 project 폴더 내의 data 폴더에 넣습니다.
사용자 삽입 이미지

주의점으로.. 파일을 있는데로 다 끌어 쓰면 안됩니다.
이 NDS 프로그래밍에서는 ROM 파일의 용량이 4MB로 한정 되 있어서 (아무래도 롬파일을 NDS 메모리에 모두 적재 하고 실행시키는 구조인가 봅니다... 참고로 원래 NDS 칩은 128MB 의 용량을 가지고 있습니다)

사운드 파일 크기든, 다 합해서 4MB가 초과 되면 컴파일이 안됩니다.
위의 WavePad 로 적절히 끊어서 저장해서 raw 파일 용량을 줄이던지 해야 합니다.


경험상..  여기 밑에 포스트 되있는 제 졸업작품경우... 그림 + 알고리즘 소스가 1MB, 사운드 3MB 됩니다.
(소스야.. 원래 모바일 WIPI 소스다 보니 최적화를 잘 시켜놔서 별로 용량이 안됩니다)

여하튼...
그 뒤 Visual Stdio 상에서 아래와 같이 사운드 파일을 추가해주고
#include "사운드파일 이름.h" 로 선언해 줍니다.
사용자 삽입 이미지

이후 소스 입니다. 역시 새로 추가한 부분만 빨간색입니다.
//////////////////////////////////////////////////////
// Includes
#include <PA9.h>       // Include for PA_Lib
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"
#include "velvet_moon.h"

#define UP_SCREEN 1
#define DOWN_SCREEN 0

#define BG0   0
#define BG1   1
#define BG2   2
#define BG3   3

#define SPRITE_MENU_PAL  0
#define SPRITE_POINT_PAL 1

#define SPRITE_MENU   0
#define SPRITE_POINT  1

#define TRUE 1
#define FALSE 0

// Video ram 의 모든 그림을 제거 하는 함수
void UnLoad_Screen()
{
 int i;

 for(i=0; i<2; ++i)
 {
  PA_ResetBgSysScreen(i);
  PA_ResetSpriteSysScreen(i);
 }
}

// 현재 출력중인 사운드를 모두 끈다
void UnLoad_Sound()
{
 int i;
 
 for(i=0; i<16; ++i)
  PA_StopSound(i);
}

int main()
{
 PA_Init();    // Initializes PA_Lib
 PA_InitVBL(); // Initializes a standard VBL

 // Init AS_Lib for normal sound playback only
 PA_InitASLibForSounds(AS_MODE_SURROUND | AS_MODE_16CH);

 PA_InitText(UP_SCREEN, BG2);
 PA_OutputSimpleText(UP_SCREEN, 1, 2, "Hello World!");

 // 배경 화면 로드
 PA_EasyBgLoad(UP_SCREEN, BG3, bg2);
 PA_EasyBgLoad(DOWN_SCREEN, BG2, bg_charactor);
 PA_EasyBgLoad(DOWN_SCREEN, BG3, bg1);

 // 스프라이트 준비 1. 팔레트 설정
 PA_LoadSpritePal(DOWN_SCREEN, SPRITE_MENU_PAL, (void*)Sprite_Init_Menu_Pal);
 PA_LoadSpritePal(DOWN_SCREEN, SPRITE_POINT_PAL, (void*)Sprite_Point_Pal);

 // 스프라이트 준비 2. 실제 그림 생성
 PA_CreateSprite(DOWN_SCREEN, SPRITE_MENU,
    (void*)Sprite_Init_Menu_Sprite, OBJ_SIZE_64X64,
    TRUE, SPRITE_MENU_PAL, 10, 10);

 PA_CreateSprite(DOWN_SCREEN, SPRITE_POINT,
    (void*)Sprite_Point_Sprite, OBJ_SIZE_32X32,
    TRUE, SPRITE_POINT_PAL, 80, 10);

 PA_CreateSprite(DOWN_SCREEN, SPRITE_POINT+1,
    (void*)Sprite_Point_Sprite, OBJ_SIZE_32X32,
    TRUE, SPRITE_POINT_PAL, 80, 40);

 // 스프라이트 준비 3. 몇몇 변경
 PA_SetSpriteAnim(DOWN_SCREEN, SPRITE_MENU, 2);
 PA_SetSpriteHflip(DOWN_SCREEN, SPRITE_POINT, TRUE);

 s16 x =0, y = 0;

 AS_SoundDefaultPlay((u8*)velvet_moon, (u32)velvet_moon_size, 127, 64, true, 0);
 // Infinite loop to keep the program running
 while (1)
 {
  // 배경 움직이기
  PA_EasyBgScrollXY(UP_SCREEN, BG3, --x, ++y);
  PA_EasyBgScrollX(DOWN_SCREEN, BG3, x);

  // 스타일러스 팬 위치에 스프라이트를 이동 시키기.
  PA_SetSpriteXY(DOWN_SCREEN, SPRITE_MENU, Stylus.X, Stylus.Y);
  PA_WaitForVBL();
 }

 UnLoad_Screen();  // 리소스 정리
 UnLoad_Sound();
 return 0;
}

//////////////////////////////////////////////////////

음.. 각각 설명입니다..
#include "velvet_moon.h"

위에서 설명되있듯, 사운드 파일이 있음을 컴파일러에게 알려주는 역활을 합니다.
밑의 Makefile 을 분석하시면 대략 아실꺼라 생각합니다.

요약하면, 컴파일러가 저 velvet_moon.h 가 있는지 보고, 당연히 선언이 안되어있으니
raw, jpg, gif ... 등 확장자를 바꿔가면서 /data/ 디렉토리에 해당 파일이 있는지 봅니다.
그리고 관련된 파일 (raw 파일 있으니 이거겠죠..)이 있으면 파일이름.h 헤더를 생성하고
거기에 대략 맞는(선언 위주의) 헤더를 생성합니다.

// 현재 출력중인 사운드를 모두 끈다
void UnLoad_Sound()
{
 int i;
 
 for(i=0; i<16; ++i)
  PA_StopSound(i);
}
위 소스는 제가 만든겁니다.
현 게임 상황에서 다음 게임 상황 (Menu state 에서 Game state 로 넘어갈때) 사운드가 바뀌지 않아
아예 다 꺼버리는 매크로 같은겁니다.
(즉.. 사운드는 0~15번까지 각각 재생이 된다는거라 생각합니다만.. 확실치는... orz
다만 0~7번이 효과음, 8~15번이 배경음 으로 지정되 있는거 같습니다)

 PA_InitASLibForSounds(AS_MODE_SURROUND | AS_MODE_16CH);
이 소스는 사운드를 출력할태니 준비하라는 초기화 API 입니다.
당연히 이걸 선언 안하면 사운드가 출력이 안되겠죠.

 AS_SoundDefaultPlay((u8*)velvet_moon, (u32)velvet_moon_size, 127, 64, true, 0);
위 소스로 사운드를 실행 시킵니다.
대략 AS_SoundDefaultPlay( (u8*) 사운드 파일 이름,
                                       (u32) 사운드 파일 이름_size,
                                       127, 64  (사운드 화음 같은거 같네요..)
                                        true, (이건 루프를 돌릴껀지 선택하는겁니다),
                                        0);
음... 사운드 파일 이름은.. 위에서 컴파일러가 자동으로 만들어 주는 "사운드파일.h" 에 선언되 있습니다.
그런이유로 컴파일 에러가 나진 않죠..

여튼 컴파일 해서 이상이 없으면 아래와 같은 전에 했던 작업에
사운드 파일이 재생되는것을 들으실 수 있습니다.

사용자 삽입 이미지

음.. 대략.. 이걸로 환경조성하고, 배경띄우고, 스프라이트 조작하고, 사운드를 넣어보았습니다.
기본적으로 NDS 게임 프로그래밍은 이거를 조금더 풀어쓴다고 생각하시면 될꺼 같네요
(여기 있는게, MFC 같은 캡슐화된 메소드들이고, 실제는 여기서 좀 풀어쓴 API 급 정도..)

게임의 기본 루프는

fn_game1()
{
     // 메모리 청소 및 초기화
     ...
 
     // 화면에 띄울것 메모리에 Load
     ...

     // 게임 알고리즘 셋팅
     ...

     while( 탈출 변수 )
     {
           // 화면 움직임 처리
           ...
           //  입력 감지 및 처리
           switch(입력?)
           {
                 case 1 :  fn_game_1();  break;
                 case 2 :  fn_game_2();  break;
                 .....
            }
      }
       // 메모리 청소
}

등으로 구성 됩니다.
이 정도면.. 간단한 2D 정도는 문제 없을꺼라 생각되네요.

신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소

잠시.. 일본에 갔다와서 연재 시기가 늦었습니다. >_<..

음.. 저번에 했던건 배경 그림 컨트롤 하는것 인데, 이번엔 게임 플레이어가 직접 뭔가 어떻게 할 수 있는 대상
즉, 오브젝트 그림들... 통칭 스프라이트를 띄우는 방법에 대해서 이야기 하겠습니다.

일단 스프라이트 개념은.. 대충 저런 느낌이구요.. 슈퍼 마리오 게임을 예로 들면,
마리오, 필드의 몹들, 부실 수 있는 벽돌, 장애물... 등을 말 할 수 있겟죠...

일단... 스프라이트 제약 사양입니다.

아래표의 스프라이트 사이즈만 사용가능

사용자 삽입 이미지

각각 가로 세로 길이이며 256색 이하 bmp 그림

단위는 당연히 픽셀이며, 딱 저것만 가능합니다. 각각 가로 세로 8의 배수로 생각하시면 될꺼 같네요.
이 이상 크기는.. 확대 하는 함수를 사용해서 최대 128x128 크기까지 뽑아 낼 수 있습니다.

하지만 저 정도 크기이면 NDS 화면 해상도가... 256x192 크기임을 가만하면... 저런 케릭 2개만 있어도
화면 가득 메워 버리므로... 적절한 크기는 64x64 정도로 잡은거 같습니다.

여튼... 예제 스프라이트 이미지 입니다.

사용자 삽입 이미지
<Sprite_Init_Menu.bmp>

사용자 삽입 이미지
<Sprite_Point.bmp>
파일은 여길 누르세요

한가지 주의점은.. 스프라이트는 위와 같이 세로 방향으로 넣어 주셔야 합니다.
왜 저렇게 해야 하면, NDS 자체가 성능이 많이 딸려서 라고 추정됩니다.
좀더 빠른 메모리 접근 이유가 타당하겠네요.

예를들어 가로로 그림을 배치 한다면..

  000111222333444555666777888999
  000111222333444555666777888999
  000111222333444555666777888999

와 같이 메모리 배열이 있고, 2번으만 되어있는 프레임을 긁어올려면 첫 배열에서 x*3(넓이)*2(프레임)에서 프레임 넓이, 다음 줄 그림 읽기 위해 넓이를 더하고, 다시 메모리에 붙이고 ......

하지만 그림을 세로로 할 경우
000
000
000
111
111
111
222
222
222
....
즉...
000000000111111111222222222 ..... 식으로 메모리에 배열이 되겠죠.
그럼 이미지를 가져올때 필요한 정보는 스프라이트 넓이와, 프레임 번호만 있으면 이후 별도 연산은 안해도 되는것이죠.

음.. 뭐 요지는... 세로로 해야 제대로 스프라이트가 나옵니다.
스프라이트를 추가시키기 위해선 배경 그림 컨버팅 한것 처럼 PAGfx안의 프로그램을 사용해서 컨버팅 합니다.

사용자 삽입 이미지
그림 설명대로, sprite 탭에서 스프라이트 그림을 로드 한뒤에 컨버팅 합니다.
이때 주의점... 배경 그림도 같이 변환해야 합니다.

사용자 삽입 이미지

왜냐면.. 결과 파일로 all_gfx.c/h 파일이 만들어 지는대 여기에서 모든 그림 리소스 변수명을 정의하기 때문입니다.
스프라이트만 해놓으면, 배경 그림 변수가 빠진 all_gfx.h 파일이 만들어지므로, 배경 그림을 못찾는다거나 하는 문제가 발생할 수 있습니다.

여튼... 만들어진 파일을, 저번과 같이 프로젝트/source/gfx 안에 덮어 씌웁니다.
사용자 삽입 이미지


이후... 소스는 아래와 같이 수정 합니다.


//////////////////////////////////////////////////////
// Includes
#include <PA9.h>       // Include for PA_Lib
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"

#define UP_SCREEN 1
#define DOWN_SCREEN 0

#define BG0   0
#define BG1   1
#define BG2   2
#define BG3   3

#define SPRITE_MENU_PAL  0
#define SPRITE_POINT_PAL 1

#define SPRITE_MENU   0
#define SPRITE_POINT  1

#define TRUE 1
#define FALSE 0

// Video ram 의 모든 그림을 제거 하는 함수
void UnLoad_Screen()
{
 int i;

 for(i=0; i<2; ++i)
 {
  PA_ResetBgSysScreen(i);
  PA_ResetSpriteSysScreen(i);
 }
}

int main()
{
 PA_Init();    // Initializes PA_Lib
 PA_InitVBL(); // Initializes a standard VBL

 PA_InitText(UP_SCREEN, BG2);
 PA_OutputSimpleText(UP_SCREEN, 1, 2, "Hello World!");

 // 배경 화면 로드
 PA_EasyBgLoad(UP_SCREEN, BG3, bg2);
 PA_EasyBgLoad(DOWN_SCREEN, BG2, bg_charactor);
 PA_EasyBgLoad(DOWN_SCREEN, BG3, bg1);

 // 스프라이트 준비 1. 팔레트 설정
 PA_LoadSpritePal(DOWN_SCREEN, SPRITE_MENU_PAL, (void*)Sprite_Init_Menu_Pal);
 PA_LoadSpritePal(DOWN_SCREEN, SPRITE_POINT_PAL, (void*)Sprite_Point_Pal);

 // 스프라이트 준비 2. 실제 그림 생성
 PA_CreateSprite(DOWN_SCREEN, SPRITE_MENU,
    (void*)Sprite_Init_Menu_Sprite, OBJ_SIZE_64X64,
    TRUE, SPRITE_MENU_PAL, 10, 10);

 PA_CreateSprite(DOWN_SCREEN, SPRITE_POINT,
    (void*)Sprite_Point_Sprite, OBJ_SIZE_32X32,
    TRUE, SPRITE_POINT_PAL, 80, 10);

 PA_CreateSprite(DOWN_SCREEN, SPRITE_POINT+1,
    (void*)Sprite_Point_Sprite, OBJ_SIZE_32X32,
    TRUE, SPRITE_POINT_PAL, 80, 40);

 // 스프라이트 준비 3. 몇몇 변경
 PA_SetSpriteAnim(DOWN_SCREEN, SPRITE_MENU, 2);
 PA_SetSpriteHflip(DOWN_SCREEN, SPRITE_POINT, TRUE);

 s16 x =0, y = 0;

 // Infinite loop to keep the program running
 while (1)
 {
  // 배경 움직이기
  PA_EasyBgScrollXY(UP_SCREEN, BG3, --x, ++y);
  PA_EasyBgScrollX(DOWN_SCREEN, BG3, x);

  // 스타일러스 팬 위치에 스프라이트를 이동 시키기.
  PA_SetSpriteXY(DOWN_SCREEN, SPRITE_MENU, Stylus.X, Stylus.Y);
  PA_WaitForVBL();
 }

 UnLoad_Screen();  // 리소스 정리
 return 0;
}

//////////////////////////////////////////////////////


바뀐곳만 빨간색을 칠했습니다.
일단 정의 부분
#define SPRITE_MENU_PAL  0
#define SPRITE_POINT_PAL 1

#define SPRITE_MENU   0
#define SPRITE_POINT  1

#define TRUE 1
#define FALSE 0


각 스프라이트의 팔레트 번호와, 스프라이트 번호 그리고 true, false 값의 정의입니다.
왜 저짓을 하냐면... 숫자로 그냥 둘 경우 나중에 스프라이트 더 추가 하거나 할때 상당히 햇갈립니다.

다음
 // 스프라이트 준비 1. 팔레트 설정
 PA_LoadSpritePal(DOWN_SCREEN, SPRITE_MENU_PAL, (void*)Sprite_Init_Menu_Pal);
 PA_LoadSpritePal(DOWN_SCREEN, SPRITE_POINT_PAL, (void*)Sprite_Point_Pal);

이건 뭐냐면... 팔레트 생성 입니다. 위의 define 한거에 따라 팔레트 번호를 배당하고,
뒤의 (void*)Sprite_Init_Menu_Pal 은 팔레트 변수명 입니다.
팔레트 변수는 [그림파일_Pal] 로 컨버팅시 정의 됩니다.

다음
 // 스프라이트 준비 2. 실제 그림 생성
 PA_CreateSprite(DOWN_SCREEN, SPRITE_MENU,
    (void*)Sprite_Init_Menu_Sprite, OBJ_SIZE_64X64,
    TRUE, SPRITE_MENU_PAL, 10, 10);

 PA_CreateSprite(DOWN_SCREEN, SPRITE_POINT,
    (void*)Sprite_Point_Sprite, OBJ_SIZE_32X32,
    TRUE, SPRITE_POINT_PAL, 80, 10);

 PA_CreateSprite(DOWN_SCREEN, SPRITE_POINT+1,
    (void*)Sprite_Point_Sprite, OBJ_SIZE_32X32,
    TRUE, SPRITE_POINT_PAL, 80, 40);

스프라이트를 생성하는 부분 입니다.
총 3개의 스프라이트가 나옵니다.
각각 인자값은,
생성할 위치 스크린 번호,
할당시킬 스프라이트 번호 (중복없이 한 화면 최대 128개)
스프라이트 그림 변수로서.. [그림파일_Sprite]로 자동 할당,
스프라이트 크기
이 스프라이트가 256 색인가?
이 스프라이트가 사용할 팔레트 번호
처음 생성될때의 x, y 위치

입니다.

다음..
 // 스프라이트 준비 3. 몇몇 변경
 PA_SetSpriteAnim(DOWN_SCREEN, SPRITE_MENU, 2);
 PA_SetSpriteHflip(DOWN_SCREEN, SPRITE_POINT, TRUE);

이 함수는
각각, SPRITE_MENU 번호의 스프라이트의 2번 프레임을 표시하라와
SPRITE_POINT 를 좌우대칭(Hflip) 시켜라 라는 의미 입니다.

다음 while 루프 안에
// 스타일러스 팬 위치에 스프라이트를 이동 시키기.
  PA_SetSpriteXY(DOWN_SCREEN, SPRITE_MENU, Stylus.X, Stylus.Y);


는 스프라이트 x,y 이동시키는 함수로서 (이 말은 x만, y 만 전용 움직이게 하는 함수도 있습니다)
스프라이트 있는 곳의 화면 번호
스프라이트 번호
Stylus 는 스타일러스 상태를 가져오는 매크로 같은 것이라.. 현재 정의는 X,Y 값을 가져오는것 입니다.
 

이후 컴파일 하면 아래와 같이 나오며
아래 스크린을 마우스로 클릭해서 끌어 보면, 카드 스프라이트가 마우스로 끄는 위치로
쫏아감을 느낄 수 있습니다.

사용자 삽입 이미지

음.. 대략 이런 느낌으로 하면 됩니다.
좀더 자세한건 C:\devkitPro\PAlibExamples\Sprites 안의 여러 예제 소스들과 (상당히 간단합니다)
http://www.palib.info/wiki/doku.php?id=day3ko 부분을 병행해서 보시면 될꺼 같습니다.

음.. 이것으로 2D 이미지를 띄우는 방법은.. 다 됬네요.
게임은 솔직히 이것 만으로도 만들어 지고, 남은건 알고리즘 재량 정도가 아닐까 싶네요 >_<..

신고
블로그 이미지

프로그래머 지향자 RosaGigantea

바쁜 일상 생활중의 기억 장소