C++实现俄罗斯方块
本文实例为大家分享了C++实现俄罗斯方块的具体代码,供大家参考,具体内容如下
工具:vc++2010,图库:EasyX
先看效果图片
纯手写,没有面向对象思想,看全部源码
#include#include #include #include #defineBLOCK_COUNT5 #defineBLOCK_WIDTH5 #defineBLOCK_HEIGHT5 #defineUNIT_SIZE20 #defineSTART_X130 #defineSTART_Y30 #defineKEY_UP72 #defineKEY_RIGHT77 #defineKEY_LEFT75 #defineKEY_SPACE32 #defineKEY_DOWN76 typedefenum{ BLOCK_UP, BLOCK_RIGHT, BLOCK_DOWN, BLOCK_LEFT }block_dir_t; typedefenum{ MOVE_DOWN, MOVE_LEFT, MOVE_RIGHT }move_dir_t; intspeed=500; intNextIndex=-1;//下一个方块种类 intBlockIndex=-1;//当前方块种类 intscore=0;//分数 intrank=0;//等级 intvisit[30][15];//访问数组 intmarkcolor[30][15];//表示颜色 intminX=30; intminY=30; intcolor[BLOCK_COUNT]={ GREEN,CYAN,MAGENTA,BROWN,YELLOW }; intblock[BLOCK_COUNT*4][BLOCK_HEIGHT][BLOCK_WIDTH]={ //条形方块 { 0,0,0,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,0,0,0,0, 0,1,1,1,0, 0,0,0,0,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,0,0,0,0, 0,1,1,1,0, 0,0,0,0,0, 0,0,0,0,0}, //L形方块 { 0,0,0,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,1,1,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,0,0,0,0, 0,1,1,1,0, 0,1,0,0,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,1,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,0,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,0,0}, //田字型 { 0,0,0,0,0, 0,1,1,0,0, 0,1,1,0,0, 0,0,0,0,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,1,1,0,0, 0,1,1,0,0, 0,0,0,0,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,1,1,0,0, 0,1,1,0,0, 0,0,0,0,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,1,1,0,0, 0,1,1,0,0, 0,0,0,0,0, 0,0,0,0,0}, //T字形方块 { 0,0,0,0,0, 0,1,1,1,0, 0,0,1,0,0, 0,0,0,0,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,0,0,1,0, 0,0,1,1,0, 0,0,0,1,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,0,1,0,0, 0,1,1,1,0, 0,0,0,0,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,0,1,0,0, 0,0,1,1,0, 0,0,1,0,0, 0,0,0,0,0}, //Z字形方块 { 0,0,0,0,0, 0,1,1,0,0, 0,0,1,1,0, 0,0,0,0,0, 0,0,0,0,0}, { 0,0,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,0,0, 0,1,1,0,0, 0,0,1,1,0, 0,0,0,0,0, 0,0,0,0,0}, { 0,0,0,0,0, 0,0,0,1,0, 0,0,1,1,0, 0,0,1,0,0, 0,0,0,0,0} }; //欢迎界面 voidwelcome(){ //初始化画布 initgraph(550,660); //设置窗口标题 HWNDwindow=GetHWnd();//获取窗口 SetWindowText(window,_T("俄罗斯方块GWF"));//设置窗口标题 //设置文本字体样式 setfont(0,30,_T("微软雅黑")); setcolor(YELLOW); outtextxy(150,200,_T("俄罗斯方块")); setfont(0,10,_T("微软雅黑")); outtextxy(175,300,_T("IT编程从俄罗斯方块开始")); Sleep(3000); } //初始化游戏屏幕 voidinitGameScene(){ charstr[16]; //清除屏幕 cleardevice(); rectangle(27,27,336,635); rectangle(29,29,334,633); rectangle(370,50,515,195); setfont(24,0,_T("楷体")); setcolor(LIGHTGRAY); outtextxy(405,215,_T("下一个")); setcolor(RED); outtextxy(405,280,_T("分数")); sprintf(str,"%d",score); outtextxy(415,310,str); outtextxy(405,375,_T("等级")); sprintf(str,"%d",rank); outtextxy(415,405,str); setcolor(LIGHTBLUE); outtextxy(390,475,"操作说明"); outtextxy(390,500,"↑:旋转"); outtextxy(390,525,"↓:下降"); outtextxy(390,550,"→:向右"); outtextxy(390,575,"←:向左"); outtextxy(390,600,"空格:暂停"); } voiddrawBlock(intx,inty){//右上角画出方块 setcolor(color[NextIndex]); setfont(23,0,"楷体"); for(inti=0;i =30||visit[x+i+1][y+j]==1)){ ret=0; } } } }elseif(moveDir==MOVE_LEFT){ for(inti=0;i<5;i++){ for(intj=0;j<5;j++){ if(block[id][i][j]==1&&(y+j==0||visit[x+i][y+j-1]==1)){ ret=0; } } } }elseif(moveDir==MOVE_RIGHT){ for(inti=0;i<5;i++){ for(intj=0;j<5;j++){ if(block[id][i][j]==1&&(y+j+1>=15||visit[x+i][y+j+1]==1)){ ret=0; } } } } returnret; } voidfailCheck(){//游戏是否结束 if(!moveable(START_X,START_Y,MOVE_DOWN,BLOCK_UP)){ setcolor(WHITE); setfont(45,0,"隶体"); outtextxy(75,300,"GAMEOVER!"); Sleep(1000); system("pause"); closegraph(); exit(0); } } intwait(intinterval){//等待 intcount=interval/5; for(inti=0;i =15||visit[xIndex+i][yIndex+j]==1)){ return0; } } } return1; } voidmark(intx,inty,intblockIndex,block_dir_tdir){ intid=blockIndex*4+dir; intx2=(y-minY)/20; inty2=(x-minX)/20; for(inti=0;i<5;i++){ for(intj=0;j<5;j++){ if(block[id][i][j]==1){ visit[x2+i][y2+j]=1; markcolor[x2+i][y2+j]=color[blockIndex]; } } } } voidclear_down(intx){//消除第x行,并把上面的行都下移 for(inti=x;i>0;i--){ for(intj=0;j<15;j++){ if(visit[i-1][j]){//上面有东西 visit[i][j]=1; markcolor[i][j]=markcolor[i-1][j]; setcolor(markcolor[i][j]); outtextxy(20*j+minX,20*i+minY,"■"); }else{ visit[i][j]=0; setcolor(BLACK); outtextxy(20*j+minX,20*i+minY,"■"); } } } //清除最顶层那一行,就是行标位0的哪一行 setcolor(BLACK); for(intj=0;j<15;j++){ visit[0][j]=0; outtextxy(20*j+minX,minY,"■"); } } voidupdataGrade(){ //更新等级提示 //假设:50分一级 charstr[10]; rank=score/50; sprintf(str,"%d",rank); outtextxy(425,405,str); //更新速度,等级越高速度越快,speed越小 //最慢是500,最快是50 speed=500-rank*50; if(speed<=0){ speed=50; } } voidaddScore(intlines){//更新分数,line表示消除的行数 charstr[32]; setcolor(RED); score+=lines*10; sprintf(str,"%d",score); outtextxy(415,310,str); } voidcheck(){//消去方块 inti,j; intclearLines=0; for(i=29;i>=0;i--){ for(j=0;j<15&&visit[i][j];j++); //执行到此处有两种情况, //1.第I行没有满,即表示有空位,此时j<15 //2.第i行已经满了,j就大于等于15 if(j>=15){ //此时第i行已经满了,就需要消除第i行 clear_down(i);//清除第i行,并把上面的行都下移动 i++; clearLines++; } } //更新分数 addScore(clearLines); //更新等级 updataGrade(); } voidmove(){ intx=START_X; inty=START_Y; intk=0; intcurSpeed=speed; block_dir_tblockDir=BLOCK_UP; //检查游戏是否结束 failCheck(); while(1){ if(kbhit()){ intkey=getch(); if(KEY_SPACE==key){ getch(); } } //清除当前方块 clearBlock(x,k,blockDir); if(kbhit()){ intkey=getch(); if(KEY_UP==key){//变形 block_dir_tnextDir=(block_dir_t)((blockDir+1)%4); if(rotatable(x,y+k,nextDir)){ blockDir=nextDir; } }elseif(KEY_DOWN==key){//乡下加速 curSpeed=50; }elseif(KEY_RIGHT==key){//右移动 if(moveable(x,y+k+20,MOVE_RIGHT,blockDir)){ x+=20; } }elseif(KEY_LEFT==key){//左移动 if(moveable(x,y+k+20,MOVE_LEFT,blockDir)){ x-=20; } } } k+=20; //绘制当前方块 drawBlock(x,y+k,BlockIndex,blockDir); wait(curSpeed); //方块降落到底层的固化处理 if(!moveable(x,y+k,MOVE_DOWN,blockDir)){ mark(x,y+k,BlockIndex,blockDir); break; } } } voidnewblock(){ //确定即将使用的方块 BlockIndex=NextIndex; //绘制方块从顶部掉下来 drawBlock(START_X,START_Y); //新出现的方块等一下 Sleep(100); //右上角绘制下一个方块 nextblock(); //向下降落的动作 move(); } intmain(void){ welcome(); initGameScene(); //产生新方块 nextblock(); Sleep(500); memset(visit,0,sizeof(visit)); while(1){ newblock(); //消除满行,并更新分数和速度 check(); } system("pause"); closegraph(); return0; }
分析项目:
1.必须要有欢迎界面
2.搭建合理的边界,就是游戏范围
3.逻辑1:先出现右上方的方块样式,等待一段时间,将右上方的样式在游戏区打印出
4.逻辑2,方块降落,要擦除原先印记,将1改为0
5.逻辑3,热键控制移动方向,暂停及变形,且不能移动出界,判断方块是否还能移动
6.逻辑4,方块凝固在下方不出界
7.逻辑5,最下面一行方块叠满了,消去它并把上面的行都下移(分两种情况),并且再次检查这一行
8.逻辑6,计算消除行数次数,统计分数,控制休眠时间长度
9.逻辑7,每次移动先判断是否能移动,默认结束程序,在合理游戏区返回false,结束界面
总结:从界面开始到完整的架构,功能后实现,一步一步,逻辑严谨,思路清晰,注释在代码里。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。