基于DOS的简易俄罗斯方块制作

2020-12-07 17:54:29 浏览数 (1)

参考链接: Java中的静态块static block

制作一个简易的俄罗斯方块,未调用graphics库(装了半天不成功),完全的黑框操作 基本思路: 1.利二维数组表示地图(也可以利用一维数组,此处利用的是一维数组) 0.表示没有方格,1.表示正在下落的方格 2.表示墙壁 2.共有七种俄罗斯方块,但是有19种状态 (绘制方块处,总共有7种俄罗斯方块,旋转之后可以形成19种方块) 3.每个方块需设置一个中心方块 ,尽量与其他的方块有联系。中心方块用B[0]表示,其他的方块由1,2,3表示 

必要的几个实用的函数 1.定位光标函数 

 #include <stdio.h>

#include <windows.h> 

#include <conio.h>

#include <time.h>

using namespace std;

//设置文字的显示位置  方法一:空格  t   n

//可以利用坐标  x axis y axis

//控制文字显示位置

void gotoxy(int x,int y)

{

    COORD pos;//COORD结构体 

    pos.X=x;

    pos.Y=y;

    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos);    

 } 

int main()

{

    gotoxy(30,10);//横坐标30,纵坐标10 

    printf("this is a test");

    return 0; 

2.颜色调用函数 

 #include <stdio.h>

#include<windows.h> 

#include <conio.h>

#include<time.h>

using namespace std;

//HANDLE hOut;//控制台的句柄 

//color

int color(int c)

{

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);

    //只能用在windows系统,且不能改变控制台的颜色 

    return 0;

}

int main()

{

    color(14);//0-15号色 ,超过15之后就是改变文本的背景色 

 //    14号黄色 13号粉色  10号绿色 15白色 6棕色 12红色 11 亮蓝色 2绿色 

    printf("this is a testn"); //改变了一次之后下面所有的文字都是此种颜色

                        //要每种颜色则只需要在每个字体前加上相应的颜色代码即可 

return 0;    

}

3._getch()函数 用于读入按键进行操作 4.函数名:kbhit() //功能及返回值: 检查当前是否有键盘输入,若有则返回一个非0值,否则返回0。 

完整的程序: 

#include <stdio.h>

#include<windows.h> 

#include <conio.h>

#include<time.h>

using namespace std;

int map[250];//地图数组

int nextblock[2];//下一个方块

int endgame;//游戏结束标志 1为游戏进行中,0为游戏失败

int xblock[2];//记录行进中方块形状和位置,xblock[0]记录形状,0为I型,1为其他型,2为O型   xblock[1]为位置 

int score;//计分

int speed=20000;//当前速度 

//7种俄罗斯方块 

int blockI[4] = { 1,1,1,1};//I型方块           xblock[0]   =   0

int blockO[9] = { 0,0,0,0,1,1,0,1,1 };//O型方块                2

int blockT[9] = { 0,0,0,1,1,1,0,1,0 };//T型方块                1

int blockL[9] = { 0,1,0,0,1,0,0,1,1 };//L型方块                1

int blockS[9] = { 0,0,0,0,1,1,1,1,0};//S型方块                 1

int blockZ[9] = { 0,0,0,1,1,0,0,1,1};//Z型方块                 1

int blockJ[9] = { 0,1,0,0,1,0,1,1,0 };//J型方块                1

int color(int c);//颜色

void init();//初始化数据

void gotoxy(int x, int y);//将光标移动到指定位置

void drawborder();//绘制边框

void drawmap();//绘制地图

int  ranblock();//方块生成

void drawblock(int block[9]);//绘制方块

void drawnextblock(int x);//绘制下一个方块

void drawmapblock(int block[9]);//向地图上绘制方块

void downblock();//方块下落

void run();//核心逻辑

void heart();//画心形

void welcom();//欢迎界面 

void title();//

void regulation();

void me();

void regulation()

{

    color(13);

    printf("1,上键旋转方块n");

    printf("2,0分:废铁 n100分:青铜 n500分:白银 n1000分:黄金 n依次500分递增,最高王者n");

    printf("3,空格键暂停,回车键继续游戏");

}

void me()

{

    color(13);

printf("t*****************************************************");    

printf("ttttt t                                        .----.      n");

printf("  tt                                            _.'__    `.    n  ");

printf("  tt                                        .--(#)(##)---/#\    n");

printf("  tt                                      .' @          /###\    n");

printf("tt1 ------------------略略略略略略      :        ,  #####      n");

printf("tt* ------------------★★★★★★        `-..__.-' _.-\###/    n"); 

printf("tt2 ------------------略略略略略略            `;_:    `"'    n ");

printf("tt* ------------------★★★★★★          .'"""""`.    n");

printf("tt3 ------------------略略略略略略          /,  Main ,\      n");

printf("tt* ------------------★★★★★★          //  Menu  \\    n");

printf("tt4 ------------------略略略略略略        `-._______.-'    n");

printf("tt* ------------------★★★★★★        _ __`. | .'___    n");

printf("tt0 ------------------略略略略略略        (______|______)    n");   

 } 

void heart()

{

    //打印心形 

    color(13);

        int i = 0, j = 0;

    int a = 3;

    char c = 3;//心形的ASCII代码是3

    for (i = 0; i < 3;i )//行数  3行

    {

        gotoxy(10,9 i); 

        for (j = 0; j < 5- 2*i;j )//空格, 5,3,1个空格

        {

            printf(" ");

        }

        for (j = 0; j < 5 4 * i;j )//打印符号

        {

            printf("%c", c);

        }

        for (j = 0; j < 9- 4 * i;j )//打印空格

        {

            printf(" ");

        }

        for (j = 0; j < 5 4 * i;j )//打印符号

        {

            printf("%c", c);

        }

        printf("n");

    }

    for (i = 0; i < 3; i )//打印行数3行

    {  gotoxy(10,12 i);

        for (j = 0; j < 29;j )//打印符号

            printf("%c", c);

        printf("n");//打印空格

    }

    color(12);

    for (i = 0; i < 6 1; i )//    打印6行

    {

         gotoxy(10,15 i);

        for (j = 0; j < 2 * i 1; j )//打印空格

            printf(" ");

        for (j = 0; j < 27-4 * i; j )

            printf("%c", c);

        printf("n");

    }

    for (i = 0; i <1; i )//打印行数1行

    {

        gotoxy(10,22);

        for (j = 0; j < 14; j )//打印空格

            printf(" ");

        for (j = 0; j < 1; j )//打印符号

            printf("%c", c);

        printf("n");

    }

    color(14);

    gotoxy(24,14);

    printf("L");

}

void welcom()

{

    heart(); 

    int n;

    color(6);

    gotoxy(-20,12);

    printf("1.Play game");

    gotoxy(-8,12);

    printf("2.The regulations");

    gotoxy(-20,17);

    printf("3.Exit");

    gotoxy(-8,17);

    printf("4.About me");

    gotoxy(13,25);

    color(4);

    printf("Please enter {1,2,3,4}:[ ]bb");//b退格符

    scanf("%d",&n); 

    switch(n)

    {

        case 1:

            system("cls");//清屏 

            init();

            run();

            break;

        case 2:

            system("cls");//清屏 

            regulation();

            getchar();

            getchar();

            system("cls");//清屏 

            title();

            welcom();

            break;

        case 3:

            exit(0);

            break;

        case 4:

            system("cls");//清屏 

            me();

            getchar();

            getchar();

            system("cls");//清屏 

            title();

            welcom();

            break;

    }

}

void title()

{

    color(14);

    gotoxy(12,3);    

    printf("JELLY 的 俄 罗 斯 方 块");// 若是显示不成功,则看编译的位数,

                                      //若电脑是32位,则上面编译要用32位编译

    color(11);

    gotoxy(6,5);

    printf("■"); //汉字在x横轴上占用两个位置 ,y轴上占用一个位置

    gotoxy(6,6);

    printf("■■");

    gotoxy(6,7);

    printf("■"); 

    color(14);

    gotoxy(14,6);

    printf("■■"); //汉字在x横轴上占用两个位置 ,y轴上占用一个位置

    gotoxy(14,7);

    printf("■■"); 

    color(10);

    gotoxy(24,6);

    printf("■■");

    gotoxy(24,7);

    printf("■■");

    color(13);

    gotoxy(33,5);

    printf("■"); 

    gotoxy(33,6);

    printf("■"); 

    gotoxy(33,7);

    printf("■"); 

    gotoxy(33,8);

    printf("■"); 

    color(12);

    gotoxy(45,6);

    printf("■");

    gotoxy(41,7);

    printf("■■■");

    printf("nn"); 

}

 int color(int c)

{

    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);

    //只能用在windows系统,且不能改变控制台的颜色 

    return 0;

}

//将光标移动到指定位置

void gotoxy(int x,int y)

{

    COORD c;

    c.X = x 23 ;

    c.Y = y 2;

    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);

    SetConsoleCursorPosition(handle, c);

    CONSOLE_CURSOR_INFO CursorInfo;

    //获取控制台光标信息

    GetConsoleCursorInfo(handle, &CursorInfo);

    //隐藏控制台光标,设置控制台光标状态

    CursorInfo.bVisible = false;

    SetConsoleCursorInfo(handle, &CursorInfo);

}

//初始化数据

void init()

{

    //map数组初始化赋值,0-239赋值为0,240-249赋值为2

    for (int i = 0; i < 240; i )    

        map[i] = 0;

    for (int i = 240; i < 250; i )

        map[i] = 2;

    endgame = 1;

    nextblock[0] = 0;// 

    nextblock[1] = ranblock();///

    xblock[0] = 0;//故开始第一个必为I型 

    xblock[1] = 24;// 

    score = 0;

    drawborder();

}

//绘制边框

void drawborder()

{

    //绘制地图边框

    color(12);

    gotoxy(-2,-1);

    printf("┏");

    gotoxy(20,-1);

    printf("┓");

    gotoxy(-2,20);

    printf("┗");

    gotoxy(20,20);

    printf("┛");

    for (int i = 0; i < 20; i =2)

    {

        gotoxy(i, -1);

        printf("━");

        gotoxy(i, 20);

        printf("━");

    } 

    for (int i = -1; i < 21; i )

    {

        if (i < 19) {

            gotoxy(-2, i 1);

            //全角竖线

            printf("┃");

            gotoxy(20, i 1);

            printf("┃");

        }

    }

    //绘制预览方块边框

    for (int i = 0; i < 10; i )

    {

        gotoxy(i 30, 2);

        printf("-");

        }

    for (int i = 0; i < 10; i )

    {

        gotoxy(i 30, 7);

        printf("-");

//        if (i < 4)

//        {

//            gotoxy(29,i 2);

//            printf("丨");

//            gotoxy(39, i 2);

//            printf("丨");

//        }

    }

//    color(12);

//    gotoxy(25, 1);

//    printf("下一个方块:");

//    gotoxy(25, 19);

//    printf("制作者:jelly");

//    gotoxy(25,15);

//    printf("当前等级:") ;

}

//随机方块生成

int ranblock() {

    int x;

    srand((int)time(0));

    x = rand() % 7;

    return x;

}

//绘制地图

void drawmap()

{

    for(int i=1;i<=15;i )

    {

    color(i);

    gotoxy(-10,1);

    printf("俄"); 

    gotoxy(-10,3);

    printf("罗"); 

    gotoxy(-10,5);

    printf("斯"); 

    gotoxy(-10,7);

    printf("方"); 

    gotoxy(-10,9);

    printf("块"); 

    }

    color(12);

    gotoxy(25, 1);

    printf("下一个方块:");

    gotoxy(25, 19);

    printf("制作者:jelly");

    gotoxy(25,15);

    printf("当前等级:") ;

//    gotoxy(25, 14);

//    printf("                   ");

    gotoxy(25, 14);

    printf("游戏得分: %d",score);

    gotoxy(25,13);

    printf("当前速度: %d",(21000-speed)/1000);

    for (int i = 40; i < 240; i )

    {

        gotoxy(i*2, i/10 - 4);

        //map数组中0为空

        if (map[i] == 0)

            printf(" ");

        //1为移动中方块

        if (map[i]== 1)

            printf("■");

        //2为停止的方块

        if (map[i] == 2) 

            printf("■");

    }

    gotoxy(35,15);

    if(score==0) printf("废铁");

}

//绘制下一个方块

void drawnextblock(int x) 

{//下一个方块显示 区域清空,中文图形占用两个字节 

    for (int i = 0; i < 4; i )

    {

        gotoxy(i * 2 31, 2);

        printf(" ");

        gotoxy(i * 2 31, 3);

        printf(" ");

        gotoxy(i * 2 31, 4);

        printf(" ");

        gotoxy(i * 2 31, 5);

        printf(" ");

    }

    switch (x)//随机数x进行选择 

    {

    case 0:

        color(8);

        gotoxy(31, 4);

        printf("■");

        gotoxy(33, 4);

        printf("■");

        gotoxy(35, 4);

        printf("■");

        gotoxy(37, 4);

        printf("■");

        break;

    case 1://在next框中绘制不同的除了I型之外的方块

        color(14);

        drawblock(blockT);

        break;

    case 2:

        color(11);

        drawblock(blockL);

        break;

    case 3:

        color(13);

        drawblock(blockO);

        break;

    case 4:

        color(2);

        drawblock(blockS);

        break;

    case 5:

        color(6);

        drawblock(blockZ);

        break;

    case 6:

        color(15);

        drawblock(blockJ);

        break;

    }

}

//绘制方块(除了I型的其他方块)

void drawblock(int block[9]) { 

    for (int i = 0; i < 3; i )

    {

        gotoxy(i * 2 31, 3);

        if (block[i] == 0)        

            printf(" ");    

        else

            printf("■");

        gotoxy(i * 2 31, 4);

        if (block[i 3] == 0)

            printf(" ");

        else

            printf("■");

        gotoxy(i * 2 31, 5);

        if (block[i 6] == 0)

            printf(" ");

        else

            printf("■");

    }

}

//方块下落

void downblock()

{

    //碰撞检测标识//touch为1则为未碰撞 

    int touch = 1;

    for (int i = 239; i >= 0; i--)

    {

        if (map[i] == 1 && map[i 10] == 2)

            touch = 0;

    }

    if (touch == 1)

    {

        for (int i = 239; i >= 0; i--)

        {

            if (map[i] == 1)//向下移动,每行10个元素 

            {

                map[i 10] = map[i];

                map[i] = 0;

            }

        }

        xblock[1] = xblock[1] 10;///

    }

    else if (touch == 0)//在碰撞的基础上将1改为2,即也就是将方块改为固定不动的方块 

    {

        for (int i = 0; i < 240; i )

        {

            if (map[i] == 1)

                map[i] = 2;

        }

    }

}

//向地图上绘制方块

void drawmapblock(int block[9])

{

    for (int i = 0; i < 3; i )

    {

        map[i 13] = block[i];

        map[i 23] = block[i 3];

        map[i 33] = block[i 6];

    }

    //记录方块坐标和类型

    xblock[0] = 1;//1为除i和o型其他的形状 

    xblock[1] = 24;//

}

//核心逻辑

void run()

{

    while (endgame)

    {

        //游戏结束

        for (int i=20; i < 30; i )

        {

            if (map[i] == 2||map[i 10]==2)

            {

                gotoxy(8, 7);

                printf("  游戏结束,按任意键退出  ");

                _getch();

                endgame = 0; 

            }

        }

        //方块消除

        for (int i = 0; i < 24; i )

        {

            int sign = 0;

            for (int j = 0; j < 10; j )

            {

                if (map[i * 10 j] == 2)

                    sign ;

            }

            if (sign == 10)//记录每行的2数即固定的不能动的方块 

            {

                for (int j = 0; j < 10; j )

                {

                    map[i * 10 j] = 0;

                }

                for (int z = i*10 9; z >=0; z--)//消除一行后其他的向下移动 

                {

                    if (map[z] == 2)

                    {

                        map[z 10] = 2;

                        map[z] = 0;

                    }

                }

                score=score 100;

                //

            gotoxy(35,15);

             switch(score)

            {

             case 100: printf("青铜");break; 

             case 500: printf("白银");speed=speed-1000;break;

             case 1000:printf("黄金");break;

             case 1500:printf("白金");speed=speed-3000;break;

             case 2000:printf("钻石");break;

             case 2500:printf("大师");speed=speed-5000;break;

              case 3000:printf("王者");break;

            }

                drawmap();

            }

        }

        //新方块生成标识

        int newblock = 1;

        for (int i = 0; i < 240; i )

        {

            if (map[i] == 1)

                newblock = 0;

        }

        //生成新方块

        if (newblock == 1)

        {

            switch (nextblock[0])

            {

            case 0://i型 

                map[23] = 1;

                map[24] = 1;

                map[25] = 1;

                map[26] = 1;

                xblock[0] = 0;

                xblock[1] = 24;

                break;

            case 1:

                color(14);

                drawmapblock(blockT);

                break;

            case 2:

                color(11);

                drawmapblock(blockL);

                break;

            case 3:

                color(13);

                drawmapblock(blockO);//o型 

                xblock[0] = 2;

                break;

            case 4:

                color(2);

                drawmapblock(blockS);

                break;

            case 5:

               color(6);

                drawmapblock(blockZ);

                break;

            case 6:

                color(15);

                drawmapblock(blockJ);

                break;

            }

            nextblock[0] = nextblock[1];

            drawnextblock(nextblock[0]);

            nextblock[1] = ranblock();

        }

        else if (newblock == 0)

        {

            //方向控制,形态变换

            int t = speed,t1=0;

            while (t>0)

            {

                int ch;

                if (t1<10&&_kbhit())//函数名:kbhit()

                                     //功能及返回值: 检查当前是否有键盘输入,若有则返回一个非0值,否则返回0。 

                {

                    //需要调用两次,因为功能键第一次返回0或224

                    ch = _getch();

                    ch = _getch();

                    //按下左键,判断左边是否有已经下落的方块和是否已到达左边界,如果没有将正在下落的方块左移

                    if (ch == 75)//左键 

                    {

                            for (int i = 0; i < 24; i )

                            {

                                if (map[i * 10] == 1)

                                    ch = 0;

                            }

                            if (ch!=0&&xblock[0] == 0&&map[xblock[1] 1]==1)

                            {

                                if (map[xblock[1] - 2] == 2)

                                    ch = 0;

                            }

                            if (ch != 0 && xblock[0] == 0 && map[xblock[1] - 10] == 1)

                            {

                                if (map[xblock[1] - 1] == 2)

                                    ch = 0;

                            }

                            if (ch != 0 && xblock[0] != 0)

                            {

                                for (int i = xblock[1] - 11; i < xblock[1] - 8; i )

                                {

                                    if ((map[i] == 1 && map[i - 1] == 2)|| (map[i 10] == 1 && map[i 9] == 2)||( map[i 20] == 1 && map[i 19] == 2))

                                        ch = 0;

                                }

                            }

                            if (ch != 0)

                            {

                                for (int i = 0; i < 240; i )

                                {

                                    if (map[i] == 1)

                                    {

                                        map[i - 1] = map[i];

                                        map[i] = 0;

                                    }

                                }

                                xblock[1] = xblock[1] - 1;//

                                drawmap();

                            }

                    }

                    //按下上按键,判断形态变换后是否重叠已经停止的方块,如没有形态变换

                    if (ch == 72)//上键 

                    {

                        for (int i = 0; i < 24; i )

                        {

                            if (i * 10 == xblock[1] || (i * 10 9) == xblock[1])

                                ch = 0;

                        }

                        if (ch != 0 && xblock[0] == 0 && map[xblock[1] 1] == 1 && map[xblock[1] 10] != 2 && map[xblock[1] - 10] != 2 && map[xblock[1] - 20] != 2)

                        {

                            map[xblock[1] 1] = 0;

                            map[xblock[1] 2] = 0;

                            map[xblock[1] - 1] = 0;

                            map[xblock[1] 10] = 1;

                            map[xblock[1] - 10] = 1;

                            map[xblock[1] - 20] = 1;

                            ch = 0;

                        }

                        if (ch != 0 && xblock[0] == 0 && map[xblock[1] - 10] == 1 && map[xblock[1] 1] != 2 && map[xblock[1] 2] != 2 && map[xblock[1] - 1] != 2)

                        {

                            map[xblock[1] 1] = 1;

                            map[xblock[1] 2] = 1;

                            map[xblock[1] - 1] = 1;

                            map[xblock[1] 10] = 0;

                            map[xblock[1] - 10] = 0;

                            map[xblock[1] - 20] = 0;

                        }

                        if (xblock[0] == 2)

                            ch = 0;

                        int tempblock[3][3];

                        if (ch != 0 && xblock[0] == 1)

                        {

                            for (int i = 0; i < 3; i )

                            {

                                for (int j = 0; j < 3; j )

                                {

                                    if (map[xblock[1] - 11 j i*10] != 2)

                                        tempblock[i][j] = map[xblock[1] - 11 j i * 10];

                                    else

                                        tempblock[i][j] = 0;

                                }

                            }

                            for (int i = 0; i < 3; i )

                            {

                                for (int j = 0; j < 3; j )

                                {

                                    if (tempblock[j][2 - i] == 1 && map[xblock[1] - 11 j i * 10] == 2)

                                        ch = 0;

                                }

                            }

                        }

                        if (ch != 0 && xblock[0] == 1)

                        {

                            for (int i = 0; i < 3; i )

                            {

                                for (int j = 0; j < 3; j )

                                {

                                    if ( map[xblock[1] - 11 j i * 10] != 2)

                                        map[xblock[1] - 11 j i * 10] = tempblock[j][2-i];

                                }

                            }

                        }

                        drawmap();

                        t1 = t1 1;

                    }

                    //按下右键,判断右边是否有已经下落的方块和是否已到达右边界,如果没有将正在下落的方块右移

                    if (ch == 77)//右键 

                    {

                        for (int i = 0; i < 24; i )

                        {

                            if (map[i * 10 9] == 1)

                                ch = 0;

                        }

                        if (ch != 0 && xblock[0] == 0 && map[xblock[1] 1] == 1)

                        {

                            if (map[xblock[1] 3] == 2)

                                ch = 0;

                        }

                        if (ch != 0 && xblock[0] == 0 && map[xblock[1] - 10] == 1)

                        {

                            if (map[xblock[1] 1] == 2)

                                ch = 0;

                        }

                        if (ch != 0 && xblock[0] != 0)

                        {

                            for (int i = xblock[1] - 11; i < xblock[1] - 8; i )

                            {

                                if ((map[i] == 1 && map[i 1] == 2) || (map[i 10] == 1 && map[i 11] == 2) || (map[i 20] == 1 && map[i 21] == 2))

                                    ch = 0;

                            }

                        }

                        if (ch != 0)

                        {

                            for (int i = 239; i >= 0; i--)

                            {

                                if (map[i] == 1)

                                {

                                    map[i 1] = map[i];

                                    map[i] = 0;

                                }

                            }

                            xblock[1] = xblock[1] 1;

                        }

                        drawmap();

                    }

                    //按下按键,方块下落

                    if (ch == 80)

                    {

                        downblock();

                        drawmap();

                        break;

                    }

                    //空格 暂停 

                    if(ch==32) system("pause");

                }    

                t = t - 1;//t用来控制速度最开始循环20000次 

            }

            //自动下落

            if (t <= 0)

            {

                downblock();

                drawmap();

            }

        }    

    }

}

//入口函数

int main()

{

    title();

    welcom();

    return 0;

}

0 人点赞