之前学了些C++的课程,一直想着说编点小游戏,可是MFC又不想学,所以就只能变成控制台的小游戏。
俄罗斯方块一定是很多人小时候玩过的游戏。接下来就说说设计想法。
主要实现,选择游戏的等级,加速下降,不同形状不同颜色,暂停和退出功能。
首先是类的设计。
class Box { private: int map[23][12];//画面坐标,记录有方块的点,也是游戏界面 int hotpoint[2];//当前活动的点,所有图形都是以此为基准绘制的 int top;//当前最高位置 int point;//分数 int level;//等级 int ID;//当前活动图形的ID号 int colorID;//图形的颜色ID。 public: Box()//初始化 { int i,j; for(i=0;i<23;i++) for(j=0;j<12;j++) map[i][j]=0; hotpoint[0]=0; hotpoint[1]=5; point=0; level=1; top=99; ID=0; } void SetColor(int color);//颜色 void DrawMap();//画游戏的大界面 bool Judge(int x,int y);//判断当前位置能否绘制图形 void Welcome();//欢迎界面 void DrawBox(int x,int y,int num);//绘制图形 void Redraw(int x,int y,int num);//擦除图形 void Run();//运行 void Turn();//转动方块 void UpdataMap();//更新画面 void Pause();//暂停 };
接下来就是一些常量和光标函数,便于保存和调用
#define A1 0//A代表长条型,B为方块,C为L型,D为闪电型 #define A2 1 #define B 2 #define C11 3 #define C12 4 #define C13 5 #define C14 6 #define C21 7 #define C22 8 #define C23 9 #define C24 10 #define D11 11 #define D12 12 #define D21 13 #define D22 14 void SetPos(int i,int j)//设定光标位置 { COORD pos={i,j}; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos); } const int sharp[15][8]= { {0,0,1,0,2,0,3,0},{0,0,0,1,0,2,0,3}, {0,0,1,0,0,1,1,1}, {0,0,1,0,1,1,1,2},{0,1,1,1,2,0,2,1},{0,0,0,1,0,2,1,2},{0,0,0,1,1,0,2,0}, {1,0,1,1,1,2,0,2},{0,0,0,1,1,1,2,1},{0,0,0,1,0,2,1,0},{0,0,1,0,2,0,2,1}, {0,0,0,1,1,1,1,2},{0,1,1,0,1,1,2,0}, {0,1,0,2,1,0,1,1},{0,0,1,0,1,1,2,1} };//形状点的各个坐标,先纵后横 const int high[15]={4,1,2,2,3,2,3,2,3,2,3,2,3,2,3};//这个数组是用来保存各个形状高度的,以上面的坐标相对应
类方法的实现
void Box::SetColor(int colorID) { int n_color; switch(colorID) { case 0: n_color = 0x08;break; case 1: n_color = 0x0C;break; case 2: n_color = 0x0D;break; case 3: n_color = 0x0E;break; case 4: n_color = 0x0A;break; } SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), n_color); } void Box::DrawMap()//画界面 { int i; SetColor(0);//界面颜色 for(i=0;i<14;i++) { SetPos(i*2,0); cout<<"■"; } for(i=1;i<=24;i++) { SetPos(0,i); cout<<"■"; SetPos(13*2,i); cout<<"■"; } for(i=0;i<14;i++) { SetPos(i*2,24); cout<<"■"; } i=15; for(i=15;i<=25;i++) { SetPos(i*2,0); cout<<"■"; } for(i=1;i<=8;i++) { SetPos(15*2,i); cout<<"■"; SetPos(25*2,i); cout<<"■"; } for(i=15;i<=25;i++) { SetPos(i*2,9); cout<<"■"; } SetPos(16*2,16); cout<<"俄罗斯方块"; SetPos(16*2,17); cout<<"分数:"<<point; SetPos(16*2,18); cout<<"级别:"<<level; } void Box::DrawBox(int x,int y,int num)//绘制图形 { int i; int nx,ny; if (num<2)SetColor(1);//0、1是长条 else if(num<3) SetColor(2);//2 方块 else if(num<11) SetColor(3);//3、4、5、6、7、8、9、10 else SetColor(4); for(i=0;i<4;i++) { nx=x+sharp[num][i*2]; ny=y+sharp[num][i*2+1]; SetPos((ny+1)*2,nx+1);//利用sharp数组相对于点x,y绘制形状 //SetColor(i+1); cout<<"■"; } } void Box::Redraw(int x,int y,int num)//擦除图形,原理同上 { int i; int nx,ny; for(i=0;i<4;i++) { nx=x+sharp[num][i*2]; ny=y+sharp[num][i*2+1]; SetPos((ny+1)*2,nx+1); cout<<" "; } } void Box::Turn()//转动图形,单纯的该ID而已 { switch(ID) { case A1: ID=A2; break; case A2: ID=A1; break; case B: ID=B; break; case C11: ID=C12; break; case C12: ID=C13; break; case C13: ID=C14; break; case C14: ID=C11; break; case C21: ID=C22; break; case C22: ID=C23; break; case C23: ID=C24; break; case C24: ID=C21; break; case D11: ID=D12; break; case D12: ID=D11; break; case D21: ID=D22; break; case D22: ID=D21; break; } } void Box::Welcome()//欢迎界面 { char x; while(1) { system("cls"); cout<<"■■■■■■■■■■■■■■■■■■■"<<endl; cout<<"■ 俄罗斯方块控制台版 ■"<<endl; cout<<"■■■■■■■■■■■■■■■■■■■"<<endl; cout<<"■ A,D左右移动 S向下加速 ■"<<endl; cout<<"■ W 转动方块 P暂停游戏 ■"<<endl; cout<<"■ Q退出游戏 ■"<<endl; cout<<"■■■■■■■■■■■■■■■■■■■"<<endl; cout<<"■ ■"<<endl; cout<<"■ 按1-9选择等级!! ■"<<endl; cout<<"■ ■"<<endl; cout<<"■ ■"<<endl; cout<<"■■■■■■■■■■■■■■■■■■■"<<endl; SetPos(16,9); x=getch(); if(x<='9'&&x>='1')//设置等级 { level=x-'0'; break; } } } void Box::UpdataMap()//更新画面(关键) { int clear; int i,j,k; int nx,ny; int flag; for(i=0;i<4;i++)//更新map数组的信息 { nx=hotpoint[0]+sharp[ID][i*2]; ny=hotpoint[1]+sharp[ID][i*2+1]; map[nx][ny]=1; } if(hotpoint[0]<top)//如果热点高于顶点则更新顶点,这里0表示的是纵向的 top=hotpoint[0]; clear=0;//消除的格数 for(i=hotpoint[0];i<hotpoint[0]+high[ID];i++) { flag=0; for(j=0;j<12;j++)//检测是否可以消除此行 { if(map[i][j]==0)//代表有空格,不能消除 { flag=1;//1表示不能消除 break; } } if(flag==0)//可以消除 { for(k=i;k>=top;k--)//从当前位置向上所有的点下移一行 { if(k==0)//最高点特殊处理 for(j=0;j<12;j++) { map[k][j]=0; SetPos((j+1)*2,k+1); cout<<" "; } else { for(j=0;j<12;j++) { map[k][j]=map[k-1][j]; SetPos((j+1)*2,k+1); if(map[k][j]==0) cout<<" "; else cout<<"■"; } } } top++;//消除成功,最高点下移 clear++; point+=clear*10*level; } } SetColor(0); SetPos(16*2,17); cout<<"分数:"<<point; } void Box::Run()//运行游戏 { int i=0; char x; int Count;//计数器 int nextID; int temp; srand((int)time(0));//将随机数的起点设置为time(0):不带秒 ID=rand()%15;//随机生成ID和下一个ID nextID=rand()%15;//这里为了方便,其实每个形状不是等概率生成的 DrawBox(hotpoint[0],hotpoint[1],ID);//绘制图形 DrawBox(3,17,nextID); Count=1000-level*100;//等级决定计数,这里是用Count控制时间,来控制下落的速度 while(1) { if(i>=Count) { i=0;//计数器清零 if(Judge(hotpoint[0]+1,hotpoint[1]))//如果下个位置无效(即到底) { UpdataMap();//更新画面 ID=nextID;//生成新ID,用原等待ID替换为当前ID hotpoint[0]=0;//热点更新 hotpoint[1]=5; Redraw(3,17,nextID); nextID=rand()%15; DrawBox(hotpoint[0],hotpoint[1],ID); DrawBox(3,17,nextID); if(Judge(hotpoint[0],hotpoint[1]))//无法绘制开始图形,游戏结束 { //getch(); system("cls"); SetPos(25,15); cout<<"游戏结束!!!最终得分为:"<<point<<endl; system("pause");//就是在命令行上输出一行类似于“Press any key to exit” exit(0);//关闭所有文件,退出正在执行的程序,返回0代表正常结束 } } else { Redraw(hotpoint[0],hotpoint[1],ID);//没有到底,方块下移一位 hotpoint[0]++;//热点下移 DrawBox(hotpoint[0],hotpoint[1],ID); } } if(kbhit())//读取键盘信息 { x=getch(); if(x=='a'||x=='A')//左移 { if(Judge(hotpoint[0],hotpoint[1]-1)==0) { Redraw(hotpoint[0],hotpoint[1],ID); hotpoint[1]-=1; DrawBox(hotpoint[0],hotpoint[1],ID); } } if(x=='d'||x=='D')//右移 { if(Judge(hotpoint[0],hotpoint[1]+1)==0) { Redraw(hotpoint[0],hotpoint[1],ID); hotpoint[1]+=1; DrawBox(hotpoint[0],hotpoint[1],ID); } } if(x=='s'||x=='S')//向下加速!!!!!!!!此处可以改进,可以改进加速效果。改成+3之后,会出现BUG,最后几个无法加速 { if(Judge(hotpoint[0]+3,hotpoint[1])==0) { Redraw(hotpoint[0],hotpoint[1],ID); hotpoint[0]+=1; DrawBox(hotpoint[0],hotpoint[1],ID); } } if(x=='w'||x=='W')//转动方块 { temp=ID; Turn(); if(!Judge(hotpoint[0],hotpoint[1])) { Redraw(hotpoint[0],hotpoint[1],temp); DrawBox(hotpoint[0],hotpoint[1],ID); } else ID=temp; } if(x=='p'||x=='P') { //getch(); //system("cls"); Pause(); } if(x=='q'||x=='Q') { system("cls"); SetPos(25,15); cout<<"游戏结束!!!最终得分为:"<<point<<endl; system("pause"); exit(0); } while(kbhit())//读掉剩下的键盘信息 getch(); } Sleep(1);//等待1毫秒 i++;//计数器加1 } } int Box::Judge(int x,int y)//判断当前是否可以绘制方块 { int i; int nx,ny; for(i=0;i<4;i++) { nx=x+sharp[ID][i*2]; ny=y+sharp[ID][i*2+1]; if(nx<0||nx>=23||ny<0||ny>=12||map[nx][ny]==1)//不能,返回1 return 1; } return 0; } void Box::Pause() { system("cls"); while(1) { SetPos(30,13); cout<<"暂停等待,咖啡时间^-^"<<endl; if(getch()=='p'||getch()=='P') break; } SetPos(30,13); cout<<" "<<endl; DrawMap(); int i ,j; for(i=0;i<23;i++) for(j=0;j<12;j++) if(map[i][j]==1) { SetPos((j+1)*2,i+1); cout<<"■"; } }
void main()//主函数 { Box game; game.Welcome(); system("cls"); game.DrawMap(); game.Run(); }
待改进的点:
1、加速下降的时候,从代码中也可以发现,最后几格没法加速。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍pyqt5实现俄罗斯方块游戏,包括了pyqt5实现俄罗斯方块游戏的使用技巧和注意事项,需要的朋友参考一下 本章我们要制作一个俄罗斯方块游戏。 Tetris 译注:称呼:方块是由四个小方格组成的 俄罗斯方块游戏是世界上最流行的游戏之一。是由一名叫Alexey Pajitnov的俄罗斯程序员在1985年制作的,从那时起,这个游戏就风靡了各个游戏平台。 俄罗斯方块归类为下落块迷宫游戏。游戏
本文向大家介绍C语言实现俄罗斯方块小游戏,包括了C语言实现俄罗斯方块小游戏的使用技巧和注意事项,需要的朋友参考一下 C语言实现俄罗斯方块小游戏的制作代码,具体内容如下 更多俄罗斯方块精彩文章请点击专题:俄罗斯方块游戏集合 进行学习。 更多有趣的经典小游戏实现专题,分享给大家: C++经典小游戏汇总 python经典小游戏汇总 JavaScript经典游戏 玩不停 java经典小游戏汇总 javas
本章我们要制作一个俄罗斯方块游戏。 Tetris 译注:称呼:方块是由四个小方格组成的 俄罗斯方块游戏是世界上最流行的游戏之一。是由一名叫Alexey Pajitnov的俄罗斯程序员在1985年制作的,从那时起,这个游戏就风靡了各个游戏平台。 俄罗斯方块归类为下落块迷宫游戏。游戏有7个基本形状:S、Z、T、L、反向L、直线、方块,每个形状都由4个方块组成,方块最终都会落到屏幕底部。所以玩家通过控制
本章我们要制作一个俄罗斯方块游戏。 Tetris 译注:称呼:方块是由四个小方格组成的 俄罗斯方块游戏是世界上最流行的游戏之一。是由一名叫 Alexey Pajitnov 的俄罗斯程序员在 1985 年制作的,从那时起,这个游戏就风靡了各个游戏平台。 俄罗斯方块归类为下落块迷宫游戏。游戏有 7 个基本形状:S、Z、T、L、反向 L、直线、方块,每个形状都由 4 个方块组成,方块最终都会落到屏幕底部
本文向大家介绍C++实现俄罗斯方块(windows API),包括了C++实现俄罗斯方块(windows API)的使用技巧和注意事项,需要的朋友参考一下 本文分享的这些俄罗斯方块代码是我最近放假在家里自己写的,虽然以前有过看别人写的代码,但是那个游戏代码好像不是很全面,因为无法实现全部的方块和实现随机的产生任意方向的方块,现在也基本上是忘光了当时的代码,下面的这些代码是我最近写的,没有参考其他人
本文向大家介绍javascript+css实现俄罗斯方块小游戏,包括了javascript+css实现俄罗斯方块小游戏的使用技巧和注意事项,需要的朋友参考一下 俄罗斯方块,一个很有趣的一个小游戏,此次基于html+css+javaScript实现,包含在一个方块落地后自动生成方块、操控方块的移动以及方块变形等。 部分代码: 游戏截图: 源码可参考:js俄罗斯方块 更多有趣的经典小游戏实现专题,分享