俄罗斯方块全功能简化版

来源:互联网 发布:淘宝网是阿里巴巴的吗 编辑:程序博客网 时间:2024/05/17 01:00

初写博客,格式全不知,探索中——

高手请多指教,新手请多交流。

俄罗斯方块,核心代码源于网络,增加了关卡,分数,最高分数记录等功能。

界面如下图:


核心代码是通过一个三维数组,

int block[7][4][2]
{
    1,1, 1,2, 1,3, 1,4,
    1,1, 1,2, 1,3, 2,3,
    2,1, 2,2, 1,3, 2,3,
    1,1, 1,2, 2,2, 2,3,
    2,1, 2,2, 1,3, 2,3,
    1,1, 2,1, 1,2, 2,2,
    1,1, 1,2, 1,3, 2,2
};

实现七种方块的拼合与旋转。

 

主函数代码:

/********************************
名称:俄罗斯方块
描述:用控制台程序实现俄罗斯方块小游戏 控制台字符小游戏
编译:CodeBlock16.01  vs2010
创建:零千刻
日期:170515
*********************************/


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


#define TIMEPAU 350//时间间隔timepause
#define REGIONH 25//区域高
#define REGIONW 15//区域宽


//七拼块形状数据
int block[7][4][2]
{
    1,1, 1,2, 1,3, 1,4,
    1,1, 1,2, 1,3, 2,3,
    2,1, 2,2, 1,3, 2,3,
    1,1, 1,2, 2,2, 2,3,
    2,1, 2,2, 1,3, 2,3,
    1,1, 2,1, 1,2, 2,2,
    1,1, 1,2, 1,3, 2,2
};
//拼块坐标
int blockx[4],blocky[4];
//区域数组
int region[REGIONW+1][REGIONH+3]= {};
bool intoloop=false;
int numBk=0;
int bkScorce=0;
void SetCP(short x,short y);
void DrawBlock();
void ClearBlock();
void init();
void ConsoleSize(short x,short y);
void HideCursor ();
int DropBk();
int MoveBk(int m);
void RotateBk();
char key(int Tp);
int BlockCount(int h);
void BlockClearLine(int h);
void checkBk();
void ReStart();
void level();
void FileSave();
/*主程序模块*/
int main()
{
    int i,s;
    int m,n;
    char chBk;
    system("color 0a");
    ConsoleSize(50,33);
    HideCursor();
    init();
    //bool mark1=true;
    //bool mark2=true;
    FileSave();
    while(true)
    {
        char ch= getch();
        //if(ch==13&&mark1){intoloop=true;/*enter键值为13*/mark1=false;}
        //else if(ch==13&&!mark1&&!mark2){ReStart();}/*enter键值为13,分清赋值=与等值==*/
        if(ch==13)intoloop=true;
        if(ch=='=')ReStart();
        //srand((int)time(0));
        while(intoloop)
        {
            m=rand()%7;//rand()产生一个随机数,然后对7取余,再进行运算
            for(i=0; i<4; i++)
            {
                blockx[i]=block[m][i][0]+(REGIONW-3)/2;//取组合方块的四个坐标
                blocky[i]=block[m][i][1];
            }
            for(i=0; i<4; i++) /* 检查拼块是否能放入区域中,不能放则退出游戏*/
                if (region[blockx[i]][blocky[i]]==1)
                {
                    intoloop=false;
                    FileSave();
                    break;
                }
            DrawBlock();
            s=0;// s标志是否按了S,循环初始化的位置很重要!
            for(;;)
            {


                /* 此循环中处理一个拼块的下落过程*/
                if(s==0) chBk=key(TIMEPAU);
                else chBk=key(30);
                if((chBk>='a')&&(chBk<='z')) chBk=chBk-32; //将小写字母转换为大写
                /* 根据按键作相应处理*/
                switch (chBk)
                {
                case 'S':
                    s=1;
                    break;
                case 'W':
                    RotateBk();
                    break;
                case 'A':
                    MoveBk(-1);
                    break;
                case 'D':
                    MoveBk(1);
                    break;
                case ' ':
                    while(kbhit()==0);
                    break;//按了空格键后等待热键输入
                //case 'E': exit(0); break; /* E,结束游戏,测试用*/
                case '=':
                    intoloop=false;
                    break; /*重新开始*/
                default :
                    n=DropBk(); /* 没按上面的键,或未按任何键,拼块下落一格*/
                }
                if(n==0) break; /* 拼块落到区域底部或不能再下落退出循环*/
            }
            checkBk();
        }
    }
    return 0;
}

 主要功能函数:


//拼块下落一行
int DropBk()
{
    int d,i;
    d=1;
    ClearBlock();
    for(i=0; i<4; i++)
    {
        if(blocky[i]==REGIONH)
        {
            d=0;
            break;
        };
        if(region[blockx[i]][blocky[i]+1]==1)
        {
            d=0;
            break;
        };
    }
    if(d==1&&intoloop==true)
        for(i=0; i<4; i++)
            blocky[i]=blocky[i]+1;
    else
        for(i=0; i<4; i++)
            region[blockx[i]][blocky[i]]=1;//方块占位记号 1为有,0为无
    DrawBlock();
    return d;
}

//拼块移动
int MoveBk(int m)
{
    int i,j;
    ClearBlock();
    i=0;
    j=1;
    do
    {
        if((blockx[i]==1)&&(m==-1))
        {
            j=0;
            break;
        };
        if((blockx[i]==REGIONW)&&(m==1))
        {
            j=0;
            break;
        };
        if (region[blockx[i]+m][blocky[i]]==1)
        {
            j=0;
            break;
        };
        i++;
    }
    while (i<4);
    if(j==1)
        for(i=0; i<4; i++)blockx[i]=blockx[i]+m;
    DrawBlock();
}

//拼块旋转
void RotateBk()
{
    int i,j,x,y;
    int bkx[4],bky[4];
    ClearBlock();
    x=blockx[1];
    y=blocky[1];
    for(i=0; i<4; i++)
    {
        bkx[i]=x+y-blocky[i];
        bky[i]=y-x+blockx[i];
    }
    j=1;
    for(i=0; i<4; i++)
    {
        if((bkx[i]<1)||(bkx[i]>REGIONW)||(bky[i]<1)||(bky[i]>REGIONH))
        {
            j=0;
            break;
        };
        if (region[bkx[i]][bky[i]]==1)
        {
            j=0;
            break;
        };
    }
    if(j==1)
        for(i=0; i<4; i++)
        {
            blockx[i]=bkx[i];
            blocky[i]=bky[i];
        };
    DrawBlock();
}
/* 计算一行中的方块数*/
int BlockCount(int h)
{
    int i,p=0;
    for(i=1; i<=REGIONW; i++)
        p=p+region[i][h];
    if(p==REGIONW)
        Sleep(TIMEPAU); /* 这个函数首字母大写,是Windows中的API函数,不是C中的 */
    return p;
}
/* 区域中方块除去一行,行上面的方块下移一行*/
void BlockClearLine(int h)
{
    int k,j,q;
    for(k=h; k>0; k--)
    {
        q=0;
        for(j=1; j<=REGIONW; j++)
        {
            if(region[j][k]!=region[j][k-1])
            {
                if(region[j][k-1])
                {
                    char bk[3];
                    strcpy(bk,"□");//把从src地址开始且含有\0  NULL结束符的字符串复制到以dest开始的地址空间
                    SetCP(j*2,k+2);
                    puts(bk);
                }
                else
                {
                    char bk[3];
                    strcpy(bk," ");//把从src地址开始且含有\0  NULL结束符的字符串复制到以dest开始的地址空间
                    SetCP(j*2,k+2);
                    puts(bk);
                }
                region[j][k]=region[j][k-1];
            }
            q=q+region[j][k];
        }
        if(q==0) break;
    }
}
/* 检查有无完成的行,并处理之*/
void checkBk()
{
    int i,n;
    i=REGIONH;
    do
    {
        n=BlockCount(i);
        if(n==REGIONW)
        {
            BlockClearLine(i);
            numBk+=15;
            level();
        }
        else i--;
    }
    while((i>0)&&(n>0));
}
char key(int Tp)//等待按键并延时
{
    clock_t t1,t2;
    char chp;
    t1=clock();
    do
        t2=clock();
    while (((t2-t1)<Tp) && !kbhit());
    if (kbhit())
    {
        Sleep(20);    //延时为重画
        chp=getch();
    }
    else chp=0;
    return chp;
}

更多内容参见资源:

http://download.csdn.net/detail/qq_38329891/9863966