【C语言】控制台界面的俄罗斯方块
来源:http://www.0xaa55.com/thread-1477-1-1.html转载请注明出处。
也就是所谓“DOS窗口”的控制台程序。我写的这个是全平台的,只用了C语言的库(不过貌似有些函数好像只有微软有提供,比如_sleep这种,不过可以将其定义为void _sleep(int iTime){};来解决跨平台的兼容性问题(但是这么弄会导致这个游戏很占CPU)。
我当时写这个程序的时候我忘记了它应该叫“Tetris”而不是“Russian Blocks”(中式英语,大概可以翻译成“俄罗斯的方块”)
代码不算很复杂,一些游戏逻辑判断的函数,一些画面的逻辑判断的函数,以及整个游戏的组织函数。#include<stdint.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#include<string.h>
#include<signal.h>
const int8_t g_BlockTypes[]=//方块组合
{
//格式:1个字节表示组合所需方块数,后面的字节是偏移坐标
1,
0,0, // 口
4,
0,0,
0,1, // 口口
1,0, // 口口
1,1,
4,
-1,0,
0,0, // 口口口口
1,0,
2,0,
4,
-1,1,
-1,0, // 口口口
0,0, // 口
1,0,
4,
-1,-1,
-1,0, // 口
0,0, // 口口口
1,0,
4,
-1,0,
0,0, // 口口口
1,0, // 口
0,-1,
4,
-1,0,
0,0, // 口口
0,1, // 口口
1,1,
4,
1,0,
0,0, // 口口
0,1, // 口口
-1,1,
0
};
//目前共8种组合
#define NbTypes 8
typedef int32_t pos_t,*pos_p;//坐标
typedef uint8_t block_t,*block_p;//方块状态
//方块缓冲区
#define BlockBufWidth 12
#define BlockBufHeight 23
block_t g_BlockBuf={0};
#define ReDirToBBuf(x,y) ((x)+(y)*BlockBufWidth)
//游戏界面显示的字符
#define BlockChar '\xB1'
#define BlankChar ' '
#define ClientAreaChar '\xDB'
//当前方块的中心位置
pos_t g_CurX,g_CurY;
uint8_t g_CurRot;//当前旋转
uint8_t g_GameOver;
uint8_t g_QuitGame;
uint16_t g_CurrentBlock;
typedef uint32_t score_t,*score_p;//用来计算分数的变量类型
#define MaxScore 999999999L
score_t g_Score=0,g_HighScore=0;
//方块视口的位置
#define VP_X 20
#define VP_Y 1
#define VP_W (BlockBufWidth*2)
#define VP_H BlockBufHeight
//“下一个方块”的提示框位置
#define NextBlockAreaX 2
#define NextBlockAreaY 2
#define NextBlockAreaW 12
#define NextBlockAreaH 6
#define NextBlockAreaR (NextBlockAreaX+NextBlockAreaW)
#define NextBlockAreaB (NextBlockAreaY+NextBlockAreaH)
#define NextBlockAreaCX (NextBlockAreaX+NextBlockAreaW/2)
#define NextBlockAreaCY (NextBlockAreaY+NextBlockAreaH/2)
#define ShowScoreAreaX 2
#define ShowScoreAreaY 9
#define ShowScoreAreaW 12
#define ShowScoreAreaH 4
#define ShowScoreAreaR (ShowScoreAreaX+ShowScoreAreaW)
#define ShowScoreAreaB (ShowScoreAreaY+ShowScoreAreaH)
#define GameOverDlgBoxAreaX 20
#define GameOverDlgBoxAreaY 4
#define GameOverDlgBoxAreaW 40
#define GameOverDlgBoxAreaH 10
#define GameOverDlgBoxAreaR (GameOverDlgBoxAreaX+GameOverDlgBoxAreaW)
#define GameOverDlgBoxAreaB (GameOverDlgBoxAreaY+GameOverDlgBoxAreaH)
#define Rot_0 0
#define Rot_90 1
#define Rot_180 2
#define Rot_270 3
uint8_t g_NextRot;//当前旋转
uint16_t g_NextBlock;
clock_t g_CurClock=0;//当前时钟计数
clock_t g_Interval=1000;//每次移动的时钟数
//“画板”
#define ScrBufWidth 80
#define ScrBufHeight 25
#define ScrBufSize (ScrBufWidth*ScrBufHeight)
char g_ScrBuf={0};//显示缓冲区
#define ReDirToScr(x,y) ((x)+(y)*ScrBufWidth)
void TranslateRotateCoord(pos_t x,pos_t y,uint8_t Rot,pos_p px,pos_p py);
void ClearBuf(char cChar);
void DrawStaticBlocks(char cBL,char cBR,char cBlank);
uint16_t GetBlockTypeData(uint16_t BlockType);
void DrawFallingComb(pos_t x,pos_t y,uint16_t BlockData,uint8_t Rot,char cBL,char cBR);
void InitGame();
void NewGame();
void MoveLeft();
void MoveRight();
void Rotate();
void FixBlock();
void NewBlock();
void FallDown();
void CheckupBlockFall();
void EraseLines();
void GameOverBox();
void FrameMove();
void InitScrBuf();
void DrawNextBlockType();
void DrawCurrentFallingBlock();
void RenderScene();
void FlushScene();
void GameMenu();
void GameLoop();
//=============================================================================
//函数:TranslateRotateCoord
//描述:翻译相对旋转坐标
//-----------------------------------------------------------------------------
void TranslateRotateCoord(pos_t x,pos_t y,uint8_t Rot,pos_p px,pos_p py)
{
//判断是哪种旋转
switch(Rot)
{
default://默认:不旋转
*px=x;*py=y;
break;
case Rot_90://旋转90度,x=-y y=x
*px=-y;*py=x;
break;
case Rot_180://旋转180度,x=-x y=-y
*px=-x;*py=-y;
break;
case Rot_270://旋转270度,x=y y=-x
*px=y;*py=-x;
break;
}
}
//=============================================================================
//函数:ClearBuf
//描述:将“画板”用cChar填充
//-----------------------------------------------------------------------------
void ClearBuf(char cChar)
{
memset(g_ScrBuf,cChar,sizeof(g_ScrBuf));//每一行都用cChar来填
}
//=============================================================================
//函数:FillRectangle
//描述:在“画板”上填充举行
//-----------------------------------------------------------------------------
void FillRectangle(pos_t x,pos_t y,pos_t r,pos_t b,char cChar)
{
pos_t cbLine,i;
if(x>ScrBufWidth || y>ScrBufHeight)
return;
if(r>ScrBufWidth)
r=ScrBufWidth;
if(b>ScrBufHeight)
b=ScrBufHeight;
cbLine=r-x;
i=ReDirToScr(x,y);//“画布”上的对应位置
for(;y<b;y++)
{
memset(&g_ScrBuf,cChar,cbLine);//每一行都用cChar来填
i+=ScrBufWidth;//转到下一行
}
}
//=============================================================================
//函数:DrawStaticBlocks
//描述:在“画板”上将所有的静态方块都绘制上去(也就是画好已经落下的方块)
//-----------------------------------------------------------------------------
void DrawStaticBlocks
(
char cBL,//方块左半边的字符
char cBR,//方块右半边的字符
char cBlank//没有方块时的字符
)
{
pos_t x,y,i;
//擦除背景
FillRectangle(VP_X,VP_Y,VP_X+BlockBufWidth*2,VP_Y+BlockBufHeight,cBlank);
//一行行的画方块
for(y=i=0;y<BlockBufHeight;y++)//遍历每一行方块槽
{
for(x=0;x<BlockBufWidth;x++,i++)//遍历每一列方块槽
{
pos_t uIndex=ReDirToScr(VP_X+x*2,VP_Y+y);//方块在“画布”对应位置
//方块槽每个格子相当于画布上的两个字符
//一个字符是长方形,两个就是正方形了
if(g_BlockBuf)//有方块
{
g_ScrBuf=cBL;//方块左半边的字符
g_ScrBuf=cBR;//方块右半边的字符
}
}
}
}
//=============================================================================
//函数:GetBlockTypeData
//描述:取得方块类型数据
//-----------------------------------------------------------------------------
uint16_t GetBlockTypeData(uint16_t BlockType)
{
uint16_t BlockIndex=0;
while(BlockType--)
BlockIndex+=g_BlockTypes*2+1;
return BlockIndex;
}
//=============================================================================
//函数:DrawFallingComb
//描述:在“画板”上绘制落下的方块组合
//-----------------------------------------------------------------------------
void DrawFallingComb
(
pos_t x,//画布上的位置横坐标
pos_t y,//画布上的位置纵坐标
uint16_t BlockType,//方块种类
uint8_t Rot,//方向
char cBL,//方块左半边的字符
char cBR//方块右半边的字符
)
{
uint16_t BlockIndex=GetBlockTypeData(BlockType);
uint8_t NbBlocks=g_BlockTypes;
BlockIndex++;//这是坐标索引
while(NbBlocks--)
{
pos_t BlockX,BlockY,uIndex;//这是转换后的相对坐标
TranslateRotateCoord(g_BlockTypes,
g_BlockTypes,
Rot,&BlockX,&BlockY);
//取得绝对坐标
BlockX=BlockX*2+x;
BlockY=BlockY+y;
uIndex=ReDirToScr(BlockX,BlockY);//方块在“画布”对应位置
g_ScrBuf=cBL;//方块左半边的字符
g_ScrBuf=cBR;//方块右半边的字符
BlockIndex+=2;
}
}
//=============================================================================
//函数:DrawString
//描述:“画板”上写字
//-----------------------------------------------------------------------------
void DrawString(pos_t x,pos_t y,char*szString)
{
size_t cbString=strlen(szString);
memcpy(&g_ScrBuf,szString,cbString);
}
//=============================================================================
//函数:InitGame
//描述:初始化游戏
//-----------------------------------------------------------------------------
void InitGame()
{
g_CurClock=clock();
srand((unsigned)g_CurClock);
InitScrBuf();
g_HighScore=0;
}
//=============================================================================
//函数:NewGame
//描述:开始新游戏
//-----------------------------------------------------------------------------
void NewGame()
{
g_Score=0;
g_QuitGame=0;
g_GameOver=0;
g_NextRot=rand()%4;
g_NextBlock=rand()%NbTypes;
memset(g_BlockBuf,0,sizeof(g_BlockBuf));
NewBlock();
RenderScene();
FlushScene();
}
//=============================================================================
//函数:MoveLeft
//描述:将方块往左移
//-----------------------------------------------------------------------------
void MoveLeft()
{
uint16_t BlockIndex=GetBlockTypeData(g_CurrentBlock);
uint8_t NbBlocks=g_BlockTypes;
BlockIndex++;//这是坐标索引
g_CurX--;//先左移
while(NbBlocks--)
{
pos_t BlockX,BlockY;//这是转换后的相对坐标
TranslateRotateCoord(g_BlockTypes,
g_BlockTypes,
g_CurRot,&BlockX,&BlockY);
//左边没有空间可以移动,退出。
if(g_CurX+BlockX<0 ||
g_BlockBuf)
{
g_CurX++;//移回来
return;
}
BlockIndex+=2;
}
}
//=============================================================================
//函数:MoveRight
//描述:将方块往右移
//-----------------------------------------------------------------------------
void MoveRight()
{
uint16_t BlockIndex=GetBlockTypeData(g_CurrentBlock);
uint8_t NbBlocks=g_BlockTypes;
BlockIndex++;//这是坐标索引
g_CurX++;
while(NbBlocks--)
{
pos_t BlockX,BlockY;//这是转换后的相对坐标
TranslateRotateCoord(g_BlockTypes,
g_BlockTypes,
g_CurRot,&BlockX,&BlockY);
//左边没有空间可以移动,退出。
if(g_CurX+BlockX>BlockBufWidth-1||
g_BlockBuf)
{
g_CurX--;
return;
}
BlockIndex+=2;
}
}
//=============================================================================
//函数:RotateForward
//描述:向前旋转,不带判断
//-----------------------------------------------------------------------------
static void RotateForward()
{
switch(g_CurRot)
{
default: g_CurRot=Rot_90;break;
case Rot_90: g_CurRot=Rot_180;break;
case Rot_180: g_CurRot=Rot_270;break;
case Rot_270: g_CurRot=Rot_0;break;
}
}
//=============================================================================
//函数:RotateBackward
//描述:向后旋转,不带判断
//-----------------------------------------------------------------------------
static void RotateBackward()
{
switch(g_CurRot)
{
default: g_CurRot=Rot_270;break;
case Rot_270: g_CurRot=Rot_180;break;
case Rot_180: g_CurRot=Rot_90;break;
case Rot_90: g_CurRot=Rot_0;break;
}
}
//=============================================================================
//函数:Rotate
//描述:旋转方块
//-----------------------------------------------------------------------------
void Rotate()
{
uint16_t BlockIndex=GetBlockTypeData(g_CurrentBlock);
uint8_t NbBlocks=g_BlockTypes;
BlockIndex++;//这是坐标索引
//先向前旋转
RotateForward();
while(NbBlocks--)
{
pos_t BlockX,BlockY;//这是转换后的相对坐标
TranslateRotateCoord(g_BlockTypes,
g_BlockTypes,
g_CurRot,&BlockX,&BlockY);
//如果旋转后有方块会跑出,那么就转回来。
BlockX+=g_CurX;
BlockY+=g_CurY;
if(BlockX<0 || BlockY<0 ||
BlockX>BlockBufWidth-1 ||
BlockY>BlockBufHeight-1 ||
g_BlockBuf)
{
RotateBackward();
return;
}
BlockIndex+=2;
}
}
//=============================================================================
//函数:FixBlock
//描述:将方块固定到槽里
//-----------------------------------------------------------------------------
void FixBlock()
{
uint16_t BlockIndex=GetBlockTypeData(g_CurrentBlock);
uint8_t NbBlocks=g_BlockTypes;
BlockIndex++;//这是坐标索引
while(NbBlocks--)
{
pos_t BlockX,BlockY;//这是转换后的相对坐标
TranslateRotateCoord(g_BlockTypes,
g_BlockTypes,
g_CurRot,&BlockX,&BlockY);
g_BlockBuf=1;
BlockIndex+=2;
}
}
//=============================================================================
//函数:NewBlock
//描述:设置下一个方块
//-----------------------------------------------------------------------------
void NewBlock()
{
uint16_t BlockIndex,BIStart;
uint8_t NbBlocks,i;
g_CurrentBlock=g_NextBlock;
g_CurRot=g_NextRot;
g_NextBlock=rand()%NbTypes;
g_CurX=BlockBufWidth/2;
g_CurY=0;
g_NextRot=rand()%4;
BlockIndex=GetBlockTypeData(g_CurrentBlock);
NbBlocks=g_BlockTypes;
BIStart=++BlockIndex;//这是坐标索引
for(i=0;i<NbBlocks;i++)
{
pos_t BlockX,BlockY;//这是转换后的相对坐标
TranslateRotateCoord(g_BlockTypes,
g_BlockTypes,
g_CurRot,&BlockX,&BlockY);
//先保证方块完全进入区域
if(g_CurY+BlockY<0)
g_CurY-=BlockY;
BlockIndex+=2;
}
//然后判断是否有重合方块
BlockIndex=BIStart;
for(i=0;i<NbBlocks;i++)
{
pos_t BlockX,BlockY;//这是转换后的相对坐标
TranslateRotateCoord(g_BlockTypes,
g_BlockTypes,
g_CurRot,&BlockX,&BlockY);
//如果现在的位置有方块重合了
if(g_BlockBuf)
g_GameOver=1;
BlockIndex+=2;
}
}
//=============================================================================
//函数:FallDown
//描述:坠下方块
//-----------------------------------------------------------------------------
void FallDown()
{
g_CurY++;
}
//=============================================================================
//函数:CheckupBlockFall
//描述:检查方块状态(当前方块是否已经沉底)
//-----------------------------------------------------------------------------
void CheckupBlockFall()
{
uint16_t BlockIndex=GetBlockTypeData(g_CurrentBlock);
uint8_t NbBlocks=g_BlockTypes;
BlockIndex++;//这是坐标索引
while(NbBlocks--)
{
pos_t BlockX,BlockY;//这是转换后的相对坐标
TranslateRotateCoord(g_BlockTypes,
g_BlockTypes,
g_CurRot,&BlockX,&BlockY);
if(g_CurY+BlockY>BlockBufHeight-1 ||
g_BlockBuf)
{
g_CurY--;
FixBlock();
NewBlock();
}
BlockIndex+=2;
}
}
//=============================================================================
//函数:FallDownFixedBlocks
//描述:从第0行开始到第y行坠下固定的方块
//-----------------------------------------------------------------------------
void FallDownFixedBlocks(pos_t y)
{
pos_t i;
if(!y)
return;
i=y*BlockBufWidth;
while(--y)
{
memcpy(&g_BlockBuf,&g_BlockBuf,BlockBufWidth*sizeof(block_t));
i-=BlockBufWidth;
}
}
//=============================================================================
//函数:EraseLines
//描述:消除填满的行
//-----------------------------------------------------------------------------
void EraseLines()
{
pos_t y,i,LineBlockIndex;
score_t AddScore=1;//加分(每多消除一行,多加一分)
uint8_t CouldNotErase;
//判断是否有已经填满的一行,并给用户统计积分
//从最后一行开始判断
y=BlockBufHeight-1;
LineBlockIndex=y*BlockBufWidth;
for(;y;y--,LineBlockIndex-=BlockBufWidth)
{
CouldNotErase=0;
for(i=0;i<BlockBufWidth;i++)
{
if(!g_BlockBuf)
{
CouldNotErase=1;
break;
}
}
if(!CouldNotErase)
{
FallDownFixedBlocks(y);
g_Score+=AddScore++;//加分到总分里,并且同时消除的行数会增加加分量
}
}
if(g_Score>g_HighScore)
g_HighScore=g_Score;//统计最高分
}
//=============================================================================
//函数:FrameMove
//描述:判断是否在降落的时候碰到已有的方块、计算积分等
//-----------------------------------------------------------------------------
void FrameMove()
{
char chKey;
for(;;_sleep(1))//节省CPU的游戏循环
{
if(clock()-g_CurClock>=g_Interval)//超时
{
//向下移动方块
g_CurY++;
g_CurClock=clock();//更新时钟
break;
}
if(_kbhit())
{
chKey=_getch();
switch(chKey)
{
case'W':
case'w':
Rotate();
break;
case'A':
case'a':
MoveLeft();
break;
case'S':
case's':
FallDown();
break;
case'D':
case'd':
MoveRight();
break;
}
break;
}
}
CheckupBlockFall();
EraseLines();
}
//=============================================================================
//函数:InitScrBuf
//描述:初始化“画板”
//-----------------------------------------------------------------------------
void InitScrBuf()
{
ClearBuf(ClientAreaChar);
}
//=============================================================================
//函数:DrawNextBlockType
//描述:在画布上绘制“下一个方块”
//-----------------------------------------------------------------------------
void DrawNextBlockType()
{
FillRectangle(NextBlockAreaX,NextBlockAreaY,
NextBlockAreaR,NextBlockAreaB,BlankChar);
DrawString(NextBlockAreaX,NextBlockAreaY," Next Block:");
DrawFallingComb(NextBlockAreaCX,NextBlockAreaCY,
g_NextBlock,g_NextRot,BlockChar,BlockChar);
}
//=============================================================================
//函数:DrawTotalScore
//描述:在画布上绘制“总分”
//-----------------------------------------------------------------------------
void DrawTotalScore()
{
char Buf;//字符串缓冲区
FillRectangle(ShowScoreAreaX,ShowScoreAreaY,
ShowScoreAreaR,ShowScoreAreaB,BlankChar);
DrawString(ShowScoreAreaX,ShowScoreAreaY,"Total score:");
sprintf(Buf,"%u",g_Score);
DrawString(ShowScoreAreaX,ShowScoreAreaY+1,Buf);
DrawString(ShowScoreAreaX,ShowScoreAreaY+2,"High score:");
sprintf(Buf,"%u",g_HighScore);
DrawString(ShowScoreAreaX,ShowScoreAreaY+3,Buf);
}
//=============================================================================
//函数:DrawCurrentFallingBlock
//描述:绘制当前正在掉落的方块
//-----------------------------------------------------------------------------
void DrawCurrentFallingBlock()
{
DrawFallingComb(VP_X+g_CurX*2,VP_Y+g_CurY,
g_CurrentBlock,g_CurRot,BlockChar,BlockChar);
}
//=============================================================================
//函数:RenderScene
//描述:渲染整个场景
//-----------------------------------------------------------------------------
void RenderScene()
{
ClearBuf(ClientAreaChar);
DrawNextBlockType();
DrawTotalScore();
DrawStaticBlocks(BlockChar,BlockChar,BlankChar);
DrawCurrentFallingBlock();
}
//=============================================================================
//函数:FlushScene
//描述:将场景显示出来
//-----------------------------------------------------------------------------
void FlushScene()
{
//强行换行
pos_t y,i;
for(y=0,i=0;y<ScrBufHeight-1;y++)
{
g_ScrBuf='\n';//然后在行末加一个换行符
i+=ScrBufWidth;//转到下一行
}
fputc('\n',stdout);//插入一个新行,以让“画板”从新行输出
fwrite(g_ScrBuf,1,ScrBufSize-1,stdout);//减去1是为了防止自动换行
}
//=============================================================================
//函数:GameMenu
//描述:游戏菜单
//-----------------------------------------------------------------------------
void GameMenu()
{
//清屏
system("cls");
//显示LOGO
fputs("\n"
" TTTTTTTTTTEEEEEEEEEETTTTTTTTTTRRRRRRRR IIIIIIIIII SSSSSSSS\n"
" TTTTTT EE EETTTTTT RR RR II SS SS\n"
" TT EEEE TT RR RR II SS\n"
" TT EEEEEE TT RRRRRR II SSSS\n"
" TT EEEE TT RRRR II SS\n"
" TT EE TT RR RR II SS\n"
" TT EE EE TT RR RR II SS SS\n"
" TTTTTT EEEEEEEEEE TTTTTT RRRRRRRRRRIIIIIIIIIISSSSSSSS\n"
" \n"
" BBBBBB YY YY 00000000 AAAAAAAAAAAA555555555555\n"
" BB BBYY YY::00 00 AAAAAAAA55 55\n"
" BBBBBB YY YY 00 00 AAAAAAAAAAAA555555555555\n"
" BB BB YYYYYY 00 00XXXXAAAAAAAA 55 55\n"
" BB BB YY::00 00 XX AAAAAAAA 55 55\n"
" BBBBBB YYYYYY 00000000XXXXAAAAAAAA555555555555\n"
"\n"
" http://www.0xaa55.com\n"
"\n",stdout);
//显示最高分
printf(" HIGH SCORE:%u\n\n",g_HighScore);
//闪烁显示“按键开始游戏”
for(;!g_QuitGame;_sleep(1))
{
if(clock()%1000 > 500)//根据时钟来判断显示字符还是抹掉字符
fputs(" Press 'B' to start the game.\r",stdout);
else
fputs(" \r",stdout);
//判断按键输入
if(_kbhit())
{
char ch=_getch();
if(ch=='B'||ch=='b')//B键开始游戏,其它键没用。Ctrl+C退出游戏。
{
NewGame();
break;
}
}
}
}
//=============================================================================
//函数:GameOverBox
//描述:显示“游戏结束”框
//-----------------------------------------------------------------------------
void GameOverBox()
{
uint8_t ShowScene=0;
char szBuf;
//渲染一次场景
RenderScene();
//画出对话框边框
FillRectangle(GameOverDlgBoxAreaX,GameOverDlgBoxAreaY,
GameOverDlgBoxAreaR,GameOverDlgBoxAreaB,ClientAreaChar);
FillRectangle(GameOverDlgBoxAreaX+2,GameOverDlgBoxAreaY+1,
GameOverDlgBoxAreaR-2,GameOverDlgBoxAreaB-1,BlankChar);
//显示字符串
DrawString(GameOverDlgBoxAreaX+2,GameOverDlgBoxAreaY+1,
"Game Over");
//显示分数
sprintf(szBuf,"Total score:%u",g_Score);
DrawString(GameOverDlgBoxAreaX+2,GameOverDlgBoxAreaY+3,szBuf);
//显示最高分
sprintf(szBuf,"High score:%u",g_HighScore);
DrawString(GameOverDlgBoxAreaX+2,GameOverDlgBoxAreaY+5,szBuf);
//闪烁提示按任意键继续,并判断按键
for(;;_sleep(10))
{
if(clock()%1000<500)
{
if(!ShowScene)
{
DrawString(GameOverDlgBoxAreaX+2,GameOverDlgBoxAreaY+7,
"Press 'C' to continue. . .");
//显示已经绘制好的场景
FlushScene();
ShowScene=1;//防止重复刷屏
}
}
else
{
if(ShowScene)
{
DrawString(GameOverDlgBoxAreaX+2,GameOverDlgBoxAreaY+7,
" ");
//显示已经绘制好的场景
FlushScene();
ShowScene=0;//防止重复刷屏
}
}
//如果按下了键,就退出这个循环
if(_kbhit())
{
char chKey=_getch();
if(chKey=='C'||chKey=='c')
break;
}
}
}
//=============================================================================
//函数:GameLoop
//描述:游戏逻辑循环
//-----------------------------------------------------------------------------
void GameLoop()
{
//游戏循环
while(!g_GameOver)
{
FrameMove();
RenderScene();
FlushScene();
}
//游戏结束
GameOverBox();
}
//=============================================================================
//函数:SigProc
//描述:信号处理程序
//-----------------------------------------------------------------------------
void SigProc(int Signal)
{
switch(Signal)
{
case SIGINT:
g_QuitGame=1;
break;
}
}
//=============================================================================
//函数:main
//描述:程序入口点
//-----------------------------------------------------------------------------
int main(int argc,char**Argv)
{
signal(SIGINT,SigProc);
system("chcp 437");
system("mode con cols=80 lines=25");
system("cls");
InitGame();
do
{
GameMenu();
if(g_QuitGame)
break;
GameLoop();
}while(!g_QuitGame);
return 0;
}BIN:
SRC:
其实名字应该叫Tetris。 棒棒哒!! 代码我要了。 先占个位置.. 坐标设计太有才了. 这样就可以很容易实现旋转了. 大赞
页:
[1]