鱼C论坛

 找回密码
 立即注册
查看: 4591|回复: 21

[技术交流] 俄罗斯方块源码 我又来炫啦!!!

[复制链接]
发表于 2016-2-1 15:44:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
上一次些的贪吃蛇  http://bbs.fishc.com/thread-68229-1-1.html
这段时间学习指针和结构,确实很难,但也啃下来啦
在做这个俄罗斯方块的时候,方块结构没有设计好,导致后面改的一塌糊涂,心都弄累了 ;所以后面写的有点潦草了
  1. #include <stdio.h>
  2. #include <time.h>
  3. #include <stdlib.h>
  4. #include <conio.h>
  5. #include <windows.h>

  6. #define kd 14   //宽度
  7. #define gd 23        //高度

  8. //----------功能键设置------------
  9. #define zuoyi 'a' //左移动
  10. #define youyi 'd'//右移动
  11. #define xiayi 's'//下移动 (加速)
  12. #define bx '-' //变形
  13. #define zt '+' //暂停

  14. /* run this program using the console pauser or add your own getch, system("pause") or input loop */

  15. //---------------定义结构----------------------
  16. typedef struct{//坐标结构
  17.         int x;
  18.         int y;
  19. }zb;

  20. typedef struct{//方块结构
  21.         int lx;   //他的类型  0是田  1是T 2是F,3是N,4是条
  22.         int x1;//3初始
  23.         int y1;//2初始
  24.         zb zb;                //他的坐标,中心点
  25.         const char *p[6];//指向一个形状地址;
  26. }xz;


  27. //----------------定义函数---------------------
  28. void gotoxy( int x, int y );

  29. void chushi();//初始一些数据
  30. void printf_dy();//打印地图数据
  31. void bianxing(xz*dqxz);//变形 (方块指针,旋转几次)
  32. char jieshou();//接受字符输入,直到接受到字符才返回;
  33. int get_c();//缓冲区获取一个功能键状态,如果获取失败,返回字符-1   (马上返回 )  -1失败  0左移 1下移动 2右移动 3变型 4暂停
  34. int jiance(int n);//下左右移动检测   OK返回1,失败返回0
  35. void zanting();//暂停
  36. int yidong(int n);//根据方向移动, 到底部,返回-1
  37. int jiaru();//将当前不能下降的方块加入到障碍物数组里面;并消行,返回有多少行消了
  38. void xiaohang(int h);//消行(行坐标)
  39. void shenchan();//生产方块  
  40. int naozhong();//闹钟,间隔多久


  41. //-------------定义全局变量-------------------

  42. const char *ditu[kd][gd];//地图
  43. const char *zhangaiwu[kd][gd] ;//障碍物
  44. clock_t jg;
  45. int nd;//设置难度,就是方块下降的速度 间隔时间,微妙
  46. int sfch;//是否重行绘制  1绘制  0不绘制
  47. int jifen;//当前玩了多少分
  48. xz dqxz; //当前形状 ------
  49. xz xgxz;//下一个形状--------------
  50. xz lsxz; //临时形状----
  51. const char *leixing[5][6]={                                                                                                //这里的指针都是指向常量区的,大家可以添加跟多的方块类型
  52.                                                 {"■","■","■","■","  ","  "},//方块田比较特殊,旋转就不用旋转
  53.                                                 {"■","  ","■","■","■","  "}, //T块
  54.                                                 {"■","■","■","  ","■","  "}, //F块       
  55.                                                 {"  ","■","■","■","■","  "}, //N块
  56.                                                 {"■","  ","■","  ","■","  "}, //条块                                       
  57.                                                 };

  58. int fx[6]={-1,0,1,0,1,0};//方向坐标

  59. //-----------------------函数-------------------------------

  60. int naozhong(){
  61.         clock_t njg=clock();
  62.         if(njg-jg>=nd){
  63.                 jg=njg;
  64.                 return 1;
  65.         }else{
  66.                 return 0;
  67.         }
  68. }

  69. void shenchan(){
  70.        
  71.         dqxz.zb =xgxz.zb ;
  72.         dqxz.x1 =xgxz.x1;
  73.         dqxz.y1 =xgxz.y1;
  74.         dqxz.lx =xgxz.lx;
  75.         int n;
  76.         for(n=0;n<6;n++){
  77.                 dqxz.p[n] =xgxz.p[n];
  78.         }
  79.        
  80.         //生产一个下一个方块数据
  81.         xgxz.lx=rand()%5;
  82.         xgxz.x1=3;
  83.         xgxz.y1=2;
  84.         xgxz.zb .x=(kd-2)/2;
  85.         xgxz.zb.y =-1;
  86.         for(n=0;n<6;n++){
  87.                 xgxz.p[n]=        leixing[xgxz.lx][n];
  88.         }
  89.         for(n=0;n<rand()%5;n++){
  90.                 bianxing(&xgxz);
  91.         }
  92.        
  93. }

  94. int jiaru(){//加入障碍物 ,返回有多少行可以消
  95.         int x1,y1,x,y,m,n=0;
  96.                
  97.         for(y=0;y<dqxz.x1 ;y++){//打印方块
  98.                 for(x=0;x<dqxz.y1 ;x++){
  99.                         if(*(dqxz.p +n)=="■" ){
  100.                                 x1=dqxz.zb .x+x;
  101.                                 y1=dqxz.zb .y+y;
  102.                                 zhangaiwu[x1][y1]="■";                                       
  103.                         }
  104.                         n++;
  105.                 }
  106.         }
  107.         m=0;
  108.         for(y1=0;y1<dqxz.x1 ;y1++){
  109.                 n=0;
  110.                 for(x=0;x<kd;x++){
  111.                         y=dqxz.zb .y+y1;
  112.                         if(zhangaiwu[x][y]=="■" && y<gd-1)        {
  113.                                 n++;
  114.                         }
  115.                 }
  116.                 if(n==kd){
  117.                         xiaohang(y);       
  118.                         m++;
  119.                 }       
  120.         }
  121.         return m;
  122. }

  123. void xiaohang(int h){//消行坐标
  124.         int x,y,y1;
  125.         for(y1=0;y1<h;y1++){
  126.                 for(x=1;x<kd-1;x++){
  127.                         y=h-y1;
  128.                         if(y>0){
  129.                                 zhangaiwu[x][y]=zhangaiwu[x][y-1];
  130.                         }else{
  131.                                 zhangaiwu[x][y]=". ";
  132.                         }               
  133.                 }               
  134.         }
  135. }       

  136. int yidong(int n){//根据字符控制方块状态,如果到底部,则返回-1
  137.         int f=1;
  138.                
  139.         if(jiance(n)==1){

  140.                 if(n==1){
  141.                         while(jiance(n)==1){
  142.                         dqxz.zb .x=dqxz.zb .x+fx[n];
  143.                         dqxz.zb .y=dqxz.zb .y+fx[n+3];               
  144.                         }
  145.                 }else{               
  146.                         dqxz.zb .x=dqxz.zb .x+fx[n];
  147.                         dqxz.zb .y=dqxz.zb .y+fx[n+3];       
  148.                 }       
  149.         }
  150.         if(jiance(1)==0){
  151.                 f=0;
  152.         }       
  153.         return f;               
  154. }

  155. void gotoxy( int x, int y ){
  156.         COORD c;
  157.         c.X = x - 1; c.Y = y - 1;
  158.         SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), c );
  159. }

  160. void zanting(){//暂停
  161.         gotoxy(kd*2+2,gd/2+7);
  162.         printf("请安“+”加号键继续!!");
  163.         while(jieshou()!='+'){//游戏继续啦
  164.         }
  165.         gotoxy(kd*2+2,gd/2+7);
  166.         printf(" -变形  +暂停         ");
  167. }


  168. int jiance(int f){//下左右移动检测   OK返回1,失败返回0
  169.         xz lsxz;//零时形状

  170.         int x,y,n=0,m=1;
  171.         int x1,y1;
  172.        
  173.         lsxz=dqxz;       
  174.         lsxz.zb .x=lsxz.zb.x +fx[f];
  175.         lsxz.zb .y=lsxz.zb.y +fx[f+3];
  176.        
  177.         for(y=0;y<lsxz.x1 ;y++){//打印方块
  178.                 for(x=0;x<lsxz.y1 ;x++){
  179.                         if(*(dqxz.p +n)=="■" ){
  180.                                 x1=lsxz.zb .x+x;
  181.                                 y1=lsxz.zb .y+y;
  182.                                         if(x1<1 ||x1>kd-2 ||y1<0 ||y1>gd-2){
  183.                                                 m=0;
  184.                                                 break;                       
  185.                                         }else if( zhangaiwu[x1][y1]=="■" && y1>0){               
  186.                                                 m=0;
  187.                                                 break;
  188.                                         }                       
  189.                         }
  190.                         n++;
  191.                 }
  192.         }       
  193.         return m;
  194. }


  195. int get_c(){//缓冲区获取一个功能键状态,如果获取失败,返回字符-1   (马上返回 )  -1失败  0左移 1下移动 2右移动 3变型 4暂停
  196.         char ls;
  197.         int n=-1;
  198.         if(kbhit()!=0){
  199.                 ls=getch();
  200.                 while(kbhit()){
  201.                         getch();
  202.                 }
  203.         }
  204.         switch(ls){
  205.                 case zuoyi:n=0;break;       
  206.                 case youyi:n=2;break;
  207.                 case xiayi:n=1;break;
  208.                 case bx:n=3;break;       
  209.                 case zt:n=4;break;
  210.         }
  211.         return n;       
  212. }  

  213. void bianxing(xz*ybxz){//变形 (方块指针,旋转几次)
  214.         if(ybxz->lx==0){
  215.                 return ;
  216.         }
  217.         int x,y,n,i;
  218.         int z[2][6]={{4,2,0,5,3,1},{3,0,4,1,5,2}};
  219.         int z2[3][2]={{2,3},{3,2},{1,-1}};
  220.        
  221.         lsxz.zb=ybxz->zb ;
  222.                          
  223.         if(ybxz->x1==2){       
  224.                 i=1;       
  225.         }else{
  226.                 i=0;
  227.         }       
  228.         for(n=0;n<6;n++){//旋转
  229.                 lsxz.p[n]=ybxz->p[z[i][n]];               
  230.         }
  231.         lsxz.zb.y=lsxz.zb.y +z2[2][i];//旋转之后的坐标的变换,我这里只简单处理了下,具体的坐标是这么样的没研究出来,考亲们研究啦
  232.         lsxz.x1 =z2[0][i];
  233.         lsxz.y1 =z2[1][i];
  234. //---------------------------------
  235.         int x1,y1,m=1;
  236.         n=0;
  237.         for(y=0;y<lsxz.x1  ;y++){//遍历
  238.                 for(x=0;x<lsxz.y1;x++){
  239.                         if(lsxz.p[n]=="■" ){
  240.                                 x1=lsxz.zb .x+x;
  241.                                 y1=lsxz.zb .y+y;
  242.                                         if(x1<1 ||x1>kd-2 ||y1>gd-2){
  243.                                                 m=0;
  244.                                                 break;                       
  245.                                         }else if( zhangaiwu[x1][y1]=="■" && y1>0){               
  246.                                                 m=0;
  247.                                                 break;
  248.                                         }                       
  249.                         }
  250.                         n++;
  251.                 }
  252.         }       

  253. //--------------------------------------------       
  254.         if(m==1){//如果零时方块和障碍物没有重叠,则把零时方块的信息复制个当前方块
  255.                 ybxz->zb =lsxz.zb;
  256.                 ybxz->x1=lsxz.x1 ;
  257.                 ybxz->y1=lsxz.y1 ;       
  258.                 for(n=0;n<6;n++){
  259.                         ybxz->p[n]=lsxz.p [n];       
  260.                 }
  261.         }       
  262. }


  263. void chushi(){//初始一些数据
  264.         jifen=0;//初始化积分
  265.         srand((unsigned int)time(NULL));//初始化随机种子
  266.         jg=clock();//初始化时间
  267.         nd=300;//初始化难度,毫米级别
  268. //---------初始化下个形状的数据---------------
  269.         int n;
  270.         xgxz.lx=rand()%5;
  271.         xgxz.x1=3;
  272.         xgxz.y1=2;
  273.         xgxz.zb .x=(kd-2)/2;
  274.         xgxz.zb.y =-1;
  275.        
  276.         for(n=0;n<6;n++){
  277.                 xgxz.p[n]=        leixing[xgxz.lx][n];
  278.         }
  279.        
  280.         shenchan(); //产生一个方块
  281.         int x,y;
  282.         for(y=0;y<gd;y++){//初始化障碍物
  283.                 for(x=0;x<kd;x++){
  284.                         if(x==0||x==kd-1||y==gd-1){
  285.                                 zhangaiwu[x][y]="■";
  286.                         }else{
  287.                                 zhangaiwu[x][y]=". ";
  288.                         }
  289.                 }
  290.         }               
  291. }

  292. void printf_dy(){//打印地图数据
  293.         int x,y,n=0;
  294.        
  295.         for(y=0;y<gd;y++){//初始化地图
  296.                 for(x=0;x<kd;x++){
  297.                         if(x==0||x==kd-1||y==0||y==gd-1){
  298.                                 ditu[x][y]="●";
  299.                         }else{
  300.                                 ditu[x][y]=zhangaiwu[x][y];
  301.                         }
  302.                 }
  303.         }
  304. //        system("cls");       
  305.         for(y=0;y<dqxz.x1 ;y++){//打印方块
  306.                 for(x=0;x<dqxz.y1 ;x++){
  307.                         int x1=dqxz.zb .x+x;
  308.                         int y1=dqxz.zb .y+y;
  309.                         if(dqxz.p[n]=="■" && x1>0 &&x<kd-1 && y1>0 && y<gd-1){
  310.                                 ditu[x1][y1]=dqxz.p[n];       
  311.                         }
  312.                         n++;
  313.                 }
  314.         }       
  315.         gotoxy(1,1);//将光标移到最上面       
  316.         for(y=0;y<gd;y++){//打印地图
  317.                 for(x=0;x<kd;x++){
  318.                         printf("%s",ditu[x][y]);
  319.                 }
  320.                 printf("\n");
  321.         }
  322.         gotoxy(kd*2+2,gd/2-4);
  323.         printf("---下个方块---");
  324.         n=0;
  325.         for(x=0;x<3;x++){
  326.                 gotoxy(kd*2+6,gd/2-2+x);
  327.                 for(y=0;y<3 ;y++){
  328.                         if(x<xgxz.x1 && y<xgxz.y1 ){
  329.                                 printf("%s",xgxz.p[n]);
  330.                                 n++;
  331.                         }else{
  332.                                 printf("   ");
  333.                         }
  334.                 }       
  335.         }
  336.         gotoxy(kd*2+2,gd/2+2);
  337.         printf("---游戏积分---");
  338.         gotoxy(kd*2+2,gd/2+3);
  339.         printf("      %d",jifen*10);
  340.         gotoxy(kd*2+2,gd/2+5);
  341.         printf("---控制按钮---");
  342.         gotoxy(kd*2+2,gd/2+6);
  343.         printf(" A下 S下 D右 ");
  344.         gotoxy(kd*2+2,gd/2+7);
  345.         printf(" -变形  +暂停 ");
  346. }

  347. char jieshou(){//接受字符输入,直到接受到字符才返回;
  348.         while( !kbhit() ){
  349.                 Sleep(20);       
  350.         }
  351.         char ls=getch();
  352.        
  353.         while(kbhit()){
  354.                         getch();
  355.                 }
  356.         return ls;       
  357. }

  358. int main(int argc, char *argv[]) {
  359.         chushi();
  360.         int jc,n;
  361.        
  362.         while(1){
  363.                 if(sfch=1){//检测是否重行绘制
  364.                         printf_dy();
  365.                         sfch=0;
  366.                 }
  367.                 jc=jiance(1);
  368.                 if(jc==1){//这里检测是否能往下移动
  369.                         if(sfch=naozhong()){
  370.                                 dqxz.zb .y=dqxz.zb .y+1;
  371.                         }
  372.                 }else if(jc==0 && dqxz.zb .y<0){//检测是否到顶部了,到顶部了就结束游戏
  373.                         system("cls");
  374.                         printf("游戏失败");//放假了心静不下来,不想搞了,简单处理
  375.                         break;
  376.                 }else{        //不能移动了,就说明到底部了,把当前方块加入到障碍物里面
  377.                         jifen=jiaru()+jifen;
  378.                         nd=nd*19/20;//放假了心静不下来,不想搞了,简单处理
  379.                         shenchan();
  380.                 }       
  381.                 n=get_c();//从键盘区获取一个功能键状态  -1失败  0左移 1下移动 2右移动 3变型 4暂停
  382.                 switch(n){
  383.                         case -1:;break;//非法移动
  384.                         case 4://暂停
  385.                                 zanting();
  386.                                 break;       
  387.                         case 3:
  388.                                 bianxing(&dqxz);
  389.                                 sfch=1;
  390.                                 break;//变型
  391.                        
  392.                         default: //移动
  393.                                 yidong(n);
  394.                                 sfch=1;
  395.                                 break;       
  396.                 }
  397.         }

  398.         return 0;
  399. }
复制代码
GIF.gif

俄罗斯方块.zip

293.93 KB, 下载次数: 75

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-2-1 19:41:51 | 显示全部楼层
楼主相当厉害啊,六六六,膜拜。这东西新手怎么可能写的出来啊!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 19:59:10 | 显示全部楼层
你现在什么职业?学生还是什么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 20:43:49 | 显示全部楼层
zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?

论坛里装作菜鸟的很多了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 20:43:49 | 显示全部楼层
zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?

论坛里装作菜鸟的很多了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 20:45:09 | 显示全部楼层
这回VS下编译通过了 不过运行时奔溃了。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 21:05:39 | 显示全部楼层
66666666666666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-1 22:30:26 | 显示全部楼层
厉害厉害
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-2 09:50:29 | 显示全部楼层
这么牛逼
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-2 10:32:27 | 显示全部楼层
zlh 发表于 2016-2-1 19:59
你现在什么职业?学生还是什么?

我从事的工作是平面设计,我喜欢编程
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-2 10:34:06 | 显示全部楼层
黑龍 发表于 2016-2-1 20:45
这回VS下编译通过了 不过运行时奔溃了。。。

你在什么环境下运行的啊,我的WIN10,没出现问题,附件里面有编译好了的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-2 10:51:16 | 显示全部楼层
ligen超越 发表于 2016-2-2 10:34
你在什么环境下运行的啊,我的WIN10,没出现问题,附件里面有编译好了的

WIN7的VS2012
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-2 10:51:33 | 显示全部楼层
ligen超越 发表于 2016-2-2 10:34
你在什么环境下运行的啊,我的WIN10,没出现问题,附件里面有编译好了的

游戏写的挺好的 加油吧~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-5 23:18:35 | 显示全部楼层
楼主写得好。加油。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2016-2-6 11:59:58 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-2-6 12:29:30 | 显示全部楼层
好东西,感谢分享!努力学习!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-20 13:34:38 | 显示全部楼层
我看一个汇编教程,进阶就是用汇编写贪吃蛇和俄罗斯方块俩程序,卧槽你们是不是一个人...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-21 20:26:48 | 显示全部楼层
zjk 发表于 2016-2-20 13:34
我看一个汇编教程,进阶就是用汇编写贪吃蛇和俄罗斯方块俩程序,卧槽你们是不是一个人...

不是的啊,我现在学算法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-2-22 16:54:47 | 显示全部楼层
不知道你用的什么软件编译的~~VC6.0 不成功啊。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-2-23 13:29:21 | 显示全部楼层
lovly714366 发表于 2016-2-22 16:54
不知道你用的什么软件编译的~~VC6.0 不成功啊。。。

用的DEV-C++,你下载附件试试
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-25 12:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表