DX라이브러리2014. 12. 24. 12:35

3.2 나눗셈 나머지를 이용한 루프


게임 제작시에 루프처리를 매우 많이 사용한다. 예를 들어 0-1-2-3-0-1-2-3.......같은 흐름의 루프들이다. 다음과 같이 루프시키는 방법도 있지만,


int x = 0;

while( ... ){

  x++;

  if( x == 3 ){

    x = 0;

  }

}


나눗셈의 나머지를 사용하면 좀더 간단하게 구현이 가능하다.


int x = 0;

while( ... ){

  x = ( x + 1 ) % 4

}


x의 값은 다음과 같다.


0-1-2-3-4-5-6-7-8-9.....

0-1-2-3-0-1-2-3-0-1.....


이를 활용한 예제를 확인해보자.


#include <DxLib.h>


int Key[256];



int gpUpdateKey(){

char tmpKey[256];

GetHitKeyStateAll( tmpKey );

for( int i=0; i<256; i++ ){ 

if( tmpKey[i] != 0 ){

Key[i]++;

} else {

Key[i] = 0;

}

}

return 0;

}


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        int Count = 0; // 카운트를 위한 변수 선언

        int Handle = LoadGraph("image/character_01.png");


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){


                DrawGraph(   0, Count% 50, Handle, TRUE ); // 50을 주기로 루프

                DrawGraph( 100, Count%100, Handle, TRUE ); // 100을 주기로 루프

                DrawGraph( 200, Count%150, Handle, TRUE ); // 150을 주기로 루프


                Count++; // Count 1씩 증가


        }


        DxLib_End();

        return 0;

}


실행결과




Posted by 캡슐리어
DX라이브러리2014. 12. 24. 12:09

3.1 키 입력에 대응해서 캐릭터를 움직여보자


기본적인 처리방식은


if( 방향키"상"이 입력되었다. ){

  캐릭터를 위로 움직인다.;

}


를 기본 구조로 하여 상,하,좌,우 모두 처리해주면 되겠다.


사용예제


#include <DxLib.h>


int Key[256];


int gpUpdateKey(){

char tmpKey[256];

GetHitKeyStateAll( tmpKey );

for( int i=0; i<256; i++ ){ 

if( tmpKey[i] != 0 ){

Key[i]++;

} else {

Key[i] = 0;

}

}

return 0;

}


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        int x=320, y=240;

        int Handle = LoadGraph("image/character_01.png");


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){


                if( Key[ KEY_INPUT_RIGHT ] >= 1 ){ // "우" 입력

x++;                       // 오른쪽 이동

}

if( Key[ KEY_INPUT_DOWN  ] >= 1 ){ // "하" 입력

y++;                       // 아래 이동

}

if( Key[ KEY_INPUT_LEFT  ] >= 1 ){ // "좌" 입력

x--;                       // 왼쪽 이동

}

if( Key[ KEY_INPUT_UP    ] >= 1 ){ // "상" 입력

y--;                       // 위로 이동

}


DrawRotaGraph( x, y, 1.0, 0.0, Handle, TRUE );


}


DxLib_End();

return 0;

}


실행결과




이와같이 게임프로그램은 계산부분과 묘화부분으로 구분 가능하다.



계산 구문에서 캐릭터의 좌표등을 계산하고 묘화 구문에서 계산이 완료된 좌표에 따라 이미지를 처리하는 것이 일반적이다. 게임을 제작하다보면 계산부분만 스킵한다던가 반대로 묘화부분만 스킵하는 경우가 있기 때문에 이부분은 다음 예제와 같이 명확하게 구분 지을 필요가 있다.


#include <DxLib.h>


int Key[256];


int gpUpdateKey(){

char tmpKey[256];

GetHitKeyStateAll( tmpKey );

for( int i=0; i<256; i++ ){ 

if( tmpKey[i] != 0 ){

Key[i]++;

} else {

Key[i] = 0;

}

}

return 0;

}


int x=320, y=240;

int Handle;


void gpCalc(){    //좌표 계산을 위한 별도 함수

if( Key[ KEY_INPUT_RIGHT ] >= 1 ){

x++;

}

if( Key[ KEY_INPUT_DOWN  ] >= 1 ){

y++;

}

if( Key[ KEY_INPUT_LEFT  ] >= 1 ){

x--;

}

if( Key[ KEY_INPUT_UP    ] >= 1 ){

y--;

}

}


void gpDraw(){ // 이미지 묘화를 위한 별도 함수

        DrawRotaGraph( x, y, 1.0, 0.0, Handle, TRUE );

}


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        Handle = LoadGraph("image/character_01.png");


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){


                gpCalc();


                gpDraw();


}


DxLib_End();

return 0;

}


실행결과는 위의 예제와 동일하다.

'DX라이브러리' 카테고리의 다른 글

3.3 간단한 선택화면  (0) 2014.12.24
3.2 나눗셈 나머지를 이용한 루프  (0) 2014.12.24
2.9 키 입력  (0) 2014.12.23
2.8 이미지를 분할하여 로드  (0) 2014.12.23
2.7 효과음 재생  (0) 2014.12.23
Posted by 캡슐리어
DX라이브러리2014. 12. 23. 16:06

2.9 키 입력


키 입력 여부가 관련된 함수는 있지만 키가 얼마나 오랫동안 눌려 있는지 감수하는 함수는 없다. 때문에 이부분은 직접 코딩하여 실현해야 한다. 아래의 그림과 같이 게임의 메뉴 선택시 방향키를 눌러 한개씩 이동해야 하는 경우에 이와 같은 처리를 하게 된다.



만약 다음과 같은 예제를 통하여 구현하면


while(1){

  if(  방향키 "하"가 입력되었다. ){

    선택항목에서 아래로 한칸 내린다.;

  }

}


while문은 1초에 60번 동작하기 때문에 엄청난 속도(1초에 60번의 속도)로 메뉴 이동을 하게 된다. 잠깐만 눌렀다고 하더라도 자신이 원하는 메뉴를 선택하기가 매우 힘들어진다.


다음 예제를 통하여 확인 해보도록 하자.


#include <DxLib.h>


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        int x=0;


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){


                DrawFormatString( x, 0, GetColor(255,255,255), "?!" );


                if( CheckHitKey(KEY_INPUT_RIGHT) != 0 ){

                        x = x + 50;

                }


        }


        DxLib_End();

        return 0;

}


오른쪽 방향키를 누르게 되면 "?!"문자가 오른쪽으로 움직이는데 한칸씩이 아니라 매우 빠른 속도로 움직이는것을 볼 수 있다. 그렇다면 입력을 받은 시간만큼이 아니라 입력 받은 순간을 입력받 고서 1프레임 째로 한정하여 처리하면 되겠지만 DX라이브러리에서 제공하는 기본 함수만으로는 이부분이 불가능하다. 때문에 이 함수를 만들어보도록 한다. 먼저 키 입력 상태를 감지하는 GetHitKeyStateAll함수에 대해 알아본다. 레퍼런스는 여기를 확인.


선언

 int GetHitKeyStateAll( char *KeyStateBuf ) ;

기능

 키보드의 모든 키 입력 상태를 감지

인수

 char *KeyStateBuf : 키 입력 상태를 저장하는 포인터


지금까지 CheckHitKey함수를 사용했지만 많은 키를 확인하고 싶다면 위 함수를 사용한다. 인수에 반환하는 변수는 키 입력상태를 보존하기 위해 char형 배열로 선언한다. 키는 전부 256종류가 있으며 다음 예제처럼 사용하게 된다.


char key[256];

GetHitKeyStateAll( key );


함수를 호출하면 키코드에 따라 키의 입력 상태를 저장하게 된다. 각 키에 대응하는 키코드는 다음 표와 같다.



예를 들면 Z키를 감지하기 위해선


if( key[ KEY_INPUT_Z ] != 0 ){

}

가 된다.


그럼 위에서 언급했던 "몇 프레임이나 입력되었는가" 를 계산하는 함수를 만들어보자. 함수의 이름은 gpUpdateKey함수로 한다. 전역변수 int Key[256];을 선언하고 메인 함수에서 gpUpdateKey함수가 호출될 때 마다 모든 키의 입력 상태를 확인하여 입력된 키코드의 키프레임수를 가산한다.


#include <DxLib.h>


int Key[256]; // 키가 입력되는 프레임수를 저장


// 키 입력 상태를 갱신

int gpUpdateKey(){

        char tmpKey[256]; // 현재  키의 입력 상태를 저장

        GetHitKeyStateAll( tmpKey ); // 모든 키 입력 상태를 감지

        for( int i=0; i<256; i++ ){ 

                if( tmpKey[i] != 0 ){ // i번의 키코드에 대응 하는 키가 확인 되면

                        Key[i]++;     // 가산

                } else {              // 키가 눌려있지 않으면

                        Key[i] = 0;   // 0으로 변경

                }

        }

        return 0;

}


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        int x=0;


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){


                DrawFormatString( x, 100, GetColor(255,255,255), "?!" );


                if( Key[KEY_INPUT_RIGHT] == 1 ){

                        x = x + 50;

                } else if ( Key[KEY_INPUT_LEFT] == 1 ){

x = x - 50;

}


        }


        DxLib_End();

        return 0;


실행결과



위 예제의 gpUpdateKey함수에서 입력받은 키 코드에 대응하는 키의 입력 프레임을 가산하는 것이 가능하다. 즉, Key[키코드]에 입력된 수치가 입력하고 있는 프레임 수가 된다. 이 값이 1일 때만 처리하게 되면 입력된 순간에만 처리하는것이 가능하다. 또한 입력되고 있는 프레임의 수를 알 수 있기 때문에 얼마나 입력했나 하는 확인도 가능하다. 아래는 1초 이상 Z키를 눌렀을 때 문자가 표시되는 예제이다.


#include <DxLib.h>


int Key[256]; 


int gpUpdateKey(){

        char tmpKey[256];

        GetHitKeyStateAll( tmpKey );

        for( int i=0; i<256; i++ ){ 

                if( tmpKey[i] != 0 ){

                        Key[i]++;

                } else {

                        Key[i] = 0;

                }

        }

        return 0;

}


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){


                if( Key[KEY_INPUT_Z] >= 60 ){ // 60프레임 이상 입력 햇다면

                DrawFormatString( 0, 0, GetColor(255,255,255), "?!" ); // 문자를 표시

        }


}


DxLib_End();

return 0;

}





Posted by 캡슐리어
DX라이브러리2014. 12. 23. 14:51

2.8 이미지를 분할하여 로드


RPG Maker를 사용해본일이 있다면 이해가 쉬울 것이다. 맵칩 또는 캐릭터칩과 비슷한 방식이다.



이와 같은 이미지를 활용할 수 있다. 표현할 이미지가 많은경우 각각의 파일로 나뉘면 파일 개수가 너무 많아지게 된다. 때문에 위 그림과 같이 한개의 이미지 파일에 합친 이후 분할하여 이미지를 로드할 수 있다. 이 때 LoadDivGraph함수를 사용한다. 레퍼런스는 여기서 확인


선언

 int LoadDivGraph(char *FileName,int AllNum,int XNum,int YNum,int XSize,int YSize,int *HandleBuf );

기능

 이미지파일을 메모리로 분할하여 로드

인수

 FileName : 분할할 이미지 파일의 경로명 포인터

 AllNum : 분할완료 후 총 갯수

 XNum ,YNum : 이미지의 횡/종에 대한 분할 갯수

 SizeX ,SizeY : 분할된 한개의 이미지 크기

 HandleBuf : 분할 로드된 이미지에서 업게된 핸들값을 보존할 int형 배열의 포인터


위에서 보았던 이미지를 예로 들어 아래의 예제처럼 사용 가능하다.


int image[16];

LoadDivGraph( "파일명" , 16 , 4 , 4 , 32 , 32 , image ) ;


각 인수의 의미는 다음과 같다.


제 1인수 : 파일명(경로포함)

제 2인수 : 이미지의 수

제 3인수 : 횡방향 이미지의 수

제 4인수 : 종방향 이미지의 수

제 5인수 : 이미지 한개의 횡 사이즈

제 6인수 : 이미지 한개의 종 사이즈

제 7인수 : 이미지 핸들값을 저장할 배열 포인터


이는 다음과 같은 순번으로 핸들값을 부여 받게 된다.



이미지를 그려줄 때에는 지금까지와 동일하게 DrawGraph함수를 이용한다. 다음 예제는 8번째 그림을 표시하는 예제이다.


#include <DxLib.h>


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


int image[16];

LoadDivGraph( "image/character_10.png" , 16 , 4 , 4 , 32 , 32 , image ); // 이미지 분할 로드


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){


                DrawGraph( 100, 100, image[8], TRUE );


        }


        DxLib_End();

        return 0;

}


실행결과


'DX라이브러리' 카테고리의 다른 글

3.1 키 입력에 대응해서 캐릭터를 움직여보자  (0) 2014.12.24
2.9 키 입력  (0) 2014.12.23
2.7 효과음 재생  (0) 2014.12.23
2.6 랜덤값을 얻어보자  (0) 2014.12.23
2.5 텍스트 표현  (0) 2014.12.23
Posted by 캡슐리어
DX라이브러리2014. 12. 23. 14:05

2.7 효과음 재생


효과음 재생역시 이미지와 크게 다리지 않다. 효과음을 메모리로 로드한 이후 재생하는 단계를 거친다. 효과음도 메모리로 로드하게 되면 식별코드를 부여 받게 된다. 이 식별코드를 반환하는 함수는 LoadSoundMem함수이며 레퍼런스는 여기를 확인한다.


선언

 int LoadSoundMem( char *FileName ) ;

기능

 사운드 파일을 메모리로 로드

인수

 FileName : 메모리에 로드한 사운드파일의 경로 및 파일명 문자열 포인터


지원 가능한 포맷은 wav, mp3, ogg 3종류이며 다음과 같은 특성을 갖는다.


wav : 압축하지 않은 사운드파일.

mp3 : 압축된 사운드 파일. 별도의 라이센스가 필요.

ogg : 압축된 사운드 파일. 프리 라이센스.


사운드를 메모리로 로드한 이후 재생을 하기위해서는 별도의 PlaySoundMem함수를 사용한다. 레퍼런스는 여기서 확인.


선언

 int PlaySoundMem( int SoundHandle , int PlayType ) ;

기능

 메모리에 로드된 사운드 재생

인수

 SoundHanle : 재생할 사운드의 핸들값

 PlayType : 재생형식

  - DX_PLAYTYPE_NORMAL : 기본 재생

  - DX_PLAYTYPE_BACK : 백그라운드 재생

  - DX_PLAYTYPE_LOOP : 루프 재생


보통 기본재생은 사용하지 않는다. 기본재생을 할 경우 사운드 재생이 끝날 때 까지 진행상황이 중지된다. 효과음으로 사용시에는 백그라운드 재생 계속해서 재생되는 BGM의경우 루프 재생을 이용한다.


사용예제

#include <DxLib.h>


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        int Handle, Count=0;

        Handle = LoadSoundMem("sound/1up.wav"); // sound/1up.wav를 로드, 핸들값 반환



        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){


                if( Count % 120 == 0 ){ // 2초에 한번 (60hz기 때문에)

                        PlaySoundMem( Handle, DX_PLAYTYPE_BACK ); // 효과음 재생

                }


                Count++;


        }


        DxLib_End();

        return 0;


실행결과





'DX라이브러리' 카테고리의 다른 글

2.9 키 입력  (0) 2014.12.23
2.8 이미지를 분할하여 로드  (0) 2014.12.23
2.6 랜덤값을 얻어보자  (0) 2014.12.23
2.5 텍스트 표현  (0) 2014.12.23
2.4 가산블렌딩  (0) 2014.12.23
Posted by 캡슐리어
DX라이브러리2014. 12. 23. 13:34

2.6 랜덤값을 얻어보자


게임제작에 필요한 난수값을 얻기 위한 함수. 반복할때마다 동일한 값이 아닌 계속해서 다른값이 필요한 부분에서 사용하게 된다. C언어 자체에서의 난수 함수도 있지만 DX라이브러리를 위한 난수 함수는 GetRand함수이며 레퍼런스는 여기를 확인 하자.


 선언 

 int GetRand( int RandMax ) ;

기능

 난수값 획득

인수

 RandMax : 반환되는 난수값의 최대치

반환값

 0부터 RandMax에서 설정된 수치 사이의 난수


사용예제

 int a = GetRand(3);


단, 난수는 정확하게 말하면 난수처럼 보이는 수일 뿐이다. 이 난수를 정말 랜덤한 값으로 보이게 하기 위해 초기값을 설정하여 난수값을 얻어낸다. 다시말하면 초기값이 변하게 되면 난수값도 역시 변하게 되는것이다. 보통은 현재의 시각을 밀리초단위로 바꾼 값을 초기값으로 많이 사용한다.


- 난수의 초기값이 같으면 같은 난수가 생성된다.

- DX라이브러리에서는 초기값를 지정하지 않으면 자동적으로 각자 다른 초기값를 부여하기 때문에 자연스럽게 난수값이 획득가능.


난수의 초기값을 설정하기 위해서 SRand함수를 사용한다. 임의의 int형 값을 인수로 사용하기 때문에 별도의 설명은 하지 않는다.


사용예제

#include <DxLib.h>


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        int Random[8];

        int Green = GetColor( 0, 255, 0 );


        SRand( 123456 ); // 난수의 초기값 설정


        Random[0] = GetRand( 100 ); // 0~100사이의 난수 생성

        Random[1] = GetRand( 100 );

        Random[2] = GetRand( 100 );

        Random[3] = GetRand( 100 );


        SRand( 123456 ); // 난수의 초기값 재설정


        Random[4] = GetRand( 100 ); // 0~100사이의 난수 생성

        Random[5] = GetRand( 100 );

        Random[6] = GetRand( 100 );

        Random[7] = GetRand( 100 );


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){


                for( int i=0; i<8; i++ ){

                        DrawFormatString( 0, 20*i, Green, "%d", Random[i] );

                }


        }


        DxLib_End();

        return 0;


실행결과


처음 4개의 랜덤치는 난수생성이 이루어지고 있었지만 초기값을 다시 설정해준 이후 처음 네개의 생성값과 동일한 난수값을 생성하는 모습을 확인 가능하다.

'DX라이브러리' 카테고리의 다른 글

2.8 이미지를 분할하여 로드  (0) 2014.12.23
2.7 효과음 재생  (0) 2014.12.23
2.5 텍스트 표현  (0) 2014.12.23
2.4 가산블렌딩  (0) 2014.12.23
2.3 알파블렌딩  (0) 2014.12.23
Posted by 캡슐리어
DX라이브러리2014. 12. 23. 12:33

2.5 텍스트 표현


게임상에서의 대화, 메뉴항목 등의 텍스트 표현은 DrawFormatString함수를 이용한다. 레퍼런스는 여기를 확인.


 선언 

 int DrawFormatString( int x , int y , int Color , char *FormatString , ... );

기능

 텍스트 표시

인수

 int x , y : 문자열이 표시될 좌표

 int Color : 텍스트 색

 char *FormatString : 서식이 포함된 텍스트의 포인터

 ... : 서식이 포함된 텍스트에 관련된 인수


세번째 인수의 Color는 색을 지정한다. 색은 GetColor함수를 사용하며 레퍼런스는 여기를 확인.


 선언

 int GetColor( int Red , int Green , int Blue ) ;

 기능

 칼라코드 획득

 인수

 Red , Green , Blue : 색별 휘도치(0~255)

 반환값

 칼라코드


GetColor 사용예

int Col = GetColor( 255, 255, 255 );


DrawFormatString의 네번째 인수는 printf함수와 사용법이 비슷하다.

int a=10, b=20;

printf("%d와 %d입니다.", a, b ); 

DrawFormatString( 0, 0, GetColor(255,255,255), "%d와 %d입니다.", a, b);


사용예제

#include <DxLib.h>


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        int x=0, y=0;

        int Green = GetColor( 0, 255, 0 );      // 녹색 칼라코드


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){


                DrawFormatString( x, y, Green, "좌표[%d,%d]", x, y ); // 텍스트 처리


                x = x + 2;

                y = y + 1;

        }


        DxLib_End();

        return 0;


실행결과


단, 이처럼 텍스트를 이미지로 처리하는 방법은 자원을 많이 잡아먹기 때문에 문자의 양이 많거나 빠른 처리가 필요한 경우에는 주의가 필요하다. DX라이브러리에서는 이 함수 외에도 폰트를 지정하거나 특정 사이즈로 변경하는 함수도 존재하지만 이는 다음 기회에 설명한다.

'DX라이브러리' 카테고리의 다른 글

2.7 효과음 재생  (0) 2014.12.23
2.6 랜덤값을 얻어보자  (0) 2014.12.23
2.4 가산블렌딩  (0) 2014.12.23
2.3 알파블렌딩  (0) 2014.12.23
2.2 이미지 회전, 확대축소  (0) 2014.12.22
Posted by 캡슐리어
DX라이브러리2014. 12. 23. 12:05

2.4 가산블렌딩


빛은 중첩될 수록 하얗게 된다. 빛의 삼원색을 모두 섞으면 흰색이 된다. 역으로 빛이 전혀 없다면 어둡게(검게)된다. 즉, 빛을 섞는 가산블렌딩을 거치게 되면 좀더 빛나는듯한 효과를 갖게 되며 겹칠수록 밝아지기 때문에 빛의 표현을 가능하게 한다. 다음 스크린샷의 레이져 같은 부분이 이 기능을 사용한 것이라고 보면 되겠다.



이는 한줄기의 무지게빛 선으로 보이겠지만 사실은 다음과 같은 이미지를 가산블렌딩한것이다.



그렇다면 다음 이미지를 통하여 가산블렌딩과 알파블렌딩의 차이를 알아보자.



가산블렌딩 역시 SetDrawBlendMode함수를 사용한다. 기능관련 요약은 2.3섹션에 다루었으니 해당 섹션을 참고한다. 단, 두번째 인수에서 블렌드 모드의 옵션에 차이가 있다. 이전 섹션에선 DX_BLENDMODE_ALPHA를 사용했으나 당 섹션에선 DX_BLENDMODE_ADD를 사용한다. 또한 두번째 인수는 0에서 가산하지 않는다 부터 255 모두 가산한다의 단계로 설정 가능하다.


사용예제

#include <DxLib.h>


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        int Handle;

        Handle = LoadGraph( "image/bullet_00.png" );


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){


                SetDrawBlendMode( DX_BLENDMODE_ALPHA, 128 );   //알파블렌딩 128/255

                DrawGraph( 100, 200, Handle, TRUE );

                DrawGraph( 120, 200, Handle, TRUE );

                DrawGraph( 140, 200, Handle, TRUE );

                DrawGraph( 160, 200, Handle, TRUE );

                DrawGraph( 180, 200, Handle, TRUE );

                DrawGraph( 200, 200, Handle, TRUE );

                SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );


                SetDrawBlendMode( DX_BLENDMODE_ADD,  255 );             //가산블렌딩 255/255

                DrawGraph( 300, 200, Handle, TRUE );

                DrawGraph( 320, 200, Handle, TRUE );

                DrawGraph( 340, 200, Handle, TRUE );

                DrawGraph( 360, 200, Handle, TRUE );

                DrawGraph( 380, 200, Handle, TRUE );

                DrawGraph( 400, 200, Handle, TRUE );

                SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 );


        }


        DxLib_End();

        return 0;


실행결과



왼쪽이 알파블렌딩이며 오른쪽이 가산블렌딩이다.

'DX라이브러리' 카테고리의 다른 글

2.6 랜덤값을 얻어보자  (0) 2014.12.23
2.5 텍스트 표현  (0) 2014.12.23
2.3 알파블렌딩  (0) 2014.12.23
2.2 이미지 회전, 확대축소  (0) 2014.12.22
2.1 이미지 처리 : 응용편  (0) 2014.12.22
Posted by 캡슐리어
DX라이브러리2014. 12. 23. 11:32

2.3 알파블렌딩


알파블렌딩에서의 알파는 투명도를 이야기 하는 것이며 두 이미지의 알파를 블렌딩한다는 것 즉, 반투명 효과를 말한다. 이 처리를 위한 흐름은 다음과 같다.


- 이미지 처리 방법을 알파블렌딩으로 설정

- 이미지A를 화면에 표시

- 이미지 처리 방법을 본래대로 돌림.


이 기능을 위해선 SetDrawBlendMode함수를 사용한다. 리퍼런스는 여기서 확인.


선언 

 int SetDrawBlendMode( int BlendMode , int Pal );

기능

 이미지의 알파블렌딩

인수

 BlendMode : 블렌딩 모드 설정

  - DX_BLENDMODE_NOBLEND : 노블렌딩(디폴트)

  - DX_BLENDMODE_ALPHA : 알파블렌딩

 Pal : 블렌드모드 파라메터 (0~255)


첫번째 인수는 차후에 설명하기로 하며 일단 DX_BLENDMODE_ALPHA 로 고정. 두번째 인수는 0에서 완전 투명 255에서 완전 불투명의 단계로 설정 가능.


사용예제

#include <DxLib.h>


#define PI 3.141592654


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        int x = 100;

        int Handle;

        Handle = LoadGraph( "image/character_00.png" );


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){


                DrawRotaGraph( 400, 200, 2.0, PI*x, Handle, TRUE );


                SetDrawBlendMode( DX_BLENDMODE_ALPHA,  128); //블렌드모드 128/255 설정

DrawRotaGraph(   x, 200, 1.0,  0.0, Handle, TRUE );

SetDrawBlendMode( DX_BLENDMODE_NOBLEND,  0 ); //블렌드모드 OFF


x++;


}


DxLib_End();

return 0;


실행결과





'DX라이브러리' 카테고리의 다른 글

2.5 텍스트 표현  (0) 2014.12.23
2.4 가산블렌딩  (0) 2014.12.23
2.2 이미지 회전, 확대축소  (0) 2014.12.22
2.1 이미지 처리 : 응용편  (0) 2014.12.22
1.9 게임 프로그램 골격의 완성  (0) 2014.12.22
Posted by 캡슐리어
DX라이브러리2014. 12. 22. 18:06

2.2 이미지 회전, 확대축소


선언

 int DrawRotaGraph( int x, int y, double ExtRate, double Angle, int GrHandle , int TransFlag ) ;

기능

 메모리에 로드한 이미지의 회전

인수

 x , y : 이미지 영역의 중심 좌표

 ExtRate : 확대율 (1.0으로 원본크기)

 Angle : 각도 (라디안 지정)

 GrHandle : 이미지의 핸들값

 TransFlag : 투명도 적용여부 (TRUE 적용, FALSE 비적용)


DrawGraph함수의 경우 좌표는 위 그림에서와 같이 화면의 좌상단을 (0,0)으로 하여 기준을 잡고 이미지의 좌상단점을 이미지의 위치로 판단하여 처리했다. 하지만 DrawRotaGraph함수는 이미지의 기준점이 좌상단이 아닌 중심이 된다. 아래 그림은 2배 확대시의 예

각도인수를 입력할 때에는 각도를 실수형으로 변경하여 코딩한다. 주의할 점은 회전 방향은 아래의 그림처럼 시계방향이 된다. 

또한 각도의 입력은 도수법아닌 호도법을 이용한다. 180도 회전의 경우 1π이며 원주율의 경우 전역변수 또는 PI를 치환하도록 전처리 설정을 통해 표현하게 된다.


ex)  #define PI 3.141592654

45도의 경우 PI/4


다음 예제의 경우 첫번째 이미지는 회전, 확대 모두 적용되지 않은 상태이며 두번째 이미지는 2배확대/45도 회전을 적용한 예제이다.


#include <DxLib.h>


#define PI 3.141592654


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );

        int Handle;

        Handle = LoadGraph( "image/character_00.png" );


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){


                DrawRotaGraph( 100, 200, 1.0,  0.0, Handle, TRUE ); //이미지 처리 

DrawRotaGraph( 400, 200, 2.0, PI/4, Handle, TRUE ); //이미지 처리 (2배확대, 45도 회전)


}


DxLib_End();

return 0;


실행결과





'DX라이브러리' 카테고리의 다른 글

2.4 가산블렌딩  (0) 2014.12.23
2.3 알파블렌딩  (0) 2014.12.23
2.1 이미지 처리 : 응용편  (0) 2014.12.22
1.9 게임 프로그램 골격의 완성  (0) 2014.12.22
1.8 소스코드를 간단하게 줄이자  (0) 2014.12.22
Posted by 캡슐리어