ë�°ë¸”ìŠ¤ìº í”„2005/게임만들기/ì œìž‘ê³¼ì •ì˜ˆì œ ¶
화면ì—� ë¸”ëŸ ì¶œë ¥í•˜ê¸° ¶
화면ì—� 블ëŸì�„ ì¶œë ¥í•´ë³´ìž�.
start()안ì—�ë³´ë©´, 다양한 색ìƒ�들ì�´ ì �혀있는colorë�¼ëŠ” ì�´ë¦„ì�˜ 변수가 ë³´ì�¼ 것ì�´ë‹¤.
그앞ì�˜ 주ì„�ì�´ 가르키는ë�°ë¡œ, 1~10까지ì�˜ 색ìƒ�ì�„ ì§€ì •í• ìˆ˜ 있다.
그밑ì—� ë³´ì�´ëŠ” block변수가 블ëŸì�„ 기억하게 ë�œë‹¤.
start()안ì—�ë³´ë©´, 다양한 색ìƒ�들ì�´ ì �혀있는colorë�¼ëŠ” ì�´ë¦„ì�˜ 변수가 ë³´ì�¼ 것ì�´ë‹¤.
그앞ì�˜ 주ì„�ì�´ 가르키는ë�°ë¡œ, 1~10까지ì�˜ 색ìƒ�ì�„ ì§€ì •í• ìˆ˜ 있다.
그밑ì—� ë³´ì�´ëŠ” block변수가 블ëŸì�„ 기억하게 ë�œë‹¤.
~cpp block[0][0]=1;ì�´ë�¼ê³ ì �ê³ ì‹¤í–‰í•´ë³´ìž�. 아래와 ê°™ì�€ 결과가 나올것ì�´ë‹¤.
~cpp block[x좌표][y좌표]=블ëŸì�˜ 종류;
와 ê°™ì�€ 형ì‹�으로 ì¶œë ¥í• ë¸”ëŸì�„ ì§€ì •í•˜ë©°, 0ì�€ 블ëŸì�´ 없는 것ì�´ê³ ê·¸ ì�´ì™¸ì�˜ ê°’ì�€ 해당하는 색ìƒ�ì�˜ 블ë¡�ì�´ 들어가게 ë�œë‹¤.
block_next변수는, ë©”ì�¸ì°½ 옆ì�˜ next아래ì—� 블ëŸì�„ ì¶œë ¥í•˜ë©° 가로3세로4ì�˜ í�¬ê¸°ë¥¼ ì¶œë ¥í• ìˆ˜ 있다.
ì§€ì •í˜•ì‹�ì�€ 위와 ë�™ì�¼í•˜ë‹¤.
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ì�„ 넣는 ë°©ì‹�ì�´ 있다.
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()와 ê°™ì�€ 변수안ì—� ë„£ê³ , 해당하는 키를 눌러보면 실행ì�´ ë�œë‹¤.
블ëŸì�„ ëžœë�¤í•˜ê²Œ 호출하는 함수를 만들ìž�. ê·¸ë¦¬ê³ ê·¸ 안ì—� rand()함수를 사용해서, ìž„ì�˜ì�˜ 숫ìž�를 ì–»ì�€í›„ ê·¸ 숫ìž�ì—� 맞추어 블ëŸì�„ ì§€ì •í•˜ê³
next변수ì—� ì¶œë ¥ë�˜ê²Œ 하면 ë�œë‹¤.
ê·¸ë¦¬ê³ ì¶œë ¥ë� 변수를 기억하게 하기 위해서 다ì�Œì—� 나올 블ëŸì�„ 기억하는 ì „ì—변수를 ë§Œë“¤ê³ , 거기ì—� ê°’ì�„ ì €ìž¥ì‹œí‚¤ìž�.
테스트를 위해서는 key_Right()와 ê°™ì�€ 변수안ì—� ë„£ê³ , 해당하는 키를 눌러보면 실행ì�´ ë�œë‹¤.

ì˜ˆì œ)
~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()와 ê°™ì�€ 변수안ì—� ë„£ê³ , ëžœë�¤ìœ¼ë¡œ 만드는 함수를 호출한후, 호출해 ë³´ë©´ ë�œë‹¤.
ì˜ˆì œ)ë˜� 소환ë�˜ëŠ” 순간, ê·¸ 위치ì—� 블ëŸì�´ 있다면, 게임ì�€ 종료ë� 것ì�´ë‹¤.
소환ë�œ 후, ì§„í–‰ì�„ 위해 소환ë�œ 위치ì�˜ 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
ìƒ�성ë�œ 블ëŸì�„ 움ì§�ì�´ê²Œ 하기 ¶
소환ë�œ 블ëŸì�„ 움ì§�ì�´ê²Œ í•´ë³´ìž�. 움ì§�ì�´ê²Œ 하는ë�°ëŠ” 여러가지 ì•Œê³ ë¦¬ì¦˜ì�´ 있지만, 쉬운 방법ì�€ 블ëŸì�´ ë‚´ë ¤ê°€ë©´ 색깔ì�„ ë°”ê¾¸ê³ , 색깔ì�´ 있는 블ëŸë§Œ 움ì§�ì�´ê²Œ 하는 방법ì�´ 있다. ë‘�번째는, 블ëŸì�˜ ë��ì�„ 계산해서 ê·¸ 부분ì�´ 닿게ë�˜ë©´ 멈추게 하는 방법ì�´ 있다. 후ìž�ê°€ ì—°ì‚°ì�´ ë�” 복잡하나, 좀ë�” 다양한 색ìƒ�ì�„ ë³¼ 수 있다. 움ì§�ì�¼ 때ì—�는, 좌우ì�˜ 벽과 다른 블ëŸì�„ ê³ ë ¤í•´ì„œ 움ì§�여야 한다.
다 만들어 ì§„ 후, 왼쪽, 오른쪽 방향키ì—� 알맞ì�€ ì�¸ìž�를 넣어서 함수를 ë„£ê³ , now_time()ì—� 블ëŸì�„ 아래로 내리는 함수를 호출하ë�„ë¡� 하ìž�.
다 만들어 ì§„ 후, 왼쪽, 오른쪽 방향키ì—� 알맞ì�€ ì�¸ìž�를 넣어서 함수를 ë„£ê³ , now_time()ì—� 블ëŸì�„ 아래로 내리는 함수를 호출하ë�„ë¡� 하ìž�.

ì˜ˆì œ) ë‘�번째 방법ì�„ ì�´ìš©í•œ 모습중 하나. -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문ì�„ ì�´ìš©í•´ì„œ 한줄ì�„ ê²€ìƒ‰í• ìˆ˜ 있으나, ê°™ì�€ ë‚´ë ¤ì˜¨ 블ëŸì�´ ê°™ì�€ìƒ‰ìœ¼ë¡œ 처리ë�˜ëŠ” 경우는, ë�”해서 숫ìž�ê°€ ì�¼ì¹˜í•˜ëŠ”ì§€ë¥¼ ë³¼ 수ë�„ 있다.
ì˜ˆì œ)ì�¼ë°˜ì �으로 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 변수ì�˜ ê°’ì�„ ê°�소시켜 난ì�´ë�„를 ì¦�가시키면 ë�œë‹¤.
ê·¸ë¦¬ê³ ê·¸ ê²°ê³¼ ì �수가 ì�¼ì •치ì—� 달하면 스테ì�´ì§€ë¥¼ ë°”ê¾¸ê³ , time_delay 변수ì�˜ ê°’ì�„ ê°�소시켜 난ì�´ë�„를 ì¦�가시키면 ë�œë‹¤.












