C++实现俄罗斯方块源码

本文实例为大家分享了C++实现俄罗斯方块的具体代码,供大家参考,具体内容如下
【C++实现俄罗斯方块源码】先是效果图:
主菜单:
C++实现俄罗斯方块源码
文章图片

游戏:
C++实现俄罗斯方块源码
文章图片

设置:
C++实现俄罗斯方块源码
文章图片

错误处理:
C++实现俄罗斯方块源码
文章图片

代码:

#include #include #include #include #include #include #include #pragma comment( lib,"winmm.lib" )//定义//方块#define NO 0#define SQR 1//碰撞检测#define OK 0#define CANTMOVE 1//方向#define UP 0#define DOWN 1#define LEFT 2#define RIGHT 3//错误码#define no_enough_memory0#define set_no_found1#define dat_no_found2#define error_argument3//函数声明//模块void play(); //开始游戏void sets(); //设置void highscores(); //排行榜void copyright(); //作者//功能void mapsetup(); //准备地图bool newsqr(); //放置方块,返回是否游戏结束int move(int direction); //移动方块,返回定义表void movetomap(); //把当前方块移动到地图上int wholeline(); //检查是否组成了一层,返回层数,-1表示没有void deleteline(int which); //删除一行void endup(); //结束游戏,清理内存//显示void show(); //刷新画面void showmenu(char* menu); //显示菜单//文件void loadset(); //加载设置void saveset(); //保存设置void loadhs(); //加载排行榜bool addscores(int score,char name[50]); //增加一个分数,返回是否是高分void savehs(); //保存排行榜//坐标变换int get(int x,int y); void set(int x,int y,int date); //结构//设置struct{int xs,ys; //屏幕大小int speed; //速度char sqr[3],no[3],frame[3]; //方块、空白处、边框的样式}gameset; //排行榜struct{char name[50]; int score; }rating[10]; //全局变量//变量int* map=NULL; //地图bool now[4][4]; //当前方块int xnow,ynow; //当前位置int guide; //分数//常量const bool shap[7][4][4]={//形状{\0,0,0,0,\0,0,0,0,\1,1,1,1,\0,0,0,0,\},\{\0,0,0,0,\0,1,1,0,\0,1,1,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,\1,0,0,0,\1,1,1,0,\0,0,0,0,\},\{\0,0,0,0,\0,0,0,1,\0,1,1,1,\0,0,0,0,\},\{\0,1,0,0,\0,1,1,0,\0,0,1,0,\0,0,0,0,\},\{\0,0,1,0,\0,1,1,0,\0,1,0,0,\0,0,0,0,\}\}; const char errword[4][50]={"程序没能取得足够的内存","无法打开或找不到设置文件set.ini","无法打开或找不到排行榜数据highscore.dat","您设置的参数太大或者太小"}; //控制台HANDLEhout; //控制台句柄COORD curpos={0,0}; //光标坐标//主函数int main(){start1:try{hout = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄,以便移动光标srand(time(0)); //用当前时间初始化随机数生成器loadset(); //加载loadhs(); start2:while(1){showmenu("俄罗斯方块\n请选择菜单:\n1.开始游戏\n2.设置\n3.排行榜\n4.帮助\n5.保存并退出\n"); switch(getch()){case '1':system("cls"); //play函数覆盖界面而不是清屏,所以需要先清屏play(); break; case '2':sets(); break; case '3':highscores(); break; case '4':copyright(); break; case '5':savehs(); //保存数据saveset(); return 0; }}}catch(int errnum)//错误处理{system("cls"); printf("o(>﹏<)o 出错啦!\n程序收到了一条错误信息,错误码是:%d(%s)\n您可以联系我们解决这个问题。\n",errnum,errword[errnum]); printf("\n你可以选择以下操作:\n1.重启程序\n2.以默认设置重启程序\n3.向设置和数据文件写入默认设置然后重启\n4.退出\n"); switch(getch()){case '1':goto start1; case '2':gameset.xs=20; gameset.ys=20; gameset.speed=100; strcpy(gameset.sqr,"[]"); //无法直接给数组复制数据strcpy(gameset.no,""); strcpy(gameset.frame,"::"); int i; for(i=0; i<10; i++)strcpy(rating[i].name,"未命名"),rating[i].score=0; goto start2; case '3':{ofstream fout; fout.open("set.ini"); fout<<"20\n20\n100[]\n\n::\n"; fout.close(); fout.clear(); fout.open("highscore.dat"); int j; for(j=0; j<10; j++)fout<<"未命名\n0\n"; goto start1; }default:return -1; //返回异常退出}}return 0; }void play(){mapsetup(); //初始化/*for(int i=0; i<20; i++)set(i,19,SQR); */while(newsqr())//不断新建方块,直到返回NO{while(move(DOWN)!=CANTMOVE)//每次向下移动方块,直到不能移动{guide+=1; //向下移动一次加1分show(); //显示while(kbhit())//不断处理键盘,直到没有按键{switch(getch())//获取按键{case 'w':move(UP); break; case 's':move(DOWN); break; case 'a':move(LEFT); break; case 'd':move(RIGHT); break; }}Sleep(gameset.speed); //延时}movetomap(); //退出循环时无法向下移动,把当前方块移动到地图上int line; while((line=wholeline())!=-1); //不断检查是否出现整行,直到没有deleteline(line); //删除整行}endup(); //无法新建方块,游戏结束return; //结束}//函数定义void mapsetup(){map=new int[gameset.xs*gameset.ys]; //申请内存if(!map)//如果申请到0throw no_enough_memory; //抛出异常//初始化地图int i,j; for(i=0; i=0&&x=0&&y=0&&x=0&&y0&&x0&&y0; i--)//旋转随机0-3次move(UP); xnow=gameset.xs/2; //设置坐标ynow=-4; return true; }int move(int direction){int x,y; //储存坐标偏移量int i,j; switch(direction){case UP://上键是旋转bool newshap[4][4]; //储存旋转后的图形for(i=0; i<4; i++){for(j=0; j<4; j++){newshap[i][j]=now[j][3-i]; //坐标变换}}for(i=0; i<4; i++){for(j=0; j<4; j++){if(newshap[i][j]==true&&get(xnow+i,ynow+j)==SQR)//对新图形碰撞检测return CANTMOVE; //不能旋转}}for(i=0; i<4; i++){for(j=0; j<4; j++){now[i][j]=newshap[i][j]; //检测完毕,复制形状}}return OK; case DOWN://先记录坐标的偏移量,确定没有碰撞以后移动x=0,y=1; break; case LEFT:x=-1; y=0; break; case RIGHT:x=1,y=0; break; }for(i=0; i<4; i++){for(j=0; j<4; j++){if(now[i][j]==true&&get(i+x+xnow,j+y+ynow)==SQR)//如果和地图上的方块重合(边缘以外get函数也返回SQR,不必单独处理)//if(get(i+x,j+y)==SQR)//if(now[i+x][j+y]==SQR){return CANTMOVE; //无法移动}}}xnow+=x; //检测完毕,更改坐标ynow+=y; return OK; }void movetomap(){guide+=10; //成功放置方块,加10分int i,j; for(i=0; i<4; i++){for(j=0; j<4; j++){if(now[i][j]==true)set(xnow+i,ynow+j,SQR); //复制方块到地图}}return; }int wholeline(){int i,j; bool whole; //储存是否是整行for(j=0; j=0; i--){for(j=0; j=xnow&&i<(xnow+4)&&j>=ynow&&j<(ynow+4))//if(i>=xnow&&i<(xnow+1)&&j>=ynow&&j<(ynow+1))//在当前方块范围内{if(now[i-xnow][j-ynow]==true)//如果有方块printf(gameset.sqr); else if(get(i,j)==SQR)//如果地图有方块printf(gameset.sqr); else//否则,空白printf(gameset.no); }else//不在当前方块范围内,输出地图{if(get(i,j)==SQR)//有方块printf(gameset.sqr); else//否则,没方块printf(gameset.no); }}printf("::\n"); //右边框和换行}for(i=0; i70)throw error_argument; break; case '2':scanf("%d",&gameset.ys); if(gameset.ys<15||gameset.ys>70)throw error_argument; break; case '3':scanf("%d",&gameset.speed); if(gameset.speed<0)throw error_argument; break; case '4':cin.getline(&gameset.sqr[0],3); //scanf("%s",&gameset.sqr[0]); cout<>gameset.xs>>gameset.ys>>gameset.speed; fin.getline(gameset.sqr,4); //获取整行,因为可能有空格fin.getline(gameset.no,4); fin.getline(gameset.frame,4); return; }void saveset(){ofstream fout; //输出文件流fout.open("set.ini",ifstream::out|ios::nocreate); if(!fout)throw set_no_found; fout<>rating[i].name>>rating[i].score; return; }bool addscores(int score,char name[50]){int i,j; for(i=0; i<10; i++)//枚举 {if(rating[i].scorei; j--)//移动数据空出位置 {for(int k=0; k<50; k++)rating[j].name[k]=rating[j-1].name[k]; rating[j].score=rating[j-1].score; }rating[i].score=score; //插入数据 strcpy(rating[i].name,name); return true; //返回进入排行 }}return false; //返回没有进入 }void savehs(){int i; ofstream fout; fout.open("highscore.dat",ifstream::out|ios::nocreate); if(!fout)throw dat_no_found; for(i=0; i<10; i++)fout<
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读