• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

C++实现俄罗斯方块

c++ 搞代码 4年前 (2022-01-06) 45次浏览 已收录 0个评论

这篇文章主要为大家详细介绍了C++实现俄罗斯方块,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C++实现俄罗斯方块的具体代码,供大家参考,具体内容如下

工具:vc++2010,图库:EasyX

先看效果图片

纯手写,没有面向对象思想,看全部源码

 #include  #include  #include  #include  #define BLOCK_COUNT 5 #define BLOCK_WIDTH 5 #define BLOCK_HEIGHT 5 #define UNIT_SIZE 20 #define START_X  130 #define START_Y  30 #define KEY_UP  72 #define KEY_RIGHT 77 #define KEY_LEFT  75 #define KEY_SPACE 32 #define KEY_DOWN  76 typedef enum{ BLOCK_UP, BLOCK_RIGHT, BLOCK_DOWN, BLOCK_LEFT }block_dir_t; typedef enum{ MOVE_DOWN, MOVE_LEFT, MOVE_RIGHT }move_dir_t; int speed = 500; int NextIndex = -1;//下一个方块种类 int BlockIndex = -1;//当前方块种类 int score = 0;//分数 int rank = 0;//等级 int visit[30][15];//访问数组 int markcolor[30][15];//表示颜色 int minX = 30; int minY = 30; int color[BLOCK_COUNT]={ GREEN,CYAN,MAGENTA,BROWN,YELLOW }; int block[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} }; //欢迎界面 void welcome(){ //初始化画布 initgraph(550,660); //设置窗口标题 HWND window = 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); } //初始化游戏屏幕 void initGameScene(){ char str[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,"空格:暂停"); } void drawBlock(int x,int y){//右上角画出方块 setcolor(color[NextIndex]); setfont(23,0,"楷体"); for(int i= 0;i<BLOCK_HEIGHT;i++){ for(int j= 0;j<BLOCK_WIDTH;j++){ if(block[NextIndex*4][i][j] == 1){ outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■"); } } } } void drawBlock(int x,int y,int blockIndex,block_dir_t dir){//按索引画出什么方块指定位置方块指定方向 setcolor(color[blockIndex]); setfont(23,0,"楷体"); int id = blockIndex*4+dir; for(int i= 0;i<BLOCK_HEIGHT;i++){ for(int j= 0;j<BLOCK_WIDTH;j++){ if(block[id][i][j] == 1){ outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■"); } } } } void clearBlock(int x, int y){ setcolor(BLACK); setfont(23,0,"楷体"); for(int i= 0;i<BLOCK_HEIGHT;i++){ for(int j= 0;j<BLOCK_WIDTH;j++){ outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■"); } } } void clearBlock(int x, int y,block_dir_t dir){ setcolor(BLACK); int id = BlockIndex *4+dir; y+=START_Y; for(int i= 0;i<BLOCK_HEIGHT;i++){ for(int j= 0;j<BLOCK_WIDTH;j++){ if(block[id][i][j] == 1){ outtextxy(x+UNIT_SIZE*j,y+UNIT_SIZE*i,"■"); } } } } void nextblock(){ clearBlock(391,71);//清除右上角方块 //随机选择一种方块 srand(time(NULL));//时间函数的返回值产生随机数种子 NextIndex = rand()%BLOCK_COUNT; drawBlock(391,71);//画出方块 } //如果在指定位置可以向方向移动 int moveable(int x0,int y0,move_dir_t moveDir,block_dir_t blockDir){ int x = (y0 - minY)/UNIT_SIZE; int y = (x0 - minX)/UNIT_SIZE; int id = BlockIndex * 4+blockDir; int ret = 1; if(moveDir == MOVE_DOWN){ for(int i = 0;i<5;i++){ for(int j = 0;j=30 || visit[x+i+1][y+j]==1)){ ret=0; } } } }else if(moveDir == MOVE_LEFT){ for(int i = 0;i<5;i++){ for(int j = 0;j<5;j++){ if(block[id][i][j] == 1 &&(y+j==0 || visit[x+i][y+j-1]==1)){ ret=0; } } } }else if(moveDir == MOVE_RIGHT){ for(int i = 0;i<5;i++){ for(int j = 0;j=15 || visit[x+i][y+j+1]==1)){ ret=0; } } } } return ret; } void failCheck(){//游戏是否结束 if(!moveable(START_X,START_Y,MOVE_DOWN,BLOCK_UP)){ setcolor(WHITE); setfont(45,0,"隶体"); outtextxy(75,300,"GAME OVER!"); Sleep(1000); system("pause"); closegraph(); exit(0); } } int wait(int inter<em style="color:transparent">来源[email protected]搞@^&代*@码网</em>val){//等待 int count = interval/5; for(int i = 0;i<count;i++){ Sleep(5); if(kbhit()){ return 0; } } }//判断当前方向是否可以转到指定方向 int rotatable(int x,int y,block_dir_t dir){ int id= BlockIndex * 4 +dir; int xIndex = (y-minY)/20; int yIndex = (x-minX)/20; if(!moveable(x,y,MOVE_DOWN,dir)){ return 0 ; } for(int i = 0;i<5;i++){ for(int j = 0;j<5;j++){ if(block[id][i][j] ==1&&(yIndex+j=15||visit[xIndex+i][yIndex+j] ==1)){ return 0 ; } } } return 1; } void mark(int x,int y,int blockIndex,block_dir_t dir){ int id = blockIndex*4+dir; int x2 = (y-minY)/20; int y2 = (x-minX)/20; for(int i=0;i<5;i++){ for(int j=0;j0;i--){ for(int j=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(int j = 0;j<15;j++){ visit[0][j] = 0; outtextxy(20*j+minX,minY,"■"); } } void updataGrade(){ //更新等级提示 //假设:50分一级 char str[10]; rank = score/50; sprintf(str,"%d",rank); outtextxy(425,405,str); //更新速度,等级越高速度越快,speed越小 //最慢是500,最快是50 speed = 500-rank*50; if(speed=0;i--){ for(j=0;j=15){ //此时第i行已经满了,就需要消除第i行 clear_down(i);//清除第i行,并把上面的行都下移动 i++; clearLines++; } } //更新分数 addScore(clearLines); //更新等级 updataGrade(); } void move(){ int x = START_X; int y = START_Y; int k = 0; int curSpeed = speed; block_dir_t blockDir = BLOCK_UP; //检查游戏是否结束 failCheck(); while(1){ if(kbhit()){ int key = getch(); if(KEY_SPACE == key){ getch(); } } //清除当前方块 clearBlock(x,k,blockDir); if(kbhit()){ int key = getch(); if(KEY_UP == key){//变形 block_dir_t nextDir = (block_dir_t)((blockDir+1)%4); if(rotatable(x,y+k,nextDir)){ blockDir= nextDir; } }else if(KEY_DOWN == key){//乡下加速 curSpeed = 50; }else if(KEY_RIGHT == key){//右移动 if(moveable(x,y+k+20,MOVE_RIGHT,blockDir)){ x+=20; } }else if(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; } } } void newblock(){ //确定即将使用的方块 BlockIndex = NextIndex; //绘制方块从顶部掉下来 drawBlock(START_X,START_Y); //新出现的方块等一下 Sleep(100); //右上角绘制下一个方块 nextblock(); //向下降落的动作 move(); } int main (void){ welcome(); initGameScene(); //产生新方块 nextblock(); Sleep(500); memset(visit,0,sizeof(visit)); while(1){ newblock(); //消除满行,并更新分数和速度 check(); } system("pause"); closegraph(); return 0; }

分析项目:

1.必须要有欢迎界面
2.搭建合理的边界,就是游戏范围
3.逻辑1:先出现右上方的方块样式,等待一段时间,将右上方的样式在游戏区打印出
4.逻辑2,方块降落,要擦除原先印记,将1改为0
5.逻辑3,热键控制移动方向,暂停及变形,且不能移动出界,判断方块是否还能移动
6.逻辑4,方块凝固在下方不出界
7.逻辑5,最下面一行方块叠满了,消去它并把上面的行都下移(分两种情况),并且再次检查这一行
8.逻辑6,计算消除行数次数,统计分数,控制休眠时间长度
9.逻辑7,每次移动先判断是否能移动,默认结束程序,在合理游戏区返回false,结束界面

总结:从界面开始到完整的架构,功能后实现,一步一步,逻辑严谨,思路清晰,注释在代码里。

以上就是C++实现俄罗斯方块的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:C++实现俄罗斯方块

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址