C语言/C++,实现俄罗斯方块,编程入门项目,其实项目实战也挺简单

引用

有人说:“C生万物,编程之本”,这一点都没有错!

C语言是最接近计算机的语言,很多时间,我们都会发现,C语言是非常有必要学习的。

作为一门古老的编程语言,大家熟知它不仅是因为拥有48年的发展历程,更主要还是因为当下大部分程序员走入编程世界第一个学习的语言就是C语言。

这篇文章主要为大家详细介绍了C语言实现俄罗斯方块小游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文的代码下载地址在文章末尾,有需要的同学自取。

效果展示:

编译环境:

Windows 10.xxx.xxx+Visual Studio 2017

游戏规则,游戏主要实现的功能:

  • 游戏主界面是10*20的格子。
  • 每轮随机创建一个形状的方块,总共有6种形状。
  • 方块每秒下降1格,遇到障碍无法下降时进入下一轮。
  • 方块可以旋转、移动、加速下落
  • 格子界面有一行放满时可消除。

开发思路:

1.要先下载一个 graphics.h 的头文件来绘图。

2.初始化窗口:initgraph(x, y);这是先创建一个窗口的函数,以左上角为(0,0),向右为x轴,向下为y轴,其中x表示长x个单位,y表示宽y个单位。

3.关闭图像窗口:closegraph();结束时用来关闭用的。

4.按任意键继续:getch();这个就和getchar();差不多,为了防止以运行完就关了,这样能停顿一下,他的头文件是:conio.h 。

5.画线:line(x1, y1, x2, y2);在你创建的那么窗口里以(x1,y1)和(x2,y2)为两个端点画线。

6.画矩形:rectangle(x1,y1,x2,y2);以(x1,y1)和(x2,y2)为对角画一个矩形。

7.画圆:circle(x,y,r);以(x,y)为圆点,r为半径画圆。

8.颜色:setcolor(x);用来设置颜色的,其中x是你要设置的颜色,可以填这16种:黑 BLACK、蓝 BLUE、绿 GREEN、青 CYAN、红 RED、紫 MAGENTA、棕 BROWN、浅灰 LIGHTGRAY、深灰 DARKGRAY、亮蓝 LIGHTBLUE、亮绿 LIGHTGREEN、亮青 LIGHTCYAN、亮红 LIGHTRED、亮紫 LIGHTMAGENTA、黄 YELLOW、白 WHITE;当然,你也可以根据光的三原色来调自己喜欢的颜色,方法是:setcolor(RGB(x,y,z));其中RGB分别代表红绿蓝,对应的x,y,z是你选的该颜色的多少,范围是[0,255]。

【源码获取】:

源码在C语言/C++交流④群:836880131!资料共享在群文件里面,有需要的可以自行添加获取~

如果对代码有任何建议,都可以添加小编的学习交流群,欢迎大家来讨论~

源码展示:

#include <stdio.h> 
#include <windows.h> 
#include <conio.h> 
#include <time.h> 

//游戏窗口 
#define FrameX 4   //游戏窗口左上角的X轴坐标 
#define FrameY 4   //游戏窗口左上角的Y轴坐标 
#define Frame_height  20 //游戏窗口的高度 
#define Frame_width   18 //游戏窗口的宽度 

//定义全局变量 
int i,j,temp,temp1,temp2; //temp,temp1,temp2用于记住和转换方块变量的值 
int a[80][80]={0};   //标记游戏屏幕的图案:2,1,0分别表示该位置为游戏边框、方块、无图案;初始化为无图案 
int b[4];     //标记4个"口"方块:1表示有方块,0表示无方块 

//声明俄罗斯方块的结构体 
struct Tetris 
{ 
 int x;     //中心方块的x轴坐标 
 int y;     //中心方块的y轴坐标 
 int flag;    //标记方块类型的序号 
 int next;    //下一个俄罗斯方块类型的序号 
 int speed;    //俄罗斯方块移动的速度 
 int count;    //产生俄罗斯方块的个数 
 int score;    //游戏的分数 
 int level;    //游戏的等级 
}; 

//函数原型声明 
//光标移到指定位置 
void gotoxy(HANDLE hOut, int x, int y); 
//制作游戏窗口 
void make_frame(); 
//随机产生方块类型的序号 
void get_flag(struct Tetris *); 
//制作俄罗斯方块 
void make_tetris(struct Tetris *); 
//打印俄罗斯方块 
void print_tetris(HANDLE hOut,struct Tetris *); 
//清除俄罗斯方块的痕迹 
void clear_tetris(HANDLE hOut,struct Tetris *); 
//判断是否能移动,返回值为1,能移动,否则,不动 
int if_moveable(struct Tetris *); 
//判断是否满行,并删除满行的俄罗斯方块 
void del_full(HANDLE hOut,struct Tetris *); 
//开始游戏 
void start_game(); 


void main() 
{  
 //制作游戏窗口 
 make_frame();       
 //开始游戏 
 start_game(); 
} 

/******光标移到指定位置**************************************************************/ 
void gotoxy(HANDLE hOut, int x, int y) 
{ 
 COORD pos; 
 pos.X = x;  //横坐标 
 pos.Y = y;  //纵坐标 
 SetConsoleCursorPosition(hOut, pos); 
} 

/******制作游戏窗口******************************************************************/ 
void make_frame() 
{ 
 HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);  //定义显示器句柄变量 

 gotoxy(hOut,FrameX+Frame_width-5,FrameY-2);   //打印游戏名称 
 printf("俄罗斯方块"); 
 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+7);  //打印选择菜单 
 printf("**********下一个方块:"); 
 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+13); 
 printf("**********"); 
 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+17); 
 printf("↑键:变体"); 
 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+19); 
 printf("空格:暂停游戏"); 
 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+15); 
 printf("Esc :退出游戏"); 

 gotoxy(hOut,FrameX,FrameY);       //打印框角并记住该处已有图案 
 printf("╔"); 
 gotoxy(hOut,FrameX+2*Frame_width-2,FrameY); 
 printf("╗"); 
 gotoxy(hOut,FrameX,FrameY+Frame_height); 
 printf("╚"); 
 gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+Frame_height); 
 printf("╝"); 
 a[FrameX][FrameY+Frame_height]=2;      
 a[FrameX+2*Frame_width-2][FrameY+Frame_height]=2; 

 for(i=2;i<2*Frame_width-2;i+=2) 
 { 
  gotoxy(hOut,FrameX+i,FrameY); 
  printf("═");         //打印上横框 
 } 
 for(i=2;i<2*Frame_width-2;i+=2) 
 { 
  gotoxy(hOut,FrameX+i,FrameY+Frame_height); 
  printf("═");         //打印下横框 
  a[FrameX+i][FrameY+Frame_height]=2;    //记住下横框有图案 
 } 
 for(i=1;i<Frame_height;i++) 
 { 
  gotoxy(hOut,FrameX,FrameY+i);  
  printf("║");         //打印左竖框 
  a[FrameX][FrameY+i]=2;       //记住左竖框有图案 
 } 
 for(i=1;i<Frame_height;i++) 
 { 
  gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+i);  
  printf("║");         //打印右竖框 
  a[FrameX+2*Frame_width-2][FrameY+i]=2;   //记住右竖框有图案 
 } 
} 

/******制作俄罗斯方块********************************************************************/ 
void make_tetris(struct Tetris *tetris) 
{ 
 a[tetris->x][tetris->y]=b[0];    //中心方块位置的图形状态:1-有,0-无 
 switch(tetris->flag)      //共6大类,19种类型 
 { 
  case 1:         //田字方块 
   {   
    a[tetris->x][tetris->y-1]=b[1]; 
    a[tetris->x+2][tetris->y-1]=b[2]; 
    a[tetris->x+2][tetris->y]=b[3]; 
    break; 
   } 
  case 2:         //直线方块:---- 
   {   
    a[tetris->x-2][tetris->y]=b[1]; 
    a[tetris->x+2][tetris->y]=b[2]; 
    a[tetris->x+4][tetris->y]=b[3]; 
    break; 
   } 
  case 3:         //直线方块: | 
   {   
    a[tetris->x][tetris->y-1]=b[1]; 
    a[tetris->x][tetris->y-2]=b[2]; 
    a[tetris->x][tetris->y+1]=b[3]; 
    break; 
   } 
  case 4:         //T字方块 
   {   
    a[tetris->x-2][tetris->y]=b[1]; 
    a[tetris->x+2][tetris->y]=b[2]; 
    a[tetris->x][tetris->y+1]=b[3]; 
    break; 
   } 
  case 5:         //T字顺时针转90度方块 
   {   
    a[tetris->x][tetris->y-1]=b[1]; 
    a[tetris->x][tetris->y+1]=b[2]; 
    a[tetris->x-2][tetris->y]=b[3]; 
    break; 
   } 
  case 6:         //T字顺时针转180度方块 
   {   
    a[tetris->x][tetris->y-1]=b[1]; 
    a[tetris->x-2][tetris->y]=b[2]; 
    a[tetris->x+2][tetris->y]=b[3]; 
    break; 
   } 
  case 7:         //T字顺时针转270度方块 
   {   
    a[tetris->x][tetris->y-1]=b[1]; 
    a[tetris->x][tetris->y+1]=b[2]; 
    a[tetris->x+2][tetris->y]=b[3]; 
    break; 
   } 
  case 8:         //Z字方块 
   {   
    a[tetris->x][tetris->y+1]=b[1]; 
    a[tetris->x-2][tetris->y]=b[2]; 
    a[tetris->x+2][tetris->y+1]=b[3]; 
    break; 
   } 
  case 9:         //Z字顺时针转90度方块 
   {   
    a[tetris->x][tetris->y-1]=b[1]; 
    a[tetris->x-2][tetris->y]=b[2]; 
    a[tetris->x-2][tetris->y+1]=b[3]; 
    break; 
   } 
  case 10:        //Z字顺时针转180度方块 
   {   
    a[tetris->x][tetris->y-1]=b[1]; 
    a[tetris->x-2][tetris->y-1]=b[2]; 
    a[tetris->x+2][tetris->y]=b[3]; 
    break; 
   } 
  case 11:        //Z字顺时针转270度方块 
   {   
    a[tetris->x][tetris->y+1]=b[1]; 
    a[tetris->x+2][tetris->y-1]=b[2]; 
    a[tetris->x+2][tetris->y]=b[3]; 
    break; 
   } 
  case 12:        //7字方块 
   {   
    a[tetris->x][tetris->y-1]=b[1]; 
    a[tetris->x][tetris->y+1]=b[2]; 
    a[tetris->x-2][tetris->y-1]=b[3]; 
    break; 
   } 
  case 13:        //7字顺时针转90度方块 
   {   
    a[tetris->x-2][tetris->y]=b[1]; 
    a[tetris->x-2][tetris->y+1]=b[2]; 
    a[tetris->x+2][tetris->y]=b[3]; 
    break; 
   } 
  case 14:        //7字顺时针转180度方块 
   {   
    a[tetris->x][tetris->y-1]=b[1]; 
    a[tetris->x][tetris->y+1]=b[2]; 
    a[tetris->x+2][tetris->y+1]=b[3]; 
    break; 
   } 
  case 15:        //7字顺时针转270度方块 
   { 
    a[tetris->x-2][tetris->y]=b[1]; 
    a[tetris->x+2][tetris->y-1]=b[2]; 
    a[tetris->x+2][tetris->y]=b[3]; 
    break; 
   } 
  case 16:        //倒7字方块 
   {  
    a[tetris->x][tetris->y+1]=b[1]; 
    a[tetris->x][tetris->y-1]=b[2]; 
    a[tetris->x+2][tetris->y-1]=b[3]; 
    break; 
   } 
  case 17:        //倒7字顺指针转90度方块 
   {  
    a[tetris->x-2][tetris->y]=b[1]; 
    a[tetris->x-2][tetris->y-1]=b[2]; 
    a[tetris->x+2][tetris->y]=b[3]; 
    break; 
   } 
  case 18:        //倒7字顺时针转180度方块 
   {   
    a[tetris->x][tetris->y-1]=b[1]; 
    a[tetris->x][tetris->y+1]=b[2]; 
    a[tetris->x-2][tetris->y+1]=b[3]; 
    break; 
   } 
  case 19:        //倒7字顺时针转270度方块 
   {   
    a[tetris->x-2][tetris->y]=b[1]; 
    a[tetris->x+2][tetris->y+1]=b[2]; 
    a[tetris->x+2][tetris->y]=b[3]; 
    break; 
   } 
 }  
} 

//******判断是否可动*************************************************************************/ 
int if_moveable(struct Tetris *tetris) 
{ 
 if(a[tetris->x][tetris->y]!=0)//当中心方块位置上有图案时,返回值为0,即不可移动 
 { 
  return 0; 
 } 
 else 
 { 
  if( //当为田字方块且除中心方块位置外,其他"口"字方块位置上无图案时,返回值为1,即可移动 
   ( tetris->flag==1  && ( a[tetris->x][tetris->y-1]==0   && 
    a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 
   //或为直线方块且除中心方块位置外,其他"口"字方块位置上无图案时,返回值为1,即可移动 
   ( tetris->flag==2  && ( a[tetris->x-2][tetris->y]==0   &&  
    a[tetris->x+2][tetris->y]==0 && a[tetris->x+4][tetris->y]==0 ) )   || 

   ( tetris->flag==3  && ( a[tetris->x][tetris->y-1]==0   && 
    a[tetris->x][tetris->y-2]==0 && a[tetris->x][tetris->y+1]==0 ) )   || 

   ( tetris->flag==4  && ( a[tetris->x-2][tetris->y]==0   && 
    a[tetris->x+2][tetris->y]==0 && a[tetris->x][tetris->y+1]==0 ) )   || 

   ( tetris->flag==5  && ( a[tetris->x][tetris->y-1]==0   && 
    a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y]==0 ) )   || 

   ( tetris->flag==6  && ( a[tetris->x][tetris->y-1]==0   && 
    a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y]==0 ) )   || 

   ( tetris->flag==7  && ( a[tetris->x][tetris->y-1]==0   && 
    a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) )   || 

   ( tetris->flag==8  && ( a[tetris->x][tetris->y+1]==0   && 
    a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) || 

   ( tetris->flag==9  && ( a[tetris->x][tetris->y-1]==0   && 
    a[tetris->x-2][tetris->y]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) || 

   ( tetris->flag==10 && ( a[tetris->x][tetris->y-1]==0   && 
    a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 

   ( tetris->flag==11 && ( a[tetris->x][tetris->y+1]==0   && 
    a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 

   ( tetris->flag==12 && ( a[tetris->x][tetris->y-1]==0   && 
    a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y-1]==0 ) ) || 

   ( tetris->flag==13 && ( a[tetris->x-2][tetris->y]==0   && 
    a[tetris->x-2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 

   ( tetris->flag==14 && ( a[tetris->x][tetris->y-1]==0   && 
    a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) || 

   ( tetris->flag==15 && ( a[tetris->x-2][tetris->y]==0   && 
    a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 

   ( tetris->flag==16 && ( a[tetris->x][tetris->y+1]==0   && 
    a[tetris->x][tetris->y-1]==0 && a[tetris->x+2][tetris->y-1]==0 ) ) || 

   ( tetris->flag==17 && ( a[tetris->x-2][tetris->y]==0   && 
    a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) || 

   ( tetris->flag==18 && ( a[tetris->x][tetris->y-1]==0   && 
    a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) || 

   ( tetris->flag==19 && ( a[tetris->x-2][tetris->y]==0   && 
    a[tetris->x+2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ) 

   { 
    return 1; 
   } 
 } 
 return 0; 
} 

/******随机产生俄罗斯方块类型的序号**********************************************************/ 
void get_flag(struct Tetris *tetris) 
{ 
 tetris->count++;     //记住产生方块的个数 
 srand((unsigned)time(NULL));  //初始化随机数 
 if(tetris->count==1) 
 { 
  tetris->flag = rand()%19+1;  //记住第一个方块的序号 
 } 
 tetris->next = rand()%19+1;   //记住下一个方块的序号 
} 

/******打印俄罗斯方块**********************************************************************/ 
void print_tetris(HANDLE hOut,struct Tetris *tetris) 
{ 
 for(i=0;i<4;i++) 
 { 
  b[i]=1;         //数组b[4]的每个元素的值都为1 
 } 
 make_tetris(tetris);      //制作俄罗斯方块 
 for( i=tetris->x-2; i<=tetris->x+4; i+=2 ) 
 { 
  for(j=tetris->y-2;j<=tetris->y+1;j++) 
  { 
   if( a[i][j]==1 && j>FrameY ) 
   { 
    gotoxy(hOut,i,j); 
    printf("□");     //打印边框内的方块 
   } 
  } 
 } 
 //打印菜单信息 
 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+1); 
 printf("level : %d",tetris->level); 
 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+3); 
 printf("score : %d",tetris->score); 
 gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+5); 
 printf("speed : %dms",tetris->speed); 
} 

附上视频教学:

https://www.bilibili.com/video/BV1zt4y1977U/

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小编。

另外本程序还需要一部分头文件,想要领取可以添加小编的C语言/C++交流④群:836880131,源码在群文件里

福利来袭~

学习过程很“痛苦”,但是结果大家一定会对自己很满意!

如果觉得学习资料难找的话,可以添加小编的C语言/C++交流群:836880131! 学习资料已经共享在群里了,期待你的加入~

image

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350