用c实现俄罗斯方块游戏过程

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#include <graphics.h>
#define ROW_AR 28
#define COL_AR 14
#define BLOCK_X 4
#define BLOCK_Y 2
#define originallocationX 7
#define originallocationY 7
int start, end,NUM=0;
char p,l,x,L,T,D,L2,l1,x1,L1,T1,L21,v;
enum m
{
BLock_null,
BLock_Frame,
BLock_BL,
};
enum BLock
{
row,
col
};
int MapArr[ROW_AR][COL_AR] = { 0 };
char BlockLt[BLOCK_X][BLOCK_Y] = { 0 };
int GameOver()
{
for (int i = 0; i < BLOCK_X; ++i)
{
if (BlockLt[i][row] < 8)
{
return 1;
}
}
return 0;
}
void Score()//得分
{
int F;
for (F = ROW_AR-2; F >= 8; F--)
{
p = 'T';
for (int G = 1; G < COL_AR-1; G++)
{
if (MapArr[F][G] == BLock_null)
{
p = 'F';
break;
}
}
if (p == 'T')
{
for (int i =F; i >= 8; i--)
{
for (int j = 1; j < COL_AR-1; j++)
{
MapArr[i][j] = MapArr[i-1][j];
}
}
NUM++;
F++;
}
}
}
char IsBlockchange()//判断是否能变形
{
p = 'T';
switch (x)
{
case 0://长条状
if (l == 0)
{
if (MapArr[BlockLt[1][row] - 1][BlockLt[1][col]] != BLock_null || MapArr[BlockLt[1][row] + 1][BlockLt[1][col]] != BLock_null || MapArr[BlockLt[1][row] + 2][BlockLt[1][col]] != BLock_null)
p = 'F';
}
else if (l == 1)
{
if (MapArr[BlockLt[1][row]][BlockLt[1][col]-1] != BLock_null || MapArr[BlockLt[1][row]][BlockLt[1][col]+1] != BLock_null || MapArr[BlockLt[1][row]][BlockLt[1][col]+2] != BLock_null)
p = 'F';
}
break;
case 1://L状
switch (L)
{
case 0:
if (MapArr[BlockLt[2][row]][BlockLt[2][col] + 1] != BLock_null || MapArr[BlockLt[2][row]][BlockLt[2][col] - 1] != BLock_null || MapArr[BlockLt[2][row]+1][BlockLt[2][col] - 1] != BLock_null)
p = 'F';
break;
case 1:
if (MapArr[BlockLt[2][row]-1][BlockLt[2][col] - 1] != BLock_null || MapArr[BlockLt[2][row]+1][BlockLt[2][col]] != BLock_null || MapArr[BlockLt[2][row] - 1][BlockLt[2][col]] != BLock_null)
p = 'F';
break;
case 2:
if (MapArr[BlockLt[2][row]][BlockLt[2][col] - 1] != BLock_null || MapArr[BlockLt[2][row]][BlockLt[2][col] + 1] != BLock_null || MapArr[BlockLt[2][row] - 1][BlockLt[2][col] + 1] != BLock_null)
p = 'F';
break;
case 3:
if (MapArr[BlockLt[2][row]-1][BlockLt[2][col]] != BLock_null || MapArr[BlockLt[2][row]+1][BlockLt[2][col]] != BLock_null || MapArr[BlockLt[2][row] + 1][BlockLt[2][col] + 1] != BLock_null)
p = 'F';
break;
}
break;
case 2://反7状
switch (L2)
{
case 0:
if (MapArr[BlockLt[2][row]-1][BlockLt[2][col]] != BLock_null || MapArr[BlockLt[2][row]+1][BlockLt[2][col]] != BLock_null || MapArr[BlockLt[2][row] - 1][BlockLt[2][col] + 1] != BLock_null)
p = 'F';
break;
case 1:
if (MapArr[BlockLt[2][row]][BlockLt[2][col] - 1] != BLock_null || MapArr[BlockLt[2][row]][BlockLt[2][col] + 1] != BLock_null || MapArr[BlockLt[2][row] + 1][BlockLt[2][col] +  1] != BLock_null)
p = 'F';
break;
case 2:
if (MapArr[BlockLt[2][row]-1][BlockLt[2][col]] != BLock_null || MapArr[BlockLt[2][row]+1][BlockLt[2][col]] != BLock_null || MapArr[BlockLt[2][row] + 1][BlockLt[2][col] - 1] != BLock_null)
p = 'F';
break;
case 3:
if (MapArr[BlockLt[2][row]][BlockLt[2][col] + 1] != BLock_null || MapArr[BlockLt[2][row]][BlockLt[2][col] - 1] != BLock_null || MapArr[BlockLt[2][row] - 1][BlockLt[2][col] - 1] != BLock_null)
p = 'F';
break;
}
break;
case 3://T状
switch (T)
{
case 0:
if (MapArr[BlockLt[1][row]][BlockLt[1][col] + 1] != BLock_null)
p = 'F';
break;
case 1:
if (MapArr[BlockLt[1][row]+1][BlockLt[1][col]] != BLock_null)
p = 'F';
break;
case 2:
if (MapArr[BlockLt[1][row]][BlockLt[1][col] - 1] != BLock_null)
p = 'F';
break;
case 3:             
if (MapArr[BlockLt[1][row]-1][BlockLt[1][col]] != BLock_null)
p = 'F';
break;
}
break;
}
return p;
}
void ChangeBlock()//块的变形操作
{
switch (x)
{
case 0://长条状
if (l == 0)
{
BlockLt[0][row] = BlockLt[1][row] - 1;
BlockLt[0][col] = BlockLt[1][col];
BlockLt[2][row] = BlockLt[1][row] + 1;
BlockLt[2][col] = BlockLt[1][col];
BlockLt[3][row] = BlockLt[1][row] + 2;
BlockLt[3][col] = BlockLt[1][col];
l = 1;
}
else if (l == 1)
{
BlockLt[0][row] = BlockLt[1][row];
BlockLt[0][col] = BlockLt[1][col] - 1;
BlockLt[2][row] = BlockLt[1][row];
BlockLt[2][col] = BlockLt[1][col] + 1;
BlockLt[3][row] = BlockLt[1][row];
BlockLt[3][col] = BlockLt[1][col] + 2;
l = 0;
}
break;
case 1://L状
switch (L)
{
case 0:
BlockLt[0][row] = BlockLt[2][row] + 1;
BlockLt[0][col] = BlockLt[2][col] - 1;
BlockLt[1][row] = BlockLt[2][row];
BlockLt[1][col] = BlockLt[2][col] - 1;
   BlockLt[3][row] = BlockLt[2][row];
BlockLt[3][col] = BlockLt[2][col] + 1;
L = 1;
break;
case 1:
BlockLt[0][row] = BlockLt[2][row] - 1;
BlockLt[0][col] = BlockLt[2][col] - 1;
BlockLt[1][row] = BlockLt[2][row] - 1;
BlockLt[1][col] = BlockLt[2][col];
BlockLt[3][row] = BlockLt[2][row] + 1;
BlockLt[3][col] = BlockLt[2][col];
L = 2;
break;
case 2:
  BlockLt[0][row] = BlockLt[2][row] - 1;
BlockLt[0][col] = BlockLt[2][col] + 1;
BlockLt[1][row] = BlockLt[2][row];
BlockLt[1][col] = BlockLt[2][col] + 1;
BlockLt[3][row] = BlockLt[2][row];
BlockLt[3][col] = BlockLt[2][col] - 1;
L = 3;
break;
case 3:
BlockLt[0][row] = BlockLt[2][row] + 1;
BlockLt[0][col] = BlockLt[2][col] + 1;
BlockLt[1][row] = BlockLt[2][row] + 1;
BlockLt[1][col] = BlockLt[2][col];
BlockLt[3][row] = BlockLt[2][row] - 1;
BlockLt[3][col] = BlockLt[2][col];
L = 0;
break;
}
break;
case 2://反7状
switch (L2)
{
case 0:
BlockLt[0][row] = BlockLt[2][row] - 1;
BlockLt[0][col] = BlockLt[2][col] + 1;
BlockLt[1][row] = BlockLt[2][row] - 1;
BlockLt[1][col] = BlockLt[2][col];
BlockLt[3][row] = BlockLt[2][row] + 1;
BlockLt[3][col] = BlockLt[2][col];
L2 = 1;
break;
case 1:
BlockLt[0][row] = BlockLt[2][row] + 1;
BlockLt[0][col] = BlockLt[2][col] + 1;
BlockLt[1][row] = BlockLt[2][row];
BlockLt[1][col] = BlockLt[2][col] + 1;
BlockLt[3][row] = BlockLt[2][row];
BlockLt[3][col] = BlockLt[2][col] - 1;
L2 = 2;
break;
case 2:
BlockLt[0][row] = BlockLt[2][row] + 1;
BlockLt[0][col] = BlockLt[2][col] - 1;
BlockLt[1][row] = BlockLt[2][row] + 1;
BlockLt[1][col] = BlockLt[2][col];
BlockLt[3][row] = BlockLt[2][row] - 1;
BlockLt[3][col] = BlockLt[2][col];
L2 = 3;
break;
case 3:
BlockLt[0][row] = BlockLt[2][row] - 1;
BlockLt[0][col] = BlockLt[2][col] - 1;
BlockLt[1][row] = BlockLt[2][row];
BlockLt[1][col] = BlockLt[2][col] - 1;
BlockLt[3][row] = BlockLt[2][row];
BlockLt[3][col] = BlockLt[2][col] + 1;
L2 = 0;
break;
}
break;
case 3://T状
switch (T)
{
case 0:
BlockLt[0][row] = BlockLt[1][row];
BlockLt[0][col] = BlockLt[1][col]-1;
BlockLt[2][row] = BlockLt[1][row];
BlockLt[2][col] = BlockLt[1][col]+1;
BlockLt[3][row] = BlockLt[1][row]-1;
BlockLt[3][col] = BlockLt[1][col];
T = 1;
break;
case 1:
BlockLt[0][row] = BlockLt[1][row]-1;
BlockLt[0][col] = BlockLt[1][col];
BlockLt[2][row] = BlockLt[1][row]+1;
BlockLt[2][col] = BlockLt[1][col];
BlockLt[3][row] = BlockLt[1][row];
BlockLt[3][col] = BlockLt[1][col]+1;
T = 2;
break;
case 2:
BlockLt[0][row] = BlockLt[1][row];
BlockLt[0][col] = BlockLt[1][col]+1;
BlockLt[2][row] = BlockLt[1][row];
BlockLt[2][col] = BlockLt[1][col]-1;
BlockLt[3][row] = BlockLt[1][row]+1;
BlockLt[3][col] = BlockLt[1][col];
T = 3;
break;
case 3:
BlockLt[0][row] = BlockLt[1][row]+1;
BlockLt[0][col] = BlockLt[1][col];
BlockLt[2][row] = BlockLt[1][row]-1;
BlockLt[2][col] = BlockLt[1][col];
BlockLt[3][row] = BlockLt[1][row];
BlockLt[3][col] = BlockLt[1][col]-1;
T = 0;
break;
}
break;
}
}
char Ismove(char n)//判断是否能下降和左右移动
{
p = 'T';
switch (n)
{
case 'L':
for (int i = 0; i < BLOCK_X; ++i)
{
if ((MapArr[BlockLt[i][row]][BlockLt[i][col] - 1] != BLock_null))
{
p = 'F';
break;
}
}
break;
case 'R':
for (int i = 0; i < BLOCK_X; ++i)
{
if ((MapArr[BlockLt[i][row]][BlockLt[i][col] + 1] != BLock_null))
{
p = 'F';
break;
}
}
break;
case 'D':
for (int i = 0; i < BLOCK_X; ++i)
{
if ((MapArr[BlockLt[i][row] + 1][BlockLt[i][col]] != BLock_null) && BlockLt[i][row] != 5)
{
p = 'F';
break;
}
}
break;
}
return p;
}
void Remove(int block)//复写操作
{
for (int i = 0; i < BLOCK_X; ++i)
{
if (BlockLt[i][row] == 6)
MapArr[BlockLt[i][row]][BlockLt[i][col]] = BLock_Frame;
else if ((BlockLt[i][row] > 6))
MapArr[BlockLt[i][row]][BlockLt[i][col]] = block;
}
}
char Key()//获取玩家操作
{
if (_kbhit())
{
return _getch();
}
return 0;
}
void BlockDown()//块下落
{
for (int i = 0; i < BLOCK_X; ++i)
{
BlockLt[i][row]++;
}
}
void BlockMoveAndChange()//块的运动
{
switch (Key())
{
case 'W':
case 'w':
if (IsBlockchange() == 'T')
ChangeBlock();
break;
case 'A':
case 'a':
if (Ismove('L') == 'T')
{
for (int i = 0; i < BLOCK_X; ++i)//左移
{
BlockLt[i][col]--;
}
}
break;
case 'S'://快速下
case 's':
if (Ismove('D') == 'T')
{
BlockDown();
}
break;
case 'D':
case 'd':
if (Ismove('R') == 'T')
{
for (int i = 0; i < BLOCK_X; ++i)//右移
{
BlockLt[i][col]++;
}
}
break;
}
}
void InitBlock(char x,char l,char L, char L2, char T ,char arr[][2],int m,int n)//初始化块
{
switch (x)
{
case 0://长条状,两种形态
switch (l)
{
case 0:
arr[0][row] = m;
arr[0][col] = n - 1;
arr[1][row] = m;
arr[1][col] = n;
arr[2][row] = m;
arr[2][col] = n + 1;
arr[3][row] = m;
arr[3][col] = n + 2;
break;
case 1:
arr[0][row] = m - 1;
arr[0][col] = n;
arr[1][row] = m;
arr[1][col] = n;
arr[2][row] = m + 1;
arr[2][col] = n;
arr[3][row] = m + 2;
arr[3][col] = n;
break;
}
break;
case 1://L状,4种形态
switch (L)
{
case 0:
arr[0][row] = m + 1;
arr[0][col] = n + 1;
arr[1][row] = m + 1;
arr[1][col] = n;
arr[2][row] = m;
arr[2][col] = n;
arr[3][row] = m - 1;
arr[3][col] = n;
break;
case 1:
arr[0][row] = m + 1;
arr[0][col] = n - 1;
arr[1][row] = m;
arr[1][col] = n - 1;
arr[2][row] = m;
arr[2][col] = n;
arr[3][row] = m;
arr[3][col] = n + 1;
break;
case 2:
arr[0][row] = m - 1;
arr[0][col] = n - 1;
arr[1][row] = m - 1;
arr[1][col] = n;
arr[2][row] = m;
arr[2][col] = n;
arr[3][row] = m + 1;
arr[3][col] = n;
break;
case 3:
arr[0][row] = m - 1;
arr[0][col] = n + 1;
arr[1][row] = m;
arr[1][col] = n + 1;
arr[2][row] = m;
arr[2][col] = n;
arr[3][row] = m;
arr[3][col] = n - 1;
break;
}
break;
case 2://反7 4种状态         
switch (L2)
{
case 0:
arr[0][row] = m - 1;
arr[0][col] = n - 1;
arr[1][row] = m;
arr[1][col] = n - 1;
arr[2][row] = m;
arr[2][col] = n;
arr[3][row] = m;
arr[3][col] = n + 1;
break;
case 1:
arr[0][row] = m - 1;
arr[0][col] = n + 1;
arr[1][row] = m - 1;
arr[1][col] = n;
arr[2][row] = m;
arr[2][col] = n;
arr[3][row] = m + 1;
arr[3][col] = n;
break;
case 2:
arr[0][row] = m + 1;
arr[0][col] = n + 1;
arr[1][row] = m;
arr[1][col] = n + 1;
arr[2][row] = m;
arr[2][col] = n;
arr[3][row] = m;
arr[3][col] = n - 1;
break;
case 3:
arr[0][row] = m + 1;
arr[0][col] = n - 1;
arr[1][row] = m + 1;
arr[1][col] = n;
arr[2][row] = m;
arr[2][col] = n;
arr[3][row] = m - 1;
arr[3][col] = n;
break;
}
break;
case 3://T状.四种形态
switch (T)
{
case 0:
arr[0][row] = m + 1;
arr[0][col] = n;
arr[1][row] = m;
arr[1][col] = n;
arr[2][row] = m - 1;
arr[2][col] = n;
arr[3][row] = m;
arr[3][col] = n - 1;
break;
case 1:
arr[0][row] = m;
arr[0][col] = n - 1;
arr[1][row] = m;
arr[1][col] = n;
arr[2][row] = m;
arr[2][col] = n + 1;
arr[3][row] = m - 1;
arr[3][col] = n;
break;
case 2:
arr[0][row] = m - 1;
arr[0][col] = n;
arr[1][row] = m;
arr[1][col] = n;
arr[2][row] = m + 1;
arr[2][col] = n;
arr[3][row] = m;
arr[3][col] = n + 1;
break;
case 3:
arr[0][row] = m;
arr[0][col] = n + 1;
arr[1][row] = m;
arr[1][col] = n;
arr[2][row] = m;
arr[2][col] = n - 1;
arr[3][row] = m + 1;
arr[3][col] = n;
break;
}
break;
case 4://田字状,一种形态 
arr[0][row] = m;
arr[0][col] = originallocationY - 1;
arr[1][row] = m;
arr[1][col] = originallocationY;
arr[2][row] = m - 1;
arr[2][col] = originallocationY - 1;
arr[3][row] = m - 1;
arr[3][col] = originallocationY;
break;
}
}
void ShowNextMatch(int m, int n,int block)//显示当前块
{
char Show[BLOCK_X][BLOCK_Y] = { 0 };
InitBlock(x1,l1,L1,L21,T1,Show, m, n);
for (int i = 0; i < 4; ++i)
{
MapArr[Show[i][row]][Show[i][col]] = block;
}
}
void DraWing(int x,int y)//渲染
{
//for (int i = 0; i < x; ++i)
//{
// for (int j = 0; j < y; ++j)
// {
// switch (MapArr[i][j])
// {
// case 0:
// printf("  ");
// break;
// case 1:
// printf("█");
// break;
// case 2:
// printf("□");
// break;
// }
// }
// putchar('\n');
//}
BeginBatchDraw();
for (int i = 0; i < ROW_AR; ++i)
{
for (int j = 0; j < COL_AR; ++j)
{
switch (MapArr[i][j])
{
case BLock_null:
//printf("  ");
setfillcolor(RGB(0, 0, 0));
setlinecolor(RGB(0, 0, 0));
fillrectangle(j * 25, i * 25, (j + 1) * 25, (i + i) * 25);
break;
case BLock_Frame:
//printf("* ");
setfillcolor(RGB(0, 0, 255));
setlinecolor(RGB(255, 255, 255));
fillrectangle(j * 25, i * 25, (j + 1) * 25, (i + i) * 25);
break;
case BLock_BL:
//printf("# ");
setfillcolor(RGB(255, 0, 0));
setlinecolor(RGB(255, 255, 255));
fillrectangle(j * 25, i * 25, (j + 1) * 25, (i + i) * 25);
break;
}
}
//printf("\n");
}
EndBatchDraw();
}
void Random()//随机两组数据一组显示下个方块,一组初始化当前方块
{
if (v != 'F')
{
x = rand() % 5;
l = rand() % 2;
L = rand() % 4;
L2 = rand() % 4;
T = rand() % 4;
v = 'F';
}
else
{
x = x1;
l = l1;
L = L1;
L2 = L21;
T = T1;
}
x1 = rand() % 5;
l1 = rand() % 2;
L1 = rand() % 4;
L21 = rand() % 4;
T1 = rand() % 4;
ShowNextMatch(2, 6, BLock_BL);//显示
}
void InitGame()//初始化游戏
{
for (int i = 0; i < ROW_AR; ++i)
{
for (int j = 0; j < COL_AR; ++j)
{
if ((i == 6 || j == 0 || i == ROW_AR-1 || j == COL_AR-1)&&i>5)
{
MapArr[i][j] = BLock_Frame;
}
else
{
MapArr[i][j] = BLock_null;
}
}
}
Random();
InitBlock(x,l,L,L2,T,BlockLt,originallocationX, originallocationY);
start = clock();
}


char Update()//更新
{
Remove(BLock_null);//覆盖消除
BlockMoveAndChange();//变形
end = clock();
if (end - start >= 300)//再移动
{
if (Ismove('D') == 'T')
{
BlockDown();
}
else
{
for (int i = 0; i < 6; ++i)
{
for (int j = 0; j < 14; ++j)
{
MapArr[i][j] = BLock_null;
}
}
Random();
if (GameOver())
{
return 'F';
}
Remove(BLock_BL);//写入
Score();//计数消的行数
InitBlock(x,l,L,L2,T,BlockLt, originallocationX, originallocationY);//重新初始化块
}
start = end;
}
Remove(BLock_BL);//再次写入
return 0;
}
int main()
{
srand((unsigned)time(NULL));
initgraph(350, 700);
InitGame();//初始化游戏
while (1)
{
if (Update()=='F')
{
break;
}//更新
DraWing(ROW_AR, COL_AR);//渲染
/* printf("得分为   :%d", NUM);*/
/*system("cls");*/
}   
//printf("game over\n");
//system("pause");
closegraph();
return 0;
}
/* *游戏说明:此为我边学边做的,但有很多的BUG,参照了我从网上下载的游戏方块设计 * 一、游戏的BUG * 1、提示分数那地方,玩过游戏后,长了分数后,再玩时,后面的数据没清掉 * 2、重级BUG:当在游戏过程中,切换了一个旁边的后,再切换回来后, * 刚才的方块不显了,而且游戏区的数据也不见了。 * 3、我在刚开始做时,没有要窗口上的关闭,现在想要,但不知道怎么加。 * 4、如果用鼠标点了菜单后,再回到游戏区,数据方块又不见了。 * * 二、此游戏没有版权,可以乱改,反正我也是在学习,谢谢那些无私的网友们,不过 * 请你们下次提交上来的源程序有个说明好不好,看得我头都大了,流程图也没得, * 设计说明也没有,完全看源代码,很费力的!谢谢对新人的支持。 * * 三、如果那位高手愿意,请收我为徒弟吧,我学过c/c++、数据结构、编译原理、操作系统等( * 计算机专业的),但对于VC这个大东西来说,,好像一点用也没有,现在在边学边做,门不好入呀! * * 四、请高手们帮帮我,请给分析一下问题在哪,谢谢,我对VC还不是很清楚,在文件目录下 * 有设计时的流程图。设计说明我没有写,我是针对每一个流程图模块来设计和编码的。 * * 五、在游戏中,我加了很多注释,以方便理解,主要的代码都在CChileView.h、CChileView.CPP中 * 我想的是,如果新人也想看看的话,可能理解起来快点。不过有点乱,编码中有些冗余。没来 * 得及改。如果你改好了,请给我一份,我想学学。谢谢! * *================================================================================================ * *编译环境: * 1、操作系统 :WindowsXP SP2 * 2、编译器 :Visual C++ 8.0 * *包含文件:所有源文件都在此。 * * *编译参考:此目录下有一个文件名为:Russia.sln的文件,用Visual C++ 8.0 打开,直接就可编译 * 此游戏是我编译通过后,才压缩的。如果编译不了,请联系我,下面有我的QQ和email。 * * *其它事宜:如果还有什么问题我没有提到的,请联系我,愿向你学习。 * *================================================================================================ * *Version :BUG Edtion * *Aauthor :lin_liu60 * *E-mail :lin_liu60@163.com * *QQ :994165 (网名:刘羽峰) * *Date :2006/9/27 * */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值