Logo



c俄罗斯方块源码思路(c++做俄罗斯方块代码)

本文目录一览:

怎样用c语言编写俄罗斯方块程序?

俄罗斯方块C源代码

#include stdio.h

#include windows.h

#include conio.h

#include time.h

#define  ZL  4     //坐标增量, 不使游戏窗口靠边

#define WID  36    //游戏窗口的宽度

#define HEI  20    //游戏窗口的高度

int i,j,Ta,Tb,Tc;      // Ta,Tb,Tc用于记住和转换方块变量的值

int a[60][60]={0};    //标记游戏屏幕各坐标点:0,1,2分别为空、方块、边框

int b[4];        //标记4个"口"方块:1有,0无,类似开关

int x,y, level,score,speed;    //方块中心位置的x,y坐标,游戏等级、得分和游戏速度

int flag,next;   //当前要操作的方块类型序号,下一个方块类型序号

void gtxy(int m, int n);   //以下声明要用到的自编函数

void gflag( );  //获得下一方块序号

void csh( );  //初始化界面

void start( );  //开始部分

void prfk ( );  //打印方块

void clfk( );  //清除方块

void mkfk( );  //制作方块

void keyD( );  //按键操作

int  ifmov( );  //判断方块能否移动或变体

void clHA( );  //清除满行的方块

void clNEXT( );  //清除边框外的NEXT方块

int main( )

{ csh( );   

   while(1)

     {start( );  //开始部分

       while(1)

       { prfk( );  

         Sleep(speed);  //延时

          clfk( );

          Tb=x;Tc=flag;  //临存当前x坐标和序号,以备撤销操作

          keyD( );  

          y++;     //方块向下移动

         if (ifmov( )==0) { y--; prfk( ); dlHA( ); break;} //不可动放下,删行,跨出循环

      for(i=y-2;iy+2;i++){ if (i==ZL) { j=0; } }  //方块触到框顶

     if (j==0) { system("cls");gtxy(10,10);printf("游戏结束!"); getch(); break; } 

     clNEXT( );   //清除框外的NEXT方块

  return 0;

void gtxy(int m, int n)  //控制光标移动

{COORD pos;  //定义变量

pos.X = m;  //横坐标

pos.Y = n;   //纵坐标

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);

void csh( )    //初始化界面

{gtxy(ZL+WID/2-5,ZL-2); printf("俄罗斯方块");      //打印游戏名称

gtxy(ZL+WID+3,ZL+7); printf("******* NEXT:");  //打印菜单信息

gtxy(ZL+WID+3,ZL+13); printf("**********");

gtxy(ZL+WID+3,ZL+15); printf("Esc :退出游戏");

gtxy(ZL+WID+3,ZL+17); printf("↑键:变体");

gtxy(ZL+WID+3,ZL+19); printf("空格:暂停游戏");

gtxy(ZL,ZL);  printf("╔");  gtxy(ZL+WID-2,ZL);  printf("╗");  //打印框角

gtxy(ZL,ZL+HEI);  printf("╚");  gtxy(ZL+WID-2,ZL+HEI);  printf("╝");

a[ZL][ZL+HEI]=2;  a[ZL+WID-2][ZL+HEI]=2;  //记住有图案

for(i=2;iWID-2;i+=2) {gtxy(ZL+i,ZL);  printf("═"); }  //打印上横框

for(i=2;iWID-2;i+=2) {gtxy(ZL+i,ZL+HEI); printf("═"); a[ZL+i][ZL+HEI]=2; } //下框

for(i=1;iHEI;i++) { gtxy(ZL,ZL+i);  printf("║"); a[ZL][ZL+i]=2; }  //左竖框记住有图案

for(i=1;iHEI;i++) {gtxy(ZL+WID-2,ZL+i); printf("║"); a[ZL+WID-2][ZL+i]=2; } //右框

CONSOLE_CURSOR_INFO cursor_info={1,0};   //以下是隐藏光标的设置

SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),cursor_info);

level=1; score=0; speed=400;

gflag( );  flag=next;  //获得一个当前方块序号

void gflag( )   //获得下一个方块的序号

{ srand((unsigned)time(NULL)); next = rand()%19+1; }

void start( )  //开始部分

{ gflag( ); Ta=flag; flag=next;  //保存当前方块序号,将下一方块序号临时操作

x=ZL+WID+6; y=ZL+10; prfk( );  //给x,y赋值,在框外打印出下一方块

flag=Ta; x=ZL+WID/2; y=ZL-1;  //取回当前方块序号,并给x,y赋值

void prfk ( )  //打印俄罗斯方块

{ for(i=0;i4;i++) {b[i]=1; }  //数组b[4]每个元素的值都为1

mkfk ( );  //制作俄罗斯方块

for( i= x-2; i=x+4; i+=2 )  //打印方块

{ for(j=y-2;j= y+1;j++) { if( a[i][j]==1  jZL ){ gtxy(i,j); printf("□"); } } }

gtxy(ZL+WID+3,ZL+1);   printf("level : %d",level);  //以下打印菜单信息

gtxy(ZL+WID+3,ZL+3);  printf("score : %d",score);

gtxy(ZL+WID+3,ZL+5);  printf("speed : %d",speed);

void clfk( )  //清除俄罗斯方块

{ for(i=0;i4;i++) { b[i]=0; }  //数组b[4]每个元素的值都为0

mkfk ( );  //制作俄罗斯方块

for( i=x-2; i=x+4; i+=2 )  //清除方块

{ for(j=y-2;j=y+1;j++){ if( a[i][j]==0  jZL ){ gtxy(i,j); printf("  "); } } }

void mkfk( )  //制作俄罗斯方块

{ a[x][ y]=b[0];  //方块中心位置状态: 1-有,0-无

switch(flag)   //共6大类,19种小类型

{ case 1: { a[x][y-1]=b[1]; a[x+2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //田字方块

case 2: { a[x-2][y]=b[1]; a[x+2][y]=b[2]; a[x+4][y]=b[3]; break; }  //直线方块:----

case 3: { a[x][y-1]=b[1]; a[x][y-2]=b[2]; a[x][y+1]=b[3]; break; }  //直线方块: |

case 4: { a[x-2][y]=b[1]; a[x+2][y]=b[2]; a[x][y+1]=b[3]; break; }  //T字方块

case 5: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x-2][y]=b[3]; break; }  //T字顺时针转90度

case 6: { a[x][y-1]=b[1]; a[x-2][y]=b[2]; a[x+2][y]=b[3]; break; }  //T字顺转180度

case 7: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x+2][y]=b[3]; break; }  //T字顺转270度

case 8: { a[x][y+1]=b[1]; a[x-2][y]=b[2]; a[x+2][y+1]=b[3]; break; } //Z字方块

case 9: { a[x][y-1]=b[1]; a[x-2][y]=b[2]; a[x-2][y+1]=b[3]; break; }  //Z字顺转90度

case 10: { a[x][y-1]=b[1]; a[x-2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //Z字顺转180度

case 11: { a[x][y+1]=b[1]; a[x+2][y-1]=b[2]; a[x+2][ y]=b[3]; break; } //Z字顺转270度

case 12: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x-2][y-1]=b[3]; break; }  //7字方块

case 13: {a[x-2][y]=b[1]; a[x+2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //7字顺转90度

case 14: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x+2][y+1]=b[3]; break; }  //7字顺转180度

case 15: { a[x-2][y]=b[1]; a[x-2][y+1]=b[2]; a[x+2][y]=b[3]; break; }  //7字顺转270度

case 16: { a[x][y+1]=b[1]; a[x][y-1]=b[2]; a[x+2][y-1]=b[3]; break; }  //倒7字方块

case 17: { a[x-2][y]=b[1]; a[x+2][y+1]=b[2]; a[x+2][y]=b[3]; break; }  //倒7字顺转90度

case 18: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x-2][y+1]=b[3]; break; }  //倒7字顺转180度

case 19: { a[x-2][y]=b[1]; a[x-2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //倒7字顺转270度

void keyD( )  //按键操作

{ if (kbhit( ))

{ int key;

   key=getch();

if (key==224)

{ key=getch();

       if (key==75) { x-=2; }  //按下左方向键,中心横坐标减2

if (key==77) { x+=2; }  //按下右方向键,中心横坐标加2

      if (key==72)     //按下向上方向键,方块变体

{ if (flag=2  flag=3 ) { flag++; flag%=2; flag+=2; }

if ( flag=4  flag=7 ) { flag++; flag%=4; flag+=4; }

if (flag=8  flag=11 ) { flag++; flag%=4; flag+=8; }

if (flag=12  flag=15 ) { flag++; flag%=4; flag+=12; }

if ( flag=16  flag=19 ) { flag++; flag%=4; flag+=16; } }

    if (key==32)     //按空格键,暂停

{ prfk( ); while(1) { if (getch( )==32) { clfk( );break;} } }  //再按空格键,继续游戏

    if (ifmov( )==0) { x=Tb; flag=Tc; }  //如果不可动,撤销上面操作

    else { prfk( ); Sleep(speed); clfk( ); Tb=x;Tc=flag;}   //如果可动,执行操作

int ifmov( )   //判断能否移动

{ if (a[x][y]!=0) { return 0; }  //方块中心处有图案返回0,不可移动

else{ if ( (flag==1  ( a[x][ y-1]==0  a[x+2][y-1]==0  a[x+2][y]==0 ) ) ||

       (flag==2  ( a[x-2][y]==0  a[x+2][y]==0  a[x+4][y]==0 ) ) ||

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     (flag==19 ( a[x-2][y]==0 a[x-2][y-1]==0

             a[x+2][y]==0 ) ) ) { return 1; }

return 0;   //其它情况返回0

void clNEXT( )   //清除框外的NEXT方块

{ flag = next;  x=ZL+WID+6;  y=ZL+10;  clfk( ); }

void clHA( )   //清除满行的方块

{ int k, Hang=0;    //k是某行方块个数, Hang是删除的方块行数

for(j=ZL+HEI-1;j=ZL+1;j--)  //当某行有WID/2-2个方块时,则为满行

{ k=0; for(i=ZL+2;iZL+WID-2;i+=2)

{ if (a[i][j]==1)   //竖坐标从下往上,横坐标由左至右依次判断是否满行

{ k++;   //下面将操作删除行

     if (k==WID/2-2)  {   for(k=ZL+2;kZL+WID-2;k+=2)

         { a[k][j]=0; gtxy(k,j); printf("  "); Sleep(1); }

        for(k=j-1;kZL;k--)

        { for(i=ZL+2;iZL+WID-2;i+=2)  //已删行数上面有方块,先清除再全部下移一行

          { if(a[i][k]==1) { a[i][k]=0; gtxy(i,k); printf("  ");a[i][k+1]=1;

            gtxy(i,k+1); printf("□"); } }

        j++;     //方块下移后,重新判断删除行是否满行

        Hang++;  //记录删除方块的行数

score+=100*Hang;   //每删除一行,得100分

if ( Hang0  (score%500==0 || score/500 level-1 ) )  //得分满500速度加快升一级

  { speed-=20; level++; if(speed200)speed+=20; }

C语言代码俄罗斯方块(yCodeBlocks)?

#include "mywindows.h"

HANDLE handle;

// 初始化句柄

void initHandle()

handle = GetStdHandle(STD_OUTPUT_HANDLE);

// 设置颜色

void setColor(int color)

SetConsoleTextAttribute(handle, color);

void setPos(int x, int y)

COORD coord = {x*2, y};

SetConsoleCursorPosition(handle, coord);

// 设置光标是否可见

void setCursorVisible(int flag)

CONSOLE_CURSOR_INFO info;

info.bVisible = flag; //光标是否可见

info.dwSize = 100; //光标宽度1-100

SetConsoleCursorInfo(handle, info);

// 关闭句柄

void closeHandle()

CloseHandle(handle);

求俄罗斯方块C语言设计思路

最基础就是二维数组做c俄罗斯方块源码思路,当某一行满的时候删除这一行c俄罗斯方块源码思路,固定形状从a[0][0]开始定义c俄罗斯方块源码思路,完了自己隔一秒变一次二维c俄罗斯方块源码思路,也就是

a[1][0],怎么变换也事先写好对应数组哪个位置,应该就是这样吧

用c语言编写俄罗斯方块程序 求详解

在写一个程序之前得先有思路,本题中得思路是:

随机给出不同的形状(长条形、Z字形、反Z形、田字形、7字形、反7形、T字型)下落填充给定的区域,若填满一条便消掉,记分,当达到一定的分数时,过关,每关方块下落的速度不同,若在游戏中各形状填满了给定区域,为输者。

有了思路再动手,如果不会可以参考一下别人开源的项目!

因为项目复杂性,我给出了一个俄罗斯方块程序的项目地址在最后,祝您好运!

项目地址:俄罗斯方块游戏

谁能大致描述一下C语言做俄罗斯方块的思想

#include stdlib.h /*标准库*/

#include graphics.h /*绘图库*/

#include bios.h /*BIOS库c俄罗斯方块源码思路,输入输出c俄罗斯方块源码思路,BIOS时间等*/

#define mDRAW 5 /*各种消息的宏定义*/

#define mLINE 6

#define mADOWN 7

#define mGEN 8

#define mLEFT 75

#define mRIGHT 77

#define mSPACE 57

#define mDOWN 80

#define mESC 1

#define TIMEINT 2 //下落间隔时间c俄罗斯方块源码思路,即下落速度

#define MAXX 9 /*行列数,9×30的区域*/

#define MAXY 30

#define BACKCOLOR BLACK /*背景色*/

#define WINX 50 //游戏box所在的位置,单位为像素,下同

#define WINY 470

#define GAP 6 //间隙宽度

#define AREAX (WINX+GAP)

#define AREAY (WINY-GAP)

#define BOXW 15 //每一小格的宽度

int oldarea[MAXY+1][MAXX]; //为和当前游戏区域进行比较而保存的上一游戏区域信息

int area[MAXY+1][MAXX]; //游戏区域的方块信息,有方块计1,否则计0.

int actW,actH,actX,actY; //方块可活动的X、Y、宽、高信息

int curX,curY,curColor,curW,curH; //方块当前的X、Y、宽、高、颜色信息

int newX,newY,newColor,newW,newH; //方块新的(或称为接受控制消息后计算出的下一状态的)X、Y、宽、高、颜色信息

int active; //游戏是否处于active状态

int box[4][4]; /*方块的二维数组,定义当前方块*/

int FORCOLOR; /*前景色*/

int MESSAGE; //方块位置控制消息

int BOX[7][4][4]={ /*7个不同的方块定义成4×4的数组,可以看成产生方块的模板*/

{1,1,1,1}, /*直棍*/

{0,0,0,0},

{0,0,0,0},

{0,0,0,0}

{1,1,1,0},/*右弯*/

{1,0,0,0},

{0,0,0,0},

{0,0,0,0}

{1,1,1,0}, /*左弯*/

{0,0,1,0},

{0,0,0,0},

{0,0,0,0}

{1,1,1,0}, /*T型*/

{0,1,0,0},

{0,0,0,0},

{0,0,0,0}

{1,1,0,0}, /*左Z*/

{0,1,1,0},

{0,0,0,0},

{0,0,0,0}

{0,1,1,0}, /*右Z*/

{1,1,0,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}

//子函数下面详细说明

void init(); //初始化

void draw(); //绘图

int genBox();

int getKey();

void lineFull();

int moveLeft();

int moveRight();

int moveDown();

int rotate();

int getW();

int getH();

void clearOldBox();

void putNewBox();

int collisionRotate(int box[][4]);

void getMessage();

void dispatchMessage();

int timeCome();

void fallDown();

int gameOver();

/*------------主函数----------------*/

main()

int i;

init();

do //循环

getMessage(); //获得方块位置控制消息

dispatchMessage(); //根据不同的消息做出不同的动作

while(!gameOver()); //直到游戏结束

getch(); //使用getch()让程序停在这里,按下任意键后

closegraph(); //就可关闭图形,结束游戏

/*------------子函数--------------*/

void getMessage()

if(MESSAGE) return; //除接受键盘消息外,方块的动作函数也会产生一些消息如果有一个消息尚未处理,则直接返回处理它

if(timeCome()) //计时时间到

MESSAGE=mADOWN; //控制消息=mADOWN,自动落下一格

return;

if(bioskey(1)) //查询是否有键盘消息

MESSAGE=bioskey(0)8;/*bioskey(0)返回键盘按键低8位数的ASCII码,因此右移8位,生成消息*/

return;

void dispatchMessage() //根据不同的消息做出不同的动作

switch(MESSAGE)

case mLEFT: moveLeft();break; //以下分别代表左、右、

case mRIGHT: moveRight();break;//下、旋转、落下、绘图、行满、生成方块等动作

case mADOWN: moveDown();break;

case mSPACE: rotate();break;

case mDOWN: fallDown(); break;

case mDRAW: draw();break;

case mLINE: lineFull();break;

case mGEN: genBox();break;

case mESC: closegraph(); exit(0);//退出

default: MESSAGE=0;

void fallDown()

while(active)//如果游戏active

moveDown(); draw(); //向下落,绘图

MESSAGE=mLINE;

int timeCome() //计时函数

static long tm, old; //两个时间,一个从BIOS中取得的新时间,一个上一次获得的时间

tm=biostime(0,tm);

if(tm-oldTIMEINT) return 0; //判断间隔

else

old=tm; return 1;

void init()

int i,j,x1,y1,x2,y2;

int driver=DETECT, mode=0; // 定义图形驱动模式为自检模式

randomize(); //初始化随机数生成器

registerbgidriver(EGAVGA_driver);//建立独立图形运行程序

initgraph(driver,mode,""); //直接进行的图形初始化程序

cleardevice(); //清除图形屏幕

setfillstyle(SOLID_FILL,BLUE);//设置填充模式,蓝色实心

bar(0,0,639,479);// 在(0,0)到(639,479)区域绘制蓝色矩形,这是一个总区域

x1=AREAX;

y1=AREAY-BOXW*MAXY;

x2=AREAX+MAXX*BOXW;

y2=AREAY;

rectangle(--x1,--y1,++x2,++y2); //在上述范围绘制一个矩形

setfillstyle(SOLID_FILL,BLACK);

bar(++x1,++y1,--x2,--y2); //在上述区域一个像素绘制一个黑色实心矩形,这是游戏区域

y1=AREAY-MAXY*BOXW; y2=AREAY;

setcolor(DARKGRAY);

for(i=0;iMAXX;i++)//绘制每一格子之间的网格线,深灰色

x1=AREAX+i*BOXW;

line(x1,y1,x1,y2);

x1=AREAX; x2=x1+MAXX*BOXW;

for(j=0;jMAXY;j++)

y1=AREAY-j*BOXW;

line(x1,y1,x2,y1);

for(j=0;jMAXY;j++) //将所有方格都清0,即初始的游戏区域是空的

for(i=0;iMAXX;i++)

area[j][i]=oldarea[j][i]=0; //全部清空

actX=0; actY=0; actW=MAXX-1; actH=MAXY-1;

draw();

MESSAGE=mGEN; //消息,产生一个方块

int genBox() //动作函数,产生一个方块

int i,j,boxidx;

boxidx=random(7); FORCOLOR=random(7)+1; //随机数

for(j=0;j4;j++)

for(i=0;i4;i++)

box[j][i]=BOX[boxidx][j][i];//从模板中生成一个方块

curW=getW(); curH=getH();//获得当前这个方块的宽度和高度

curX=(MAXX+curW)/2;//方块当前的X位置,开始总是从中间落下

if(curX+curW=MAXX)curX=MAXX-1-curW;//如果当前方块的宽度+方块的位置大于最大值,调整位置。我认为这种情况是不会发生的,唯一的可能是直棍。

curY=MAXY-1-curH; //当前块Y位置,开始总是从最上端落下

newX=curX; newY=curY; actX=curX;actY=curY;

actW=newW=curW; actH=newH=curH;

active=1;//游戏actice

if(collision(box)) return 0;//如果方块一下来发生碰撞,返回0,游戏结束

putNewBox();//重构游戏区域

draw(); MESSAGE=0; //绘图,清空消息

return 1;//产生成功,返回1

void lineFull()//每次有方块落下后,都对方块那几行进行判断

int row,col, rowEnd,full,i,j;

rowEnd=newY+newH; //计算方块落在哪几行

if(rowEnd=MAXY-1) rowEnd=MAXY-2;

for(row=newY; row=rowEnd;) //仅判断方块所落的那几行是否需要消行

full=1;

for(col=0;colMAXX;col++) //从0到MAXX

if(!area[row][col]){full=0; break;} //如果区域内不全是1,即这一行不满,跳出for(col=0;colMAXX;col++)循环

if(!full){++row; continue;} //如果不满,行号+1,回到for(row=newY; row=rowEnd;)继续

for(j=row; jMAXY-1;j++) //如果full=1,有一行满c俄罗斯方块源码思路了,消行,从row行开始一直到MAXY-1行

for(i=0;iMAXX;i++) //逐一将上一行的信息复制到下一行

area[j][i]=area[j+1][i];

actX=0;actY=row; actW=MAXX-1; actH=MAXY-1-row;

draw(); rowEnd--;

MESSAGE=mGEN; //方块落下,自动产生一个方块生成的消息dispatchMessage() 接到这一消息会在上端产生一个新方块

void draw() //绘制游戏区域

int row,col,x1,y1,x2,y2;

for(row=actY;row=actY+actH;row++)

for(col=actX;col=actX+actW;col++)

if(area[row][col]!=oldarea[row][col])

if(area[row][col]==0)

setfillstyle(SOLID_FILL,BACKCOLOR);

else

setfillstyle(SOLID_FILL,FORCOLOR);

x1=AREAX+col*BOXW; x2=x1+BOXW;

y1=AREAY-(row+1)*BOXW; y2=y1+BOXW;

bar(++x1,++y1,--x2,--y2);

oldarea[row][col]=area[row][col];

MESSAGE=0;

int moveLeft() //向左移动

newX=curX-1; clearOldBox(); //X位置-1

if(collision(box)) //判断是否碰撞

newX=curX; //如果碰撞,不能左移,X位置不变

putNewBox(); //产生新的游戏区域

MESSAGE=0;

return 0;

putNewBox(); //未碰撞,产生新的游戏区域

actW=curW+1; actX=curX=newX;

MESSAGE=mDRAW; //产生绘制消息

return 1;

int moveRight() //向右移动 同上

newX=curX+1; clearOldBox();

if(collision(box))

newX=curX;

putNewBox();

MESSAGE=0;

return 0;

putNewBox();

actW=curW+1; actX=curX; curX=newX;

MESSAGE=mDRAW;

return 1;

int moveDown() //向下移动 同上

int i,j;

newY=curY-1;

clearOldBox();

if(collision(box)) //判断是否发生碰撞,即是否落到底部

newY=curY;

putNewBox();

active=0; //由于已经落到c俄罗斯方块源码思路了底部,因此active要停住,falldown函数就会停,不再计时了

MESSAGE=mLINE; //发出LINE消息,看是否需要清除一行

return 0;

putNewBox(); //未发生碰撞,就重构游戏区域

actH=curH+1; actY=newY; curY=newY;

MESSAGE=mDRAW;

return 1;

int rotate() //方块旋转

int newBox[4][4];

int i,j;

clearOldBox(); //清除旧的游戏区域的信息

for(j=0;j4;j++)

for(i=0;i4;i++)

newBox[j][i]=0; //新方块信息清零

for(j=0;j4;j++)//按旋转将box数组填入对应的newbox数组

for(i=0;i4;i++)

newBox[curW-i][j]=box[j][i];

newW=curH; newH=curW;

if(collisionRotate(newBox)) //判断旋转是否发生了碰撞

newW=curW; newH=curH; newX=curX; newY=curY;

putNewBox();

MESSAGE=0;

return 0;

for(j=0;j4;j++) //重构方块旋转后游戏区域的信息

for(i=0;i4;i++)

box[j][i]=newBox[j][i];

putNewBox();

actH=newHcurH? newH:curH;

actW=curX+actH-newX;

actX=newX; actY=newY; curX=newX;

curY=newY; curW=newW; curH=newH;

MESSAGE=mDRAW;

return 1;

int getW() //获得一个方块的宽度

int i,j;

for(i=3;i0;i--)

for(j=0;j4;j++)

if(box[j][i]) return i;

return 0;

int getH() //获得一个方块的高度

int i,j;

for(j=3;j0;j--)

for(i=0;i4;i++)

if(box[j][i]) return j;

return 0;

void clearOldBox() //清除旧的游戏区域的信息

int i,j;

for(j=0;j=curH; j++)

for(i=0;i=curW; i++)

if(box[j][i])

area[curY+j][curX+i]=0;//将area数组中原方块位置信息清0

void putNewBox() //重构新游戏区域的信息

int i,j;

for(j=0;j=newH;j++)

for(i=0;i=newW;i++)

if(box[j][i]) //将area数组中填入新的方块位置的位置

area[newY+j][newX+i]=FORCOLOR;

int collision(int cbox[][4]) //方块碰撞

int i,j;

if(newX0) return 1; //遇到左右边界,碰撞

if(newX+newW=MAXX) return 1;

if(newY0) return 1; //上界?

for(j=0;j=newH;j++) //双循环逐一判断

for(i=0;i=newW;i++)

if(area[newY+j][newX+i]cbox[j][i]) return 1; //方块的新(X,Y)位置到新(X+方块长,Y+方块宽)和方块自身进行与操作,如果存在1,就是碰撞

return 0; //否则就无碰撞

int collisionRotate(int cbox[][4]) //旋转方块时碰撞

int i,j;

if(newX+newW=MAXX) newX=MAXX-1-newW;

if(newY+newH=MAXY) newY=MAXY-1-newH;

if(collision(cbox)) return 1;

for(i=0;i=newW;i++)

for(j=0;j=newH;j++)

if(area[newY+j][newX+i])

newX-=newW-i+1; goto L;

L: return collision(cbox);

int gameOver()

if(!active (curY+curHMAXY-3)) return 1; //如果大于当前Y坐标+当前高度最大Y坐标-3,游戏结束

else return 0;

求C语言俄罗斯方块代码

俄罗斯方块C源代码

#include stdio.h

#include windows.h

#include conio.h

#include time.h

#define  ZL  4     //坐标增量, 不使游戏窗口靠边

#define WID  36    //游戏窗口的宽度

#define HEI  20    //游戏窗口的高度

int i,j,Ta,Tb,Tc;      // Ta,Tb,Tc用于记住和转换方块变量的值

int a[60][60]={0};    //标记游戏屏幕各坐标点:0,1,2分别为空、方块、边框

int b[4];        //标记4个"口"方块:1有c俄罗斯方块源码思路,0无c俄罗斯方块源码思路,类似开关

int x,y, level,score,speed;    //方块中心位置的x,y坐标c俄罗斯方块源码思路,游戏等级、得分和游戏速度

int flag,next;   //当前要操作的方块类型序号,下一个方块类型序号

void gtxy(int m, int n);   //以下声明要用到的自编函数

void gflag( );  //获得下一方块序号

void csh( );  //初始化界面

void start( );  //开始部分

void prfk ( );  //打印方块

void clfk( );  //清除方块

void mkfk( );  //制作方块

void keyD( );  //按键操作

int  ifmov( );  //判断方块能否移动或变体

void clHA( );  //清除满行的方块

void clNEXT( );  //清除边框外的NEXT方块

int main( )

{ csh( );

while(1)

   {start( );  //开始部分

     while(1)

     { prfk( );  

         Sleep(speed);  //延时

        clfk( );

        Tb=x;Tc=flag;  //临存当前x坐标和序号,以备撤销操作

        keyD( );  

          y++;     //方块向下移动

       if (ifmov( )==0) { y--; prfk( ); dlHA( ); break;} //不可动放下,删行,跨出循环

    for(i=y-2;iy+2;i++){ if (i==ZL) { j=0; } }  //方块触到框顶

   if (j==0) { system("cls");gtxy(10,10);printf("游戏结束!"); getch(); break; }

   clNEXT( );   //清除框外的NEXT方块

return 0;

void gtxy(int m, int n)  //控制光标移动

{COORD pos;  //定义变量

pos.X = m;  //横坐标

pos.Y = n;   //纵坐标

SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);

void csh( )    //初始化界面

{gtxy(ZL+WID/2-5,ZL-2); printf("俄罗斯方块");      //打印游戏名称

gtxy(ZL+WID+3,ZL+7); printf("******* NEXT:");  //打印菜单信息

gtxy(ZL+WID+3,ZL+13); printf("**********");

gtxy(ZL+WID+3,ZL+15); printf("Esc :退出游戏");

gtxy(ZL+WID+3,ZL+17); printf("↑键:变体");

gtxy(ZL+WID+3,ZL+19); printf("空格:暂停游戏");

gtxy(ZL,ZL);  printf("╔");  gtxy(ZL+WID-2,ZL);  printf("╗");  //打印框角

gtxy(ZL,ZL+HEI);  printf("╚");  gtxy(ZL+WID-2,ZL+HEI);  printf("╝");

a[ZL][ZL+HEI]=2;  a[ZL+WID-2][ZL+HEI]=2;  //记住有图案

for(i=2;iWID-2;i+=2) {gtxy(ZL+i,ZL);  printf("═"); }  //打印上横框

for(i=2;iWID-2;i+=2) {gtxy(ZL+i,ZL+HEI); printf("═"); a[ZL+i][ZL+HEI]=2; } //下框

for(i=1;iHEI;i++) { gtxy(ZL,ZL+i);  printf("║"); a[ZL][ZL+i]=2; }  //左竖框记住有图案

for(i=1;iHEI;i++) {gtxy(ZL+WID-2,ZL+i); printf("║"); a[ZL+WID-2][ZL+i]=2; } //右框

CONSOLE_CURSOR_INFO cursor_info={1,0};   //以下是隐藏光标的设置

SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),cursor_info);

level=1; score=0; speed=400;

gflag( );  flag=next;  //获得一个当前方块序号

void gflag( )   //获得下一个方块的序号

{ srand((unsigned)time(NULL)); next = rand()%19+1; }

void start( )  //开始部分

{ gflag( ); Ta=flag; flag=next;  //保存当前方块序号,将下一方块序号临时操作

x=ZL+WID+6; y=ZL+10; prfk( );  //给x,y赋值,在框外打印出下一方块

flag=Ta; x=ZL+WID/2; y=ZL-1;  //取回当前方块序号,并给x,y赋值

void prfk ( )  //打印俄罗斯方块

{ for(i=0;i4;i++) {b[i]=1; }  //数组b[4]每个元素的值都为1

mkfk ( );  //制作俄罗斯方块

for( i= x-2; i=x+4; i+=2 )  //打印方块

{ for(j=y-2;j= y+1;j++) { if( a[i][j]==1  jZL ){ gtxy(i,j); printf("□"); } } }

gtxy(ZL+WID+3,ZL+1);   printf("level : %d",level);  //以下打印菜单信息

gtxy(ZL+WID+3,ZL+3);  printf("score : %d",score);

gtxy(ZL+WID+3,ZL+5);  printf("speed : %d",speed);

void clfk( )  //清除俄罗斯方块

{ for(i=0;i4;i++) { b[i]=0; }  //数组b[4]每个元素的值都为0

mkfk ( );  //制作俄罗斯方块

for( i=x-2; i=x+4; i+=2 )  //清除方块

{ for(j=y-2;j=y+1;j++){ if( a[i][j]==0  jZL ){ gtxy(i,j); printf("  "); } } }

void mkfk( )  //制作俄罗斯方块

{ a[x][ y]=b[0];  //方块中心位置状态: 1-有,0-无

switch(flag)   //共6大类,19种小类型

{ case 1: { a[x][y-1]=b[1]; a[x+2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //田字方块

case 2: { a[x-2][y]=b[1]; a[x+2][y]=b[2]; a[x+4][y]=b[3]; break; }  //直线方块:----

case 3: { a[x][y-1]=b[1]; a[x][y-2]=b[2]; a[x][y+1]=b[3]; break; }  //直线方块: |

case 4: { a[x-2][y]=b[1]; a[x+2][y]=b[2]; a[x][y+1]=b[3]; break; }  //T字方块

case 5: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x-2][y]=b[3]; break; }  //T字顺时针转90度

case 6: { a[x][y-1]=b[1]; a[x-2][y]=b[2]; a[x+2][y]=b[3]; break; }  //T字顺转180度

case 7: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x+2][y]=b[3]; break; }  //T字顺转270度

case 8: { a[x][y+1]=b[1]; a[x-2][y]=b[2]; a[x+2][y+1]=b[3]; break; } //Z字方块

case 9: { a[x][y-1]=b[1]; a[x-2][y]=b[2]; a[x-2][y+1]=b[3]; break; }  //Z字顺转90度

case 10: { a[x][y-1]=b[1]; a[x-2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //Z字顺转180度

case 11: { a[x][y+1]=b[1]; a[x+2][y-1]=b[2]; a[x+2][ y]=b[3]; break; } //Z字顺转270度

case 12: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x-2][y-1]=b[3]; break; }  //7字方块

case 13: {a[x-2][y]=b[1]; a[x+2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //7字顺转90度

case 14: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x+2][y+1]=b[3]; break; }  //7字顺转180度

case 15: { a[x-2][y]=b[1]; a[x-2][y+1]=b[2]; a[x+2][y]=b[3]; break; }  //7字顺转270度

case 16: { a[x][y+1]=b[1]; a[x][y-1]=b[2]; a[x+2][y-1]=b[3]; break; }  //倒7字方块

case 17: { a[x-2][y]=b[1]; a[x+2][y+1]=b[2]; a[x+2][y]=b[3]; break; }  //倒7字顺转90度

case 18: { a[x][y-1]=b[1]; a[x][y+1]=b[2]; a[x-2][y+1]=b[3]; break; }  //倒7字顺转180度

case 19: { a[x-2][y]=b[1]; a[x-2][y-1]=b[2]; a[x+2][y]=b[3]; break; }  //倒7字顺转270度

void keyD( )  //按键操作

{ if (kbhit( ))

{ int key;

   key=getch();

if (key==224)

{ key=getch();

       if (key==75) { x-=2; }  //按下左方向键,中心横坐标减2

if (key==77) { x+=2; }  //按下右方向键,中心横坐标加2

      if (key==72)     //按下向上方向键,方块变体

{ if (flag=2  flag=3 ) { flag++; flag%=2; flag+=2; }

if ( flag=4  flag=7 ) { flag++; flag%=4; flag+=4; }

if (flag=8  flag=11 ) { flag++; flag%=4; flag+=8; }

if (flag=12  flag=15 ) { flag++; flag%=4; flag+=12; }

if ( flag=16  flag=19 ) { flag++; flag%=4; flag+=16; } }

    if (key==32)     //按空格键,暂停

{ prfk( ); while(1) { if (getch( )==32) { clfk( );break;} } }  //再按空格键,继续游戏

    if (ifmov( )==0) { x=Tb; flag=Tc; }  //如果不可动,撤销上面操作

    else { prfk( ); Sleep(speed); clfk( ); Tb=x;Tc=flag;}   //如果可动,执行操作

int ifmov( )   //判断能否移动

{ if (a[x][y]!=0) { return 0; }  //方块中心处有图案返回0,不可移动

else{ if ( (flag==1  ( a[x][ y-1]==0  a[x+2][y-1]==0  a[x+2][y]==0 ) ) ||

       (flag==2  ( a[x-2][y]==0  a[x+2][y]==0  a[x+4][y]==0 ) ) ||

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

     (flag==19 ( a[x-2][y]==0 a[x-2][y-1]==0

             a[x+2][y]==0 ) ) ) { return 1; }

return 0;   //其它情况返回0

void clNEXT( )   //清除框外的NEXT方块

{ flag = next;  x=ZL+WID+6;  y=ZL+10;  clfk( ); }

void clHA( )   //清除满行的方块

{ int k, Hang=0;    //k是某行方块个数, Hang是删除的方块行数

for(j=ZL+HEI-1;j=ZL+1;j--)  //当某行有WID/2-2个方块时,则为满行

{ k=0; for(i=ZL+2;iZL+WID-2;i+=2)

{ if (a[i][j]==1)   //竖坐标从下往上,横坐标由左至右依次判断是否满行

{ k++;   //下面将操作删除行

     if (k==WID/2-2)  {   for(k=ZL+2;kZL+WID-2;k+=2)

         { a[k][j]=0; gtxy(k,j); printf("  "); Sleep(1); }

        for(k=j-1;kZL;k--)

        { for(i=ZL+2;iZL+WID-2;i+=2)  //已删行数上面有方块,先清除再全部下移一行

          { if(a[i][k]==1) { a[i][k]=0; gtxy(i,k); printf("  ");a[i][k+1]=1;

            gtxy(i,k+1); printf("□"); } }

        j++;     //方块下移后,重新判断删除行是否满行

        Hang++;  //记录删除方块的行数

score+=100*Hang;   //每删除一行,得100分

if ( Hang0  (score%500==0 || score/500 level-1 ) )  //得分满500速度加快升一级

  { speed-=20; level++; if(speed200)speed+=20; }

  c俄罗斯方块源码思路 


评论


最新评论