共有回帖数 0 个
-
俄罗斯方块终于成型了,由于同时还在写其他项目,总是写着写着就思路中断了,看来写代码还是需要一气呵成。好啦,废话不多说,直接开喷,哦不,开讲^_^。

这次时间虽长,其实我是用心的,duang,做了一个动态的开始界面,注意是动态的哦,看来是不是像加了特技。

游戏主界面是这个样子的。
下面介绍一下游戏的玩法:
1 一个方块由4个格子组成,穷尽4个格子能够组成的所有图形,共有19种图形(方向不同也算是一种),19种图形分为7组分别是:

2 随机生成这19种方块中的一种,对这个方块可以进行左移,右移,或者按顺序改变成这个方块所在的组内的其他方块,共三种操作。
3 方块会不断的下落,碰到障碍物就停止下落,变成一个不再能操作的方块。
4 当落下的方块使得一行堆满时,就可以消去一行,并加分。
5 最终不能操作的方块的高度超过最大高度时,游戏失败。以上就是玩法,其实游戏都是根据玩法编写的,俄罗斯方块的玩法大家当然是知道的,总结玩法时其实就是在思考如何用代码实现这些玩法。
以下是游戏代码,这次的代码比较多,得有小一千行,不过这次我多写了一些函数声明,同时全局变量的声明也比较占地方。网页上黏代码看起来实在蛋疼,上传pdf版,自己下下来看哈:
#include "stdafx.h"
#include "Tetris.h"
#include windows.h
#include time.h
#include conio.h
#includestdlib.h
/************************************************************************
* 该工程完成得比较粗糙,还有很多功能没有实现,也还有些BUG没有更改。
* 针对该项目有任何意见,或不解的地方都欢迎大家在群里提出!!!
*
* 该工程以Visual Studio 2013编写,有可能其他版本的编译编译不过
* (1)工程属性-配置属性- 常规-平台工具集(当前编译器)
* (2)vs2013中加入了很多C11标准 比如 结构体,数组赋值 “{}”全赋值为0
/************************************************************************/
// 字体颜色
#define F_BLUE FOREGROUND_BLUE // 深蓝
#define F_H_BLUE 0x0001|0x0008 // 亮蓝
#define F_GREEN 0x0002 // 深绿
#define F_H_GREEN 0x0002|0x0008 // 亮绿
#define F_RED 0x0004 // 深红
#define F_H_RED 0x0004|0x0008 // 亮红
#define F_YELLOW 0x0002|0x0004 // 深黄
#define F_H_YELLOW 0x0002|0x0004|0x0008 // 亮黄
#define F_PURPLE 0x0001|0x0004 // 深紫
#define F_H_PURPLE 0x0001|0x0004|0x0008 // 亮紫
#define F_CYAN 0x0002|0x0004 // 深青
#define F_H_CYAN 0x0002|0x0004|0x0008 // 亮青
#define F_WHITE 0x0004|0x0002|0x0001 //白
#define F_H_WHITE 0x0004|0x0002|0x0001|0x0008 //空白
#define WALL 1 //墙
#define SHAPE 2 //方块
int g_Map[40][30] = {};
//记录19种图形的结构体,这个思维数组初学者还是不太容易理解的,这里可能需要仔细的想一想
char g_aCubeShape[7][4][4][4] = {
{
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 1, 1, 0, 0 }, // ■■
{ 1, 1, 0, 0 } // ■■
},
},
{
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 } //■■■■
},
{
{ 0, 1, 0, 0 }, //■
{ 0, 1, 0, 0 }, //■
{ 0, 1, 0, 0 }, //■
{ 0, 1, 0, 0 }, //■
},
},
{
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 1, 1, 0 }, // ■■
{ 1, 1, 0, 0 } //■■
},
{
{ 0, 0, 0, 0 },
{ 1, 0, 0, 0 }, //■
{ 1, 1, 0, 0 }, //■■
{ 0, 1, 0, 0 } // ■
}
},
{
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 1, 1, 0, 0 }, //■■
{ 0, 1, 1, 0 } // ■■
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 0, 0 }, // ■
{ 1, 1, 0, 0 }, //■■
{ 1, 0, 0, 0 } //■
}
},
{
{
{ 0, 0, 0, 0 },
{ 1, 1, 0, 0 }, //■■
{ 0, 1, 0, 0 }, // ■
{ 0, 1, 0, 0 } // ■
},
{
{ 0, 0, 0, 0 },
{ 1, 0, 0, 0 }, //■
{ 1, 0, 0, 0 }, //■
{ 1, 1, 0, 0 } //■■
},
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 1, 1, 1, 0 }, //■■■
{ 1, 0, 0, 0 } //■
},
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 1, 0 }, // ■
{ 1, 1, 1, 0 } //■■■
}
},
{
{
{ 0, 0, 0, 0 },
{ 1, 1, 0, 0 }, //■■
{ 1, 0, 0, 0 }, //■
{ 1, 0, 0, 0 } //■
},
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 1, 1, 1, 0 }, //■■■
{ 0, 0, 1, 0 } // ■
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 0, 0 }, // ■
{ 0, 1, 0, 0 }, // ■
{ 1, 1, 0, 0 } //■■
},
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 1, 0 }, // ■
{ 1, 1, 1, 0 } //■■■
}
},
{
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 1, 0, 0 }, // ■
{ 1, 1, 1, 0 } //■■■
},
{
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 1, 1, 1, 0 }, //■■■
{ 0, 1, 0, 0 } // ■
},
{
{ 0, 0, 0, 0 },
{ 1, 0, 0, 0 }, //■
{ 1, 1, 0, 0 }, //■■
{ 1, 0, 0, 0 } //■
},
{
{ 0, 0, 0, 0 },
{ 0, 1, 0, 0 }, // ■
{ 1, 1, 0, 0 }, //■■
{ 0, 1, 0, 0 } // ■
}
},
};
typedef struct _RANDOM
{
int Dir; //随机出方向 0-3
int Shape; //随机出形状 0-4
int Colour; //随机出颜色 0-11
}RANDOM, *pRANDOM;
typedef struct _SHAPEINFO
{
BOOL IsObj; //是否正在移动
COORD pos; //方块坐标
int Dir; //方块方向
int NewShape; //当前方块的形状
DWORD Colour; //方块颜色
}SHAPEINFO,*pSHAPEINFO;
static int g_Score = 0; //当前分数
static int g_Grade = 0; //当前等级
///////////////////////////////////////////////////////////////////////////////////
//该函数作用:隐藏光标,设置光标位置,设置字符颜色
void WriteChar(int Wide, int High, char*m_pszChar, int m_wArr);
//该函数作用:欢迎界面
void DrawPicture(void);
// 该函数作用:初始化地图边界
void InitMap();
//该函数作用:在屏幕上打印地图边框
void DrawMap();
//该函数作用:设置控制台窗口大中及缓冲区大小
void LniSehomepage();
//该函数作用:当前行被填满时,消除当前行,并且将该行以上的图案向下移动一行
void ClsShaep(int PosY);
//该函数作用:判断该行是否填满
BOOL CountScore();
//该函数作用:产生随机数,随机第几类方块,该方块当前方向,随机方块颜色
void Random(pRANDOM pRand);
//该函数作用:擦除当前方块 在大数组中及屏幕上
void ClcShanp(SHAPEINFO Shape);
//该函数作用:画当前方块 在大数组中及屏幕上
void DrawShanp(SHAPEINFO Shape);
//该函数作用:将所有已经落下的不能移动的方块都在数组中赋值为墙,主要方便我判断碰撞
void DrawShanpBuff(SHAPEINFO Shape);
//该函数作用:判断方块是否能移动
BOOL IsMove(SHAPEINFO Shape);
//该函数作用:在地图右侧显示将要出现的图案
void DrawOffsideInfo(SHAPEINFOShape);
//该函数作用:相当于画,擦,判段方块都在这里面
BOOL CollideEngine(pSHAPEINFO Shape, pSHAPEINFO OldShape);
int _tmain(int argc, _TCHAR* argv[])
{
sinA:
LniSehomepage();
InitMap();
DrawMap();
COORD Pos = { 15, 3 }; //初始化方块出生点(右下角为中心点)
RANDOM m_Rand = {};
Random(&m_Rand); //随机
SHAPEINFO m_NewShape = { true, Pos, 0, 1, m_Rand.Colour}; //当前出现的方块
Random(&m_Rand);
SHAPEINFO m_FutShape = { true, Pos, 0, 1, m_Rand.Colour}; //下一次将要出现的方块
SHAPEINFO m_OldShape = m_NewShape;
DrawShanp(m_NewShape); //绘制方块图案
DrawOffsideInfo(m_FutShape); //绘制在右侧
int iTime = 10000;
while (true)
{
if (!m_NewShape.IsObj) //标志为假时,则重新生成图案
{
DrawShanpBuff(m_OldShape); //方块在数组中赋值为墙
if (!CountScore()) //判断该行是否填满,并计分
{
break;
}
m_NewShape = m_FutShape;
m_OldShape = m_FutShape;
Random(&m_Rand);
m_FutShape.Dir = 0;
m_FutShape.NewShape =m_Rand.Shape;
m_FutShape.Colour =m_Rand.Colour;
DrawOffsideInfo(m_FutShape); //绘制在右侧
DrawShanp(m_NewShape); //绘制方块图案
}
iTime--; //当iTime为假时,则自动向下移动一格
if (!iTime)
{
m_NewShape.pos.Y++;
CollideEngine(&m_NewShape,&m_OldShape); //相当于画,擦,判段方块
iTime = 10000;
}
if (!_kbhit()) //没有键盘消息时,回到循环开始位置
{
continue;
}
char ch = _getch();
switch (ch)
{
case 'W':
case 'w': //变换方向
{
m_NewShape.Dir++;
//方块,不用变化
if (0 == m_NewShape.NewShape)
{
m_NewShape.Dir = 0;
}
//竖条,有两种变化
else if (1 ==m_NewShape.NewShape)
{
if (m_NewShape.Dir 1)
{
m_NewShape.Dir = 0;
}
}
//Z字型,有两种变化
else if (2 ==m_NewShape.NewShape)
{
if (m_NewShape.Dir 1)
{
m_NewShape.Dir = 0;
}
}
//倒Z字型,有两种变化
else if (3 ==m_NewShape.NewShape)
{
if (m_NewShape.Dir 1)
{
m_NewShape.Dir = 0;
}
}
//其余的都是四种变化
else
{
if (m_NewShape.Dir 3)
{
m_NewShape.Dir = 0;
}
}
}
break;
case 'S':
case 's':
{
m_NewShape.pos.Y++;
}
break;
case 'A':
case 'a':
{
m_NewShape.pos.X--;
}
break;
case 'D':
case 'd':
{
m_NewShape.pos.X++;
}
break;
case ' ':
{
}
break;
default:
break;
}
CollideEngine(&m_NewShape,&m_OldShape);
}
//最后结束游戏未完成
system("cls");
WriteChar(15, 20, "游戏结束!", F_H_RED);
while (!(_kbhit()))
{
WriteChar(26, 25, "PRESS ANY KEY TO CONTINUE", F_H_RED);
Sleep(300);
WriteChar(26, 25, " ", F_H_WHITE);
Sleep(300);
}
system("cls");
goto sinA;
return 0;
}
/************************************************************************
* 该函数作用:隐藏光标,设置光标位置,设置字符颜色
* 参数:
* wide: X坐标
* High: Y坐标
* m_pszChar: 字符
* m_wArr: 颜色
* 返回值:
* void
/************************************************************************/
void WriteChar(int Wide, int High, char*m_pszChar, int m_wArr)
{
CONSOLE_CURSOR_INFO m_cci;
m_cci.bVisible =FALSE; // 将该标志设为false 表示不显示光标
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &m_cci); // 设置某个控制台屏幕缓冲区的光标属性,如大小,是否可见
COORD loc;
loc.X = Wide * 2; // Y坐标的缓冲区是X的2倍,在控制台属性里能体现出来
loc.Y = High;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), m_wArr); // 设置某个控制台屏幕缓冲区中的字符的颜色和背景色
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), loc); // 设置光标位置
printf("%s",m_pszChar);
}
/************************************************************************
* 该函数作用:初始化地图边界
* 参数:
* void
* 返回值:
* void
/************************************************************************/
void InitMap()
{
memset(g_Map, 0, sizeof(g_Map)); //将数组清空
for (int Y =0; Y 40;Y++)
{
for (int X =0; X 30;X++)
{
if ((0 ==Y)||(39==Y)||(0 ==X)||(29 ==X))
{
g_Map[Y][X] =WALL;
}
}
}
}
/************************************************************************
* 该函数作用:在屏幕上打印地图边框
* 参数:
* void
* 返回值:
* void
/************************************************************************/
void DrawMap()
{
for (int Y = 0;Y 40; Y++)
{
for (int X = 0;X 30; X++)
{
if (1 == g_Map[Y][X]) //根据数组中的值打印相应图案
{
WriteChar(X, Y, "■", F_WHITE);
}
else
{
WriteChar(X, Y, " ", F_H_WHITE);
}
}
printf("n");
}
//打印右侧信息
WriteChar(32, 2, "分数:", F_YELLOW);
WriteChar(32, 4, "等级:", F_YELLOW);
char buffer[6] = {};
g_Score = 0;
sprintf_s(buffer, sizeof(buffer), "%d", g_Score); //将int型数据转换成char类型
WriteChar(36, 2, buffer, F_H_RED);
char buffer1[6] = {};
g_Grade = 0;
sprintf_s(buffer1, sizeof(buffer1), "%d", g_Grade);
WriteChar(36, 4, buffer1,F_H_RED);
}
/************************************************************************
* 该函数作用:欢迎界面
* 参数:
* void
* 返回值:
* void
/************************************************************************/
void DrawPicture(void)
{
//COORD 结构体保存图型开始位置(X,Y)
COORD PosDown ={ 9, 0 }; //下
COORD PosRight ={ 39, 11 }; //左
COORD PosLeft ={ 0,29 }; //右
COORD PosUp ={ 29, 41 }; //上
while (true)
{
Sleep(100); //休眠库函数(包含stdlib.h)
//↓
if (PosDown.Y PosLeft.Y)
{
WriteChar(PosDown.X,PosDown.Y, "┃┃", F_RED);
PosDown.Y++;
}
//←
if (PosRight.X PosDown.X+1)
{
WriteChar(PosRight.X,PosRight.Y, "━", F_RED);
WriteChar(PosRight.X,PosRight.Y + 1, "━", F_RED);
PosRight.X--;
}
//→
if (PosLeft.X PosUp.X)
{
WriteChar(PosLeft.X,PosLeft.Y, "━", F_RED);
WriteChar(PosLeft.X,PosLeft.Y + 1, "━", F_RED);
PosLeft.X++;
}
//↑
if (PosUp.Y PosRight.Y+1)
{
WriteChar(PosUp.X,PosUp.Y, "┃┃", F_RED);
PosUp.Y--;
}
else
break;
}
Sleep(1000); //消屏库函数
system("cls");
WriteChar(3, 11, "■■■■■ ■■■■■ ■■■■■ ■■■■ ■■■■■ ■■■■", F_RED);
WriteChar(3, 12, "■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■", F_RED);
WriteChar(3, 13, " ■ ■ ■ ■ ■ ■ ■ ■ ", F_RED);
WriteChar(3, 14, " ■ ■■■ ■ ■■■ ■ ■■ ", F_RED);
WriteChar(3, 15, " ■ ■ ■ ■ ■ ■ ■ ■ ", F_RED);
WriteChar(3, 16, " ■ ■ ■ ■ ■ ■ ■", F_RED);
WriteChar(3, 17, " ■ ■ ■ ■ ■ ■ ■ ■ ■", F_RED);
WriteChar(3, 18, " ■■■ ■■■■■ ■■■ ■■■ ■■■■■■■ ■■■■", F_RED);
WriteChar(25, 20, "--by--QQ群:420297600", F_H_RED);
//_kbhit() 判断是否有键盘输入,有则返回1,否则返回0 库函数(conio.h)
//_getch() 接收从键盘上输入的一个字符,不需要回车 0x0d:表示回车键 库函数(conio.h)
while (!(_kbhit() && _getch() == 0x0d))
{
WriteChar(26, 25, "PRESS ENTER TO START", F_H_RED);
Sleep(300);
WriteChar(26, 25, " ", F_H_WHITE);
Sleep(300);
}
system("cls");
}
/************************************************************************
* 该函数作用:设置控制台窗口大中及缓冲区大小
* 参数:
* void
* 返回值:
* void
/************************************************************************/
void LniSehomepage()
{
//具体参考“控制台编程”
SetConsoleTitle(L"Tetris"); //设置控制台标题
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); //输出句柄 (STD_INPUT_HANDLE)为输入宏
COORD BufferSize ={ 80, 42 }; //初始化窗口缓冲区大小
SMALL_RECT srctWindow ={ 0, 0, 80 - 1, 42- 1 }; //初始化窗口大小
SetConsoleScreenBufferSize(hStdOut,BufferSize); //设置窗口的缓冲区
SetConsoleWindowInfo(hStdOut, true, &srctWindow); //创建窗口大小
DrawPicture();
}
/************************************************************************
* 该函数作用:产生随机数,随机第几类方块,该方块当前方向,随机方块颜色
* 参数:
* pRANDOM 随机数结构体指针 因为要将结果返回
* 返回值:
* void
/************************************************************************/
void Random(pRANDOM pRand)
{
//库函数 (time.h)
srand((unsigned)time(NULL)); //随机数 产生一个随机种子
pRand-Shape = rand() % 5; //方块形状
pRand-Dir = rand() % 3; //方块方向
pRand-Colour = rand() % 11; //方块颜色
while (true)
{
srand((unsigned)time(NULL)); //随机数
//因为第一种型状的图案只有一个方向
if (0 ==pRand-Shape) //■■
{ //■■
pRand-Dir =0;
break;
}
if (1 ==pRand-Shape&&pRand-Dir1) //同上
{
pRand-Dir =rand() % 4; //方块方向
}
else
break;
}
//随机分配方块颜色
switch (pRand-Colour)
{
case 0:
case 1:
pRand-Colour =F_BLUE;
break;
case 2:
pRand-Colour = F_H_BLUE;
break;
case 3:
pRand-Colour = F_GREEN;
break;
case 4:
pRand-Colour = F_H_GREEN;
break;
case 5:
pRand-Colour = F_RED;
break;
case 6:
pRand-Colour = F_H_RED;
break;
case 7:
pRand-Colour = F_YELLOW;
break;
case 8:
pRand-Colour = F_H_YELLOW;
break;
case 9:
pRand-Colour = F_PURPLE;
break;
case 10:
pRand-Colour = F_H_PURPLE;
break;
case 11:
pRand-Colour = F_CYAN;
break;
}
}
/************************************************************************
* 该函数作用:擦除当前方块 在大数组中及屏幕上
* 参数:
* SHAPEINFO 方块数结构体
* 返回值:
* void
/************************************************************************/
void ClcShanp(SHAPEINFO Shape)
{
//以右下角为中心点 依次从左上角开始循环遍历16个点
for (int Y = Shape.pos.Y - 3; Y = Shape.pos.Y;Y++)
{
for (int X =Shape.pos.X - 3; X = Shape.pos.X;X++)
{
//定义的方块型状结构体,根据该数组对应的值擦除大数组中的值及屏幕上的字符
if (g_aCubeShape[Shape.NewShape][Shape.Dir][Y - Shape.pos.Y+ 3][X - Shape.pos.X + 3])
{
g_Map[Y][X] = 0;
WriteChar(X, Y, " ", F_H_WHITE);
}
}
}
}
/************************************************************************
* 该函数作用:画当前方块 在大数组中及屏幕上
* 参数:
* SHAPEINFO 方块数结构体
* 返回值:
* void
/************************************************************************/
void DrawShanp(SHAPEINFO Shape)
{
//该函数同擦除函数 和擦除函数几乎没差别 唯一差别在传入的坐标值的不一样
//擦除是擦除老坐标,画则画新坐标
for (int Y = Shape.pos.Y - 3; Y = Shape.pos.Y;Y++)
{
for (int X = Shape.pos.X - 3; X = Shape.pos.X;X++)
{
if (g_aCubeShape[Shape.NewShape][Shape.Dir][Y - Shape.pos.Y+ 3][X - Shape.pos.X + 3])
{
g_Map[Y][X] = SHAPE;
WriteChar(X, Y, "■", Shape.Colour);
}
}
}
//有可能方块图案出生时将边框覆盖掉。
for (int X =12;X = 15;X++)
{
g_Map[0][X] = WALL;
WriteChar(X, 0, "■", F_WHITE);
}
}
/************************************************************************
* 该函数作用:将所有已经落下的不能移动的方块都在数组中赋值为墙,主要方便我判断碰撞
* 参数:
* SHAPEINFO 方块数结构体
* 返回值:
* void
/************************************************************************/
void DrawShanpBuff(SHAPEINFO Shape)
{
for (int Y = Shape.pos.Y - 3; Y = Shape.pos.Y;Y++)
{
for (int X = Shape.pos.X - 3; X = Shape.pos.X;X++)
{
if (g_aCubeShape[Shape.NewShape][Shape.Dir][Y - Shape.pos.Y+ 3][X - Shape.pos.X + 3])
{
WriteChar(X, Y, "■", F_H_GREEN);
g_Map[Y][X] = WALL; //方块在数组中赋值为墙
}
}
}
}
/************************************************************************
* 该函数作用:判断方块是否能移动
* 参数:
* SHAPEINFO 方块数结构体
* 返回值:
* BOOL 能移动返回true,否则返回false
/************************************************************************/
BOOL IsMove(SHAPEINFO Shape)
{
for (int Y = Shape.pos.Y; Y = Shape.pos.Y - 3; Y--)
{
for (int X =Shape.pos.X - 3; X = Shape.pos.X;X++)
{
//1.数组当前位置有值
//2.方块型状数组对应的点有值
if (1 == g_Map[Y][X] &&g_aCubeShape[Shape.NewShape][Shape.Dir][Y- Shape.pos.Y + 3][X - Shape.pos.X + 3])
{
return FALSE;
}
}
}
return TRUE;
}
/************************************************************************
* 该函数作用:当前行被填满时,消除当前行,并且将该行以上的图案向下移动一行
* 参数:
* int PosY 当前Y坐标
* 返回值:
* void
/************************************************************************/
void ClsShaep(int PosY)
{
//从最后一行开始 Y=38
//二维数组第一个下标表示行,第二个下标表示列。
//此工程中 行都以'Y'表示,列以'X'表示
for (int X = 1;X 29; X++)
{
WriteChar(X, PosY, "■", F_RED); //该行以满,用红色表示一下
}
Sleep(50);
for (int X = 1;X 29 ;X++)
{
g_Map[PosY][X] = 0;
WriteChar(X, PosY, " ", F_H_WHITE); //消空该行
}
//将以满的行以上的图案向下移动一格
for (int X = 1;X 29; X++)
{
for (int Y = PosY - 1; Y 3; Y--)
{
if (!g_Map[Y][X])
{
break;
}
for (int J = Y +1; J = 38; J++)
{
if (!g_Map[J][X])
{
g_Map[Y][X] = 0;
WriteChar(X, Y, " ", F_H_WHITE);
g_Map[J][X] = WALL;
WriteChar(X, J, "■", F_H_GREEN);
continue;
}
break;
}
}
}
//计分及等级
g_Score += 50;
switch (g_Score / 100)
{
case 3:
g_Grade++;
break;
case 8:
g_Grade++;
break;
case 15:
g_Grade++;
break;
case 24:
g_Grade++;
break;
case 35:
g_Grade++;
break;
case 50:
g_Grade++;
break;
case 70:
g_Grade++;
break;
case 95:
g_Grade++;
break;
case 175:
g_Grade++;
break;
case 230:
g_Grade++;
break;
}
}
/************************************************************************
* 该函数作用:判断该行是否填满
* 参数:
* void
* 返回值:
* BOOL
/************************************************************************/
BOOL CountScore()
{
for (int Y = 38;Y 3;Y--)
{
sig:
int iCount = 0;
int X = 1;
for (; X 28;X++)
{
for (int J = 1;J 28;J++)
{
if (1 == g_Map[4][J])
{
return FALSE;
}
}
if (!g_Map[Y][X])
{
break;
}
iCount++;
}
//当iCount为什27时,则表示填满
if (iCount == 27)
{
ClsShaep(Y);
Y = 38;
goto sig;
}
}
//显示到右侧
char buffer[6] = {};
sprintf_s(buffer, sizeof(buffer), "%d", g_Score);
WriteChar(36, 2, buffer, F_H_RED);
char buffer1[6] = {};
sprintf_s(buffer1, sizeof(buffer1), "%d", g_Grade);
WriteChar(36, 4, buffer1,F_H_RED);
return TRUE;
}
/************************************************************************
* 该函数作用:相当于画,擦,判段方块都在这里面
* 参数:
* pSHAPEINFO Shape 当前方块的信息 以向下移动,或方向有变化
* pSHAPEINFO OldShape 上一次方块的信息
* 返回值:
* BOOL 能移动返回true,否则返回false
/************************************************************************/
BOOL CollideEngine(pSHAPEINFO Shape, pSHAPEINFO OldShape)
{
if (IsMove(*Shape)) //判断是否能移动
{
ClcShanp(*OldShape); //擦除之前的方块
DrawShanp(*Shape); //画新的方块
*OldShape =*Shape; //更新信息
return TRUE;
}
//当前如果是往左右移动刚好也不能移动时,应该让其继续向下移动
//将坐标 Y++ 在判断是否能移动
SHAPEINFO obj =*OldShape;
obj.pos.Y++;
if (IsMove(obj))
{
*Shape =*OldShape;
return TRUE;
}
//如果上面两种情况都为假时,则将该标志标为false
//以便生成新的图案
Shape-IsObj =0;
return FALSE;
}
/************************************************************************
* 该函数作用:在地图右侧显示将要出现的图案
* 参数:
* SHAPEINFO Shape 当前方块的信息
* 返回值:
* void
/************************************************************************/
void DrawOffsideInfo(SHAPEINFO Shape)
{
COORD pos ={ 36, 15 };
for (int Y=pos.Y; Y =pos.Y - 3; Y--)
{
for (int X=pos.X; X =pos.X - 3; X--)
{
WriteChar(X, Y, " ", F_H_WHITE);
if (g_aCubeShape[Shape.NewShape][Shape.Dir][pos.Y - Y][pos.X-X])
{
WriteChar(X, Y, "■", Shape.Colour);
}
}
}
}
楼主 2015-06-20 18:24 回复
Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号
意见反馈 |
关于直线 |
版权声明 |
会员须知