精选俄罗斯方块C++课程设计报告Word文档下载推荐.docx
《精选俄罗斯方块C++课程设计报告Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《精选俄罗斯方块C++课程设计报告Word文档下载推荐.docx(20页珍藏版)》请在冰豆网上搜索。
![精选俄罗斯方块C++课程设计报告Word文档下载推荐.docx](https://file1.bdocx.com/fileroot1/2022-11/27/77c32b40-d295-4404-82f8-e6309e4ca55b/77c32b40-d295-4404-82f8-e6309e4ca55b1.gif)
voidOnRotate();
//旋转方块
voidOnLeft();
//左移方块
voidOnRight();
//右移方块
voidOnDown();
//下移方块
voidOnSink(CGAME&
);
//沉底方块
BLOCKINFO&
CurBlock();
NextBlock();
游戏控制类〔CGame〕
Private:
VoidDispatchControl(CTRL);
voidInitGame();
//初始化游戏
VoidStart_Game();
//开始游戏
voidGame_Over();
//游戏结束
voidNewGame();
//新游戏
voidQuit_Game();
//退出游戏
CTRLGetControl(bool_onlyresettimer=false);
//获取控制命令
在主函数中〔按照2.1中框图〕,先通过控制类初始化游戏,再通过随机时间函数获得一个随机数,该随机数确定一个方块,即用该随机数产生一个ID从而确定产生的为方块。
然后从键盘取得各种操作信号,通过控类函数对操作信号进行分发、处理,进而控制方块的行为改变。
与此同时,监控游戏区中已有方块的状态,一旦满足消行即进行消行控制,同时进行计分和等级划分,而如果游戏区已满那么游戏结束,弹出提示。
而对界面和方块的展现主要通过第三方软件EasyX实现,通过其画图位置的改变与时间的结合到达方块视觉移动的效果。
2.3、定义方块的数据结构
方块是本游戏的根本要素,对于方块的设计,本游戏用4*4的矩阵画出来,在相应的位置置为‘1’和‘0’以实现各种方块的形状,以“立L形〞为例如下:
1
而在程序设计中那么赋予各种根本方块一个不同的十六进制ID即可表示该方块,如“立7形〞其ID为[0x4460],再与其其他变形组合和着色分配即可得到各种L形ID的集合{0x4460,0x02E0,0x0622,0x0740,MAGENTA};
其他各种方块类似设计。
具体清单如下:
{{0x0F00,0x4444,0x0F00,0x4444,RED},//I
{0x0660,0x0660,0x0660,0x0660,BLUE},//口
{0x4460,0x02E0,0x0622,0x0740,CYAN},//L蓝绿色
{0x2260,0x0E20,0x0644,0x0470,GREEN},//反L
{0x0C60,0x2640,0x0C60,0x2640,BROWN},//Z
{0x0360,0x4620,0x0360,0x4620,YELLOW},//反Z
{0x4E00,0x4C40,0x0E40,0x4640,MAGENTA}};
//T品红
2.4、方块的变形
方块要实现变形,其实就是通过EasyX画出不同的图形来实现的,当然乱画是不行的,而为了控制其变形的情况,必须设定相应的图形描述,本程序使用的是不同图形的不同ID码表示的方法来实在方块的描述的。
能过键盘接收变形指令〔即向上键〕,将所得信号传递给信号接收函数,再通过信号处理函数改变当前方块的ID值,最后根据新的ID值画出新的图形,此时即实在了方块的变形。
2.5、定时处理机制
为了提高游戏的易控性和自动性,定时机制是很有必要的。
经过定时器的设置后,这里通过利用控制程序跳到定时器的时间的处理函数去实现,当固定时间片间隔到达后,先检测当前下坠物是否已经到达了底部,不是那么进行下坠物向下移动一个单位的操作,是那么到底后产生一个新的“下一个下坠物〞,并代替旧的,将原先旧的“下一个下坠物〞用作当前激活状态下正在使用的下坠物,并对使用后的一些状态进行检测:
是否马上到达底部,使那么进行销行操作;
是否在到达底部的同时到达游戏区域的顶部,从而判定游戏是否因违规而结束,弹出相应对话框供用户选择是否继续重新开始。
图3.2.2装载方块
视图类通过不同十六进制ID来记录下坠物的类型,共有七种形状,并从7种方块中随机抽取图形。
而ID除了记录下坠物的类型外,还需记录其当前的变形状态。
在产生新的下一个下坠物前,需要先将当前状态物的记录和旧的下一个下坠物保存下来,然后用随机函数Random()产生一个最大值不大于指定值的随机正整数,将这个新生成的正整数用作新的“下一个下坠物〞的形状值。
三、关键代码描述。
#include<
easyx.h>
conio.h>
time.h>
/////////////////////////////////////////////
//定义常量、枚举量、结构体、全局变量
#defineWIDTH10//游戏区宽度
#defineHEIGHT22//游戏区高度
#defineUNIT20//每个游戏区单位的实际像素
//定义操作类型
enumCMD
{
CMD_ROTATE,//方块旋转
CMD_LEFT,CMD_RIGHT,CMD_DOWN,//方块左、右、下移动
CMD_SINK,//方块沉底
CMD_QUIT//退出游戏
};
//定义绘制方块的方法
enumDRAW
SHOW,//显示方块
CLEAR,//擦除方块
FIX//固定方块
//定义七种俄罗斯方块
structBLOCK
WORDdir[4];
//方块的四个旋转状态
COLORREFcolor;
//方块的颜色
}g_Blocks[7]={{0x0F00,0x4444,0x0F00,0x4444,RED},//I
{0x0660,0x0660,0x0660,0x0660,BLUE},//口
{0x4460,0x02E0,0x0622,0x0740,CYAN},//L蓝绿色
{0x2260,0x0E20,0x0644,0x0470,GREEN},//反L
{0x0C60,0x2640,0x0C60,0x2640,BROWN},//Z
{0x0360,0x4620,0x0360,0x4620,YELLOW},//反Z
{0x4E00,0x4C40,0x0E40,0x4640,MAGENTA}};
//定义当前方块、下一个方块的信息
structBLOCKINFO
byteid;
//方块ID
charx,y;
//方块在游戏区中的坐标
bytedir:
2;
//方向
}g_CurBlock,g_NextBlock;
//定义游戏区
BYTEg_World[WIDTH][HEIGHT]={0};
//函数声明
voidInit();
//初始化游戏
voidQuit();
//退出游戏
//开始新游戏
voidGameOver();
//结束游戏
CMDGetCmd();
//获取控制命令
voidDispatchCmd(CMD_cmd);
//分发控制命令
//生成新的方块
//检测指定方块是否可以放下
voidDrawUnit(intx,inty,COLORREFc,DRAW_draw);
//画单元方块
voidDrawBlock(BLOCKINFO_block,DRAW_draw=SHOW);
//画方块
//旋转方块
//左移方块
//右移方块
//下移方块
voidOnSink();
//沉底方块
staticintscore=0;
//函数定义
//主函数
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));
setbkmode(TRANSPARENT);
//设置图案填充的背景色为透明
//显示操作说明
settextstyle(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:
退出"
outtextxy(40,150,_T(score));
//设置坐标原点
setorigin(220,20);
//绘制游戏区边界
rectangle(-1,-1,WIDTH*UNIT,HEIGHT*UNIT);
rectangle((WIDTH+1)*UNIT-1,-1,(WIDTH+5)*UNIT,4*UNIT);
//开始新游戏
NewGame();
//退出游戏
voidQuit()
closegraph();
exit(0);
//开始新游戏
voidNewGame()
//清空游戏区
setfillcolor(BLACK);
solidrectangle(0,0,WIDTH*UNIT-1,HEIGHT*UNIT-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想重新来一局吗?
游戏结束"
),MB_YESNO|MB_ICONQUESTION)==IDYES)
NewGame();
else
Quit();
//获取控制命令
DWORDm_oldtime;
CMDGetCmd()
//获取控制值
//如果超时,自动下落一格
DWORDnewtime=GetTickCount();
if(newtime-m_oldtime>
=500)
m_oldtime=newtime;
returnCMD_DOWN;
//如果有按键,返回按键对应的功能
if(kbhit())
switch(getch())
{
case'
w'
:
W'
returnCMD_ROTATE;
a'
A'
returnCMD_LEFT;
d'
D'
returnCMD_RIGHT;
s'
S'
returnCMD_DOWN;
case27:
returnCMD_QUIT;
'
returnCMD_SINK;
case0:
case0xE0:
switch(getch())
{
case72:
case75:
case77:
case80:
}
}
//延时(降低CPU占用率)
Sleep(20);
//分发控制命令
voidDispatchCmd(CMD_cmd)
switch(_cmd)
caseCMD_ROTATE:
OnRotate();
break;
caseCMD_LEFT:
OnLeft();
caseCMD_RIGHT:
OnRight();
caseCMD_DOWN:
OnDown();
caseCMD_SINK:
OnSink();
caseCMD_QUIT:
//生成新的方块
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);
//绘制下一个方块
solidrectangle((WIDTH+1)*UNIT,0,(WIDTH+5)*UNIT-1,4*UNIT-1);
DrawBlock(g_NextBlock);
//设置计时器,用于判断自动下落
m_oldtime=GetTickCount();
voidDrawUnit(intx,inty,COLORREFc,DRAW_draw)
//计算单元方块对应的屏幕坐标
intleft=x*UNIT;
inttop=(HEIGHT-y-1)*UNIT;
intright=(x+1)*UNIT-1;
intbottom=(HEIGHT-y)*UNIT-1;
//画单元方块
switch(_draw)
caseSHOW:
//画普通方块
setlinecolor(0x006060);
roundrect(left+1,top+1,right-1,bottom-1,5,5);
setlinecolor(0x003030);
roundrect(left,top,right,bottom,8,8);
setfillcolor(c);
setlinecolor(LIGHTGRAY);
fillrectangle(left+2,top+2,right-2,bottom-2);
break;
caseFIX:
//画固定的方块
setfillcolor(RGB(GetRValue(c)*2/3,GetGValue(c)*2/3,GetBValue(c)*2/3));
setlinecolor(DARKGRAY);
fillrectangle(left+1,top+1,right-1,bottom-1);
caseCLEAR:
//擦除方块
setfillcolor(BLACK);
solidrectangle(x*UNIT,(HEIGHT-y-1)*UNIT,(x+1)*UNIT-1,(HEIGHT-y)*UNIT-1);
voidDrawBlock(BLOCKINFO_block,DRAW_draw)
WORDb=g_Blocks[_block.id].dir[_block.dir];
intx,y;
for(inti=0;
i<
16;
i++,b<
<
=1)
if(b&
0x8000)
x=_block.x+i%4;
y=_block.y-i/4;
if(y<
HEIGHT)
DrawUnit(x,y,g_Blocks[_block.id].color,_draw);
//检测指定方块是否可以放下
boolCheckBlock(BLOCKINFO_block)
if((x<
0)||(x>
=WIDTH)||(y<
0))
returnfalse;
if((y<
HEIGHT)&
&
(g_World[x][y]))
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;
go