U E D R , A S I H C RSS

�블스캠프2005/게임만들기/제작과정예제

�블스캠프2005/게임만들기/제작과정예제


화면ì—� 블럭 ìœë ¥í•˜ê¸°


화면ì—� 블럭ì�„ ìœë ¥í•´ë³´ìž�.
start()안�보면, 다양한 색�들� �혀있는color�는 �름� 변수가 보� 것�다.
그앞� 주�� 가르키는�로, 1~10까지� 색�� 지정할 수 있다.
그밑� 보�는 block변수가 블럭� 기억하게 �다.
~cpp 
block[0][0]=1;
��고 �고 실행해보�. 아래와 같� 결과가 나올것�다.

test01.jpg

~cpp 
block[x좌표][y좌표]=블럭� 종류;
와 ê°™ì�€ 형ì‹�으로 ìœë ¥í•  블럭ì�„ 지정하며, 0ì�€ 블럭ì�´ 없는 것ì�´ê³  ê·¸ ì�´ì™¸ì�˜ ê°’ì�€ 해당하는 색ìƒ�ì�˜ 블ë¡�ì�´ 들어가게 ë�œë‹¤.
block_next변수는, ë©”ì�¸ì°½ 옆ì�˜ next아래ì—� 블럭ì�„ ìœë ¥í•˜ë©° 가로3세로4ì�˜ í�¬ê¸°ë¥¼ ìœë ¥í•  수 있다.
지정형�� 위와 ��하다.
~cpp 
block_next[x좌표][y좌표]=블럭� 종류;


할� 정하기

보다 쉽게 �� 진행하기 위해서 할�� 정해�어야 할 필요가 있다.
테트리스를 떠올려보고, 어떤 과정� 거�서만들지 ��해보�.

실습예제
~cpp 
1.ìœë ¥í•  블럭ì�˜ 모양ì�„ 결정한다.
2.ëžœë�¤ìœ¼ë¡œ 블럭ì�„ ìƒ�성한 후 nextì°½ì—� ìœë ¥í•œë‹¤.
3.nextì°½ì—� ìœë ¥ë�œ 블럭ì�„ 가져온뒤 ë©”ì�¸ì°½ì—� ìœë ¥í•œë‹¤.
4.블럭� 움��다.
5.블럭� 회전시킨다.
6.한줄� 다 찼�때, 블럭� 삭제한다.
7.�수와 스테�지를 변화시킨다.

위� 예제 순서를 따� 진행하면 테트리스를 만들 수 있다.
하지만, 막히는 부분� �기게 �면 아래를 참조하길 바란다.


ìœë ¥í•  블럭ì�˜ 모양 정하기


모양� 정하는 방법�는 여러가지가 있다.
n칸 �우고, n칸만� 블럭� 채우는 �으로,
예를 들어 T는(0,3)(1,1)(1,1)�렇게 표시할 수 있다. 방향� 따�, 가로가 아닌 세로부터 시작하거나 해서 바꿔줄 수 있다.
그리고 다른 방법으로는 그냥 편하게 블럭� �기만� 배열� 지정해서 있는곳�는 숫�를 넣고 아닌곳�는 0� 넣는 방�� 있다.

예제) ��모양� 배열으로 표시하는 방법. 소스가 길어지므로, 헤�파�� 넣기를 권장한다.
~cpp 
	{{
	{0,0,0,0},
	{2,2,2,2},
	{0,0,0,0},
	{0,0,0,0}}
	,{
	{0,0,2,0},
	{0,0,2,0},
	{0,0,2,0},
	{0,0,2,0}}
	,{
	{0,0,0,0},
	{2,2,2,2},
	{0,0,0,0},
	{0,0,0,0}}
	,{
	{0,0,2,0},
	{0,0,2,0},
	{0,0,2,0},
	{0,0,2,0}}
},

ëžœë�¤ìœ¼ë¡œ 블럭ì�„ ìƒ�성한 후 nextì°½ì—� ìœë ¥í•˜ê¸°


우선 랜�하게 블럭� �성하기 위해서 start()함수� srand((int)time(NULL));�고 �어서, 시간� �용해서 랜�하게 나오게 한 다�,
블럭ì�„ ëžœë�¤í•˜ê²Œ 호ìœí•˜ëŠ” 함수를 만들ìž�. 그리고 ê·¸ 안ì—� rand()함수를 사용해서, ìž„ì�˜ì�˜ 숫ìž�를 ì–»ì�€í›„ ê·¸ 숫ìž�ì—� 맞추어 블럭ì�„ 지정하고
next변수ì—� ìœë ¥ë�˜ê²Œ 하면 ë�œë‹¤.
그리고 ìœë ¥ë�  변수를 기억하게 하기 위해서 다ì�Œì—� 나올 블럭ì�„ 기억하는 전역변수를 만들고, 거기ì—� ê°’ì�„ 저장시키ìž�.

테스트를 위해서는 key_Right()와 같� 변수안� 넣고, 해당하는 키를 눌러보면 실행� �다.

test02.jpg

예제)
~cpp 
	int block_id;
	block_id=rand()%7;
	for (register int i=0;i<3;++i)
		for (register int j=0; j<4; ++j)
			block_next[i][j]=block_type[block_id][0][i][j];
	prv_block=block_id; //전역변수� 저장.



�성� 블럭� 메�창� 소환하기


정해진 블럭� 메�창� 소환해 보�. 메�창� 맨 위� 가운�쯤� 가장 �당할 것�다.
� 소환�는 순간, 그 위치� 블럭� 있다면, 게임� 종료� 것�다.
소환� 후, 진행� 위해 소환� 위치� x,y값� 기억하는 전역변수를 만들고 소환하면 �다.
그리고, 현제 블럭� 아�디를 기억할 전역변수� 만들어서 저장하�.
소환하는 알고리즘� 위�서 next창� 불러오는것과 같� 알고리즘 �다.

테스트를 위해서는 key_Left()와 ê°™ì�€ 변수안ì—� 넣고, ëžœë�¤ìœ¼ë¡œ 만드는 함수를 호ìœí•œí›„, 호ìœí•´ ë³´ë©´ ë�œë‹¤.

예제)
~cpp 
	for (register int i=0;i<3; ++i)
	{
		for (register int j=0; j<4; ++j)
		{
			if (0!=block_type[prv_block][0][i][j])
			{
				if (0==block[3+i][16+j])
					block[3+i][16+j]=block_type[prv_block][0][i][j];
				else
					game_end();
			}
		}
	}
	x=3;  //전역변수 x
	y=16; //전역변수 y
	shape=0; //전역변수 현재 블�� 회전정�
	now_block=prv_block; //전역변수 현재 블럭� ID

test03.jpg


�성� 블럭� 움��게 하기


소환� 블럭� 움��게 해보�. 움��게 하는�는 여러가지 알고리즘� 있지만, 쉬운 방법� 블럭� 내려가면 색깔� 바꾸고, 색깔� 있는 블럭만 움��게 하는 방법� 있다. �번째는, 블럭� �� 계산해서 그 부분� 닿게�면 멈추게 하는 방법� 있다. 후�가 연산� � 복잡하나, 좀� 다양한 색�� 볼 수 있다. 움�� 때�는, 좌우� 벽과 다른 블럭� 고려해서 움�여야 한다.

다 만들어 ì§„ 후, 왼쪽, 오른쪽 방향키ì—� 알맞ì�€ ì�¸ìž�를 넣어서 함수를 넣고, now_time()ì—� 블럭ì�„ 아래로 내리는 함수를 호ìœí•˜ë�„ë¡� 하ìž�.

test04.jpg


예제) �번째 방법� �용한 모습중 하나. -1� 왼쪽 0� 아래, 1� 오른쪽으로 움��다는 뜻으로 ��를 넘겨받는다.
리팩토�� 많� 필요한 모습�다.


~cpp 
int move_block(int where)// -1좌 0아래  1우
{
	int temp_x=x+where;
	int temp_y=y-(where+1)%2;
	int temp_block[4][4]={0,};
	int ground[4]={0,};
	int side[2][4]={0,};
	int swit[2][4]={0,};
         
         // 블럭� �� 체�한다.         

	for (register int i=0;i<4; ++i)
	{
		for (register int j=0; j<4; ++j)
		{
			if (0!=block_type[now_block][shape][i][j])
			{
				if (i>=side[0][j] && 0==swit[1][j])
				{
					side[0][j]=i;
					swit[1][j]=1;
				}
				side[1][j]=i;
				if (j>=ground[i] && 0==swit[0][i])
				{
					ground[i]=j;
					swit[0][i]=1;
				}
			}
		}
	}

         // 블럭� 움�� 수 있는가를 �단한다. 못 움�� 경우�는 1� 리턴하고 종료한다.

	for (i=0;i<4; ++i)
	{
		for (register int j=0; j<4; ++j)
		{
			if (0!=block_type[now_block][shape][i][j])
			{
				if (temp_x+i<0 || temp_x+i>9 )
					return 1;
				else if (temp_y+j<0 || temp_y+j>19 )
					return 1;
				else if (0!=block[temp_x+i][temp_y+j])
				{
					if (ground[i]+1>j && where==0)
						return 1;
					else if (side[0][j]+1>i && where==-1)
						return 1;
					else if (side[1][j]-1<i && where==1)
						return 1;
				}
			}
		}
	}

         // �전� 블럭� �미지를 제거한다.

	for (i=0;i<4; ++i)
		for (register int j=0; j<4; ++j)
			if (0!=block_type[now_block][shape][i][j])
				block[x+i][y+j]=0;

         // 새로운 블럭� 그린다.

	for (i=0;i<4; ++i)
		for (register int j=0; j<4; ++j)
			if (0!=block_type[now_block][shape][i][j])
				block[temp_x+i][temp_y+j]=block_type[now_block][shape][i][j];
	x=temp_x;y=temp_y;
	return 0;
}


블럭� 회전하게 하기


블럭� 회전하기 위해서, 해야할 ��, 좌 우측으로 충분한 공간� 있는지를 보고, 벽� 막고 있으면 움�여준 뒤� 공간� 확보해서 회전하게 하는 것�다. ��보다는 간편한 편�며, 전역변수� 움�� 정�를 기억시켜서, 움�� 수 있�� 해야 한다.

예제)

~cpp 
	int temp_x=x;
	int temp_y=y;
	int temp_shape=(shape+1)%4;
	int crash=2;
	int temp_block[4][4]={0,};

         //블럭� 벽� 닿는지, 충분한 공간� 있는지를 확�한다.

	while (2==crash)
	{
		for (register int i=0;i<4; ++i)
			for (register int j=0; j<4; ++j)
				temp_block[i][j]=0;
		crash=0;
		for (i=0;i<4; ++i)
			for (register int j=0; j<4; ++j)
				if (0!=block_type[now_block][shape][i][j]&& 0<=i+x-temp_x && 3>=i+x-temp_x )
					temp_block[i+x-temp_x][j]=1;
		for (i=0;i<4; ++i)
		{
			for (register int j=0; j<4; ++j)
			{
				if (0!=block_type[now_block][temp_shape][i][j])
				{
					if (temp_x+i<0)
					{
						temp_x+=1;crash=2;
					}
					else if (temp_x+i>9 )
					{
						temp_x-=1;crash=2;
					}
					else if (0!=block[temp_x+i][temp_y+j] && 1!=temp_block[i][j])
						crash=1;
				}
			}
		}
	}

         //블럭� 회전할 공간� 있으면, �전� 블럭� 삭제한다.

	if (1==crash)
		return 0;
	for (register int i=0;i<4; ++i)
		for (register int j=0; j<4; ++j)
			if (0!=block_type[now_block][shape][i][j])
				block[x+i][y+j]=0;

         //새로운 블럭� 그려넣는다.

	for (i=0;i<4; ++i)
		for (register int j=0; j<4; ++j)
			if (0!=block_type[now_block][temp_shape][i][j])
				block[temp_x+i][temp_y+j]=block_type[now_block][temp_shape][i][j];

         //변화� 값� 저장한다.

	x=temp_x;y=temp_y;shape=temp_shape;
	return 0;


블럭� 삭제하기


블럭� 내려오게 �어, 한줄� 완성�면 삭제�어야 한다. �한, 삭제�후 그 윗줄부터는 한칸씩 아래로 내려져야 한다.
�반�으로 for문� �용해서 한줄� 검색할 수 있으나, 같� 내려온 블럭� 같�색으로 처리�는 경우는, �해서 숫�가 �치하는지를 볼 수� 있다.

예제)
~cpp 
void delete_block()
{
	for (register int line=y; line<y+4; ++line)
		for (register int i=0; i<10; ++i)
			if (0==block[i][line])
				i=10;   //빈 블럭� 있으면, 그줄� 검사를 �낸다.
			else
				if (9==i) //블럭� 다 차있� 경우�는 한줄� 삭제한다.
				{
					for (register int k=0; k<10; ++k)
						block[k][line]=0;
					for (k=line; k<19; ++k) //블럭� 한줄씩 내린다.
						for (register int l=0; l<10; ++l)
							block[l][k]=block[l][k+1];
					for (k=0; k<10; ++k)
						block[k][19]=0;
					--line;
				}
}


�수와 스테�지 변환


�수는 블럭� 내려올때, 삭제�때 등으로 �가�는 경우를 정하고, 그 경우마다 알맞� 값� �가시켜 주면�다.
그리고 그 결과 �수가 �정치� 달하면 스테�지를 바꾸고, time_delay 변수� 값� �소시켜 난��를 �가시키면 �다.

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:28:59
Processing time 0.0241 sec