俄罗斯方块.docx
- 文档编号:18010973
- 上传时间:2023-08-05
- 格式:DOCX
- 页数:18
- 大小:30.19KB
俄罗斯方块.docx
《俄罗斯方块.docx》由会员分享,可在线阅读,更多相关《俄罗斯方块.docx(18页珍藏版)》请在冰点文库上搜索。
俄罗斯方块
俄罗斯方块(Tetris)VC源代码
0
作者:
krissi
童年的经典游戏~~ 。
界面上没有做额外的修饰,需要的可以自己增加。
执行效果如下:
代码如下:
////////////////////////////////////////////
//程序名称:
俄罗斯方块
//编译环境:
VisualC++6.0/2010,EasyX_v20130322(beta)
//程序编写:
krissi
//更新记录:
2010-12-18zhaoh1987@编写
// 2011-9-28yw80@修改了下落超时的逻辑
//
#include
#include
#include
/////////////////////////////////////////////
//定义常量、枚举量、结构体、全局变量
/////////////////////////////////////////////
#defineWIDTH10//游戏区宽度
#defineHEIGHT22//游戏区高度
#defineSIZE20//每个游戏区单位的实际像素
//定义操作类型
enumCMD
{
CMD_ROTATE,//方块旋转
CMD_LEFT,CMD_RIGHT,CMD_DOWN,//方块左、右、下移动
CMD_SINK,//方块沉底
CMD_QUIT//退出游戏
};
//定义绘制方块的方法
enumDRAW
{
SHOW,//显示方块
HIDE,//隐藏方块
FIX//固定方块
};
//定义七种俄罗斯方块
structBLOCK
{
WORDdir[4];//方块的四个旋转状态
COLORREFcolor;//方块的颜色
}g_Blocks[7]={{0x0F00,0x4444,0x0F00,0x4444,RED},//I
{0x0660,0x0660,0x0660,0x0660,BLUE},//口
{0x4460,0x02E0,0x0622,0x0740,MAGENTA},//L
{0x2260,0x0E20,0x0644,0x0470,YELLOW},//反L
{0x0C60,0x2640,0x0C60,0x2640,CYAN},//Z
{0x0360,0x4620,0x0360,0x4620,GREEN},//反Z
{0x4E00,0x4C40,0x0E40,0x4640,BROWN}};//T
//定义当前方块、下一个方块的信息
structBLOCKINFO
{
byteid;//方块ID
charx,y;//方块在游戏区中的坐标
bytedir:
2;//方向
}g_CurBlock,g_NextBlock;
//定义游戏区
BYTEg_World[WIDTH][HEIGHT]={0};
/////////////////////////////////////////////
//函数声明
/////////////////////////////////////////////
voidInit();//初始化游戏
voidQuit();//退出游戏
voidNewGame();//开始新游戏
voidGameOver();//结束游戏
CMDGetCmd();//获取控制命令
voidDispatchCmd(CMD_cmd);//分发控制命令
voidNewBlock();//生成新的方块
boolCheckBlock(BLOCKINFO_block);//检测指定方块是否可以放下
voidDrawBlock(BLOCKINFO_block,DRAW_draw=SHOW);//画方块
voidOnRotate();//旋转方块
voidOnLeft();//左移方块
voidOnRight();//右移方块
voidOnDown();//下移方块
voidOnSink();//沉底方块
/////////////////////////////////////////////
//函数定义
/////////////////////////////////////////////
//主函数
voidmain()
{
Init();
CMDc;
while(true)
{
c=GetCmd();
DispatchCmd(c);
//按退出时,显示对话框咨询用户是否退出
if(c==CMD_QUIT)
{
HWNDwnd=GetHWnd();
if(MessageBox(wnd,_T("您要退出游戏吗?
"),_T("提醒"),MB_OKCANCEL|MB_ICONQUESTION)==IDOK)
Quit();
}
}
}
//初始化游戏
voidInit()
{
initgraph(640,480);
srand((unsigned)time(NULL));
//显示操作说明
setfont(14,0,_T("宋体"));
outtextxy(20,330,_T("操作说明"));
outtextxy(20,350,_T("上:
旋转"));
outtextxy(20,370,_T("左:
左移"));
outtextxy(20,390,_T("右:
右移"));
outtextxy(20,410,_T("下:
下移"));
outtextxy(20,430,_T("空格:
沉底"));
outtextxy(20,450,_T("ESC:
退出"));
//设置坐标原点
setorigin(220,20);
//绘制游戏区边界
rectangle(-1,-1,WIDTH*SIZE,HEIGHT*SIZE);
rectangle((WIDTH+1)*SIZE-1,-1,(WIDTH+5)*SIZE,4*SIZE);
//开始新游戏
NewGame();
}
//退出游戏
voidQuit()
{
closegraph();
exit(0);
}
//开始新游戏
voidNewGame()
{
//清空游戏区
setfillcolor(BLACK);
bar(0,0,WIDTH*SIZE-1,HEIGHT*SIZE-1);
ZeroMemory(g_World,WIDTH*HEIGHT);
//生成下一个方块
g_NextBlock.id=rand()%7;
g_NextBlock.dir=rand()%4;
g_NextBlock.x=WIDTH+1;
g_NextBlock.y=HEIGHT-1;
//获取新方块
NewBlock();
}
//结束游戏
voidGameOver()
{
HWNDwnd=GetHWnd();
if(MessageBox(wnd,_T("游戏结束。
\n您想重新来一局吗?
"),_T("游戏结束"),MB_YESNO|MB_ICONQUESTION)==IDYES)
NewGame();
else
Quit();
}
//获取控制命令
DWORDm_oldtime;
CMDGetCmd()
{
//获取控制值
while(true)
{
//如果超时,自动下落一格
DWORDnewtime=GetTickCount();
if(newtime-m_oldtime>=500)
{
m_oldtime=newtime;
returnCMD_DOWN;
}
//如果有按键,返回按键对应的功能
if(kbhit())
{
switch(getch())
{
case'w':
case'W':
returnCMD_ROTATE;
case'a':
case'A':
returnCMD_LEFT;
case'd':
case'D':
returnCMD_RIGHT;
case's':
case'S':
returnCMD_DOWN;
case27:
returnCMD_QUIT;
case'':
returnCMD_SINK;
case0:
case0xE0:
switch(getch())
{
case72:
returnCMD_ROTATE;
case75:
returnCMD_LEFT;
case77:
returnCMD_RIGHT;
case80:
returnCMD_DOWN;
}
}
}
//延时(降低CPU占用率)
Sleep(20);
}
}
//分发控制命令
voidDispatchCmd(CMD_cmd)
{
switch(_cmd)
{
caseCMD_ROTATE:
OnRotate();break;
caseCMD_LEFT:
OnLeft();break;
caseCMD_RIGHT:
OnRight();break;
caseCMD_DOWN:
OnDown();break;
caseCMD_SINK:
OnSink();break;
caseCMD_QUIT:
break;
}
}
//生成新的方块
voidNewBlock()
{
g_CurBlock.id=g_NextBlock.id,g_NextBlock.id=rand()%7;
g_CurBlock.dir=g_NextBlock.dir,g_NextBlock.dir=rand()%4;
g_CurBlock.x=(WIDTH-4)/2;
g_CurBlock.y=HEIGHT+2;
//下移新方块直到有局部显示
WORDc=g_Blocks[g_CurBlock.id].dir[g_CurBlock.dir];
while((c&0xF)==0)
{
g_CurBlock.y--;
c>>=4;
}
//绘制新方块
DrawBlock(g_CurBlock);
//绘制下一个方块
setfillcolor(BLACK);
bar((WIDTH+1)*SIZE,0,(WIDTH+5)*SIZE-1,4*SIZE-1);
DrawBlock(g_NextBlock);
//设置计时器,用于判断自动下落
m_oldtime=GetTickCount();
}
//画方块
voidDrawBlock(BLOCKINFO_block,DRAW_draw)
{
WORDb=g_Blocks[_block.id].dir[_block.dir];
intx,y;
intcolor=BLACK;
switch(_draw)
{
caseSHOW:
color=g_Blocks[_block.id].color;break;
caseHIDE:
color=BLACK;break;
caseFIX:
BYTEr=GetRValue(g_Blocks[_block.id].color)*2/3;
BYTEg=GetGValue(g_Blocks[_block.id].color)*2/3;
BYTEb=GetBValue(g_Blocks[_block.id].color)*2/3;
color=RGB(r,g,b);
break;
}
setfillcolor(color);
for(inti=0;i<16;i++)
{
if(b&0x8000)
{
x=_block.x+i%4;
y=_block.y-i/4;
if(y { if(_draw! =HIDE) bar3d(x*SIZE+2,(HEIGHT-y-1)*SIZE+2,(x+1)*SIZE-4,(HEIGHT-y)*SIZE-4,3,true); else bar(x*SIZE,(HEIGHT-y-1)*SIZE,(x+1)*SIZE-1,(HEIGHT-y)*SIZE-1); } } b<<=1; } } //检测指定方块是否可以放下 boolCheckBlock(BLOCKINFO_block) { WORDb=g_Blocks[_block.id].dir[_block.dir]; intx,y; for(inti=0;i<16;i++) { if(b&0x8000) { x=_block.x+i%4; y=_block.y-i/4; if((x<0)||(x>=WIDTH)||(y<0)) returnfalse; if((y returnfalse; } b<<=1; } returntrue; } //旋转方块 voidOnRotate() { //获取可以旋转的x偏移量 intdx; BLOCKINFOtmp=g_CurBlock; tmp.dir++;if(CheckBlock(tmp)){dx=0;gotorotate;} tmp.x=g_CurBlock.x-1;if(CheckBlock(tmp)){dx=-1;gotorotate;} tmp.x=g_CurBlock.x+1;if(CheckBlock(tmp)){dx=1;gotorotate;} tmp.x=g_CurBlock.x-2;if(CheckBlock(tmp)){dx=-2;gotorotate;} tmp.x=g_CurBlock.x+2;if(CheckBlock(tmp)){dx=2;gotorotate;} return; rotate: //旋转 DrawBlock(g_CurBlock,HIDE); g_CurBlock.dir++; g_CurBlock.x+=dx; DrawBlock(g_CurBlock); } //左移方块 voidOnLeft() { BLOCKINFOtmp=g_CurBlock; tmp.x--; if(CheckBlock(tmp)) { DrawBlock(g_CurBlock,HIDE); g_CurBlock.x--; DrawBlock(g_CurBlock); } } //右移方块 voidOnRight() { BLOCKINFOtmp=g_CurBlock; tmp.x++; if(CheckBlock(tmp)) { DrawBlock(g_CurBlock,HIDE); g_CurBlock.x++; DrawBlock(g_CurBlock); } } //下移方块 voidOnDown() { BLOCKINFOtmp=g_CurBlock; tmp.y--; if(CheckBlock(tmp)) { DrawBlock(g_CurBlock,HIDE); g_CurBlock.y--; DrawBlock(g_CurBlock); } else OnSink();//不可下移时,执行“沉底方块”操作 } //沉底方块 voidOnSink() { inti,x,y; //连续下移方块 DrawBlock(g_CurBlock,HIDE); BLOCKINFOtmp=g_CurBlock; tmp.y--; while(CheckBlock(tmp)) { g_CurBlock.y--; tmp.y--; } DrawBlock(g_CurBlock,FIX); //固定方块在游戏区 WORDb=g_Blocks[g_CurBlock.id].dir[g_CurBlock.dir]; for(i=0;i<16;i++) { if(b&0x8000) { if(g_CurBlock.y-i/4>=HEIGHT) {//如果方块的固定位置超出高度,结束游戏 GameOver(); return; } else g_World[g_CurBlock.x+i%4][g_CurBlock.y-i/4]=1; } b<<=1; } //检查是否需要消掉行,并标记 introw[4]={0}; boolbRow=false; for(y=g_CurBlock.y;y>=max(g_CurBlock.y-3,0);y--) { i=0; for(x=0;x if(g_World[x][y]==1) i++; if(i==WIDTH) { bRow=true; row[g_CurBlock.y-y]=1; setfillcolor(WHITE); setfillstyle(DIAGCROSS2_FILL); bar(0,(HEIGHT-y-1)*SIZE+SIZE/2-2,WIDTH*SIZE-1,(HEIGHT-y-1)*SIZE+SIZE/2+2); setfillstyle(SOLID_FILL); } } if(bRow) { //延时200毫秒 Sleep(200); //擦掉刚才标记的行 IMAGEimg; for(i=0;i<4;i++) { if(row[i]) { for(y=g_CurBlock.y-i+1;y for(x=0;x { g_World[x][y-1]=g_World[x][y]; g_World[x][y]=0; } getimage(&img,0,0,WIDTH*SIZE,(HEIGHT-(g_CurBlock.y-i+1))*SIZE); putimage(0,SIZE,&img); } } } //产生新方块 NewBlock(); }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 俄罗斯方块
![提示](https://static.bingdoc.com/images/bang_tan.gif)