签到

05月05日
尚未签到

共有回帖数 0

    奈何情殇

    等级:
    俄罗斯方块终于成型了,由于同时还在写其他项目,总是写着写着就思路中断了,看来写代码还是需要一气呵成。好啦,废话不多说,直接开喷,哦不,开讲^_^。

    这次时间虽长,其实我是用心的,duang,做了一个动态的开始界面,注意是动态的哦,看来是不是像加了特技。

    游戏主界面是这个样子的。
    下面介绍一下游戏的玩法:
    1 一个方块由4个格子组成,穷尽4个格子能够组成的所有图形,共有19种图形(方向不同也算是一种),19种图形分为7组分别是:

    2 随机生成这19种方块中的一种,对这个方块可以进行左移,右移,或者按顺序改变成这个方块所在的组内的其他方块,共三种操作。
    3 方块会不断的下落,碰到障碍物就停止下落,变成一个不再能操作的方块。
    4 当落下的方块使得一行堆满时,就可以消去一行,并加分。
    5 最终不能操作的方块的高度超过最大高度时,游戏失败。以上就是玩法,其实游戏都是根据玩法编写的,俄罗斯方块的玩法大家当然是知道的,总结玩法时其实就是在思考如何用代码实现这些玩法。
    以下是游戏代码,这次的代码比较多,得有小一千行,不过这次我多写了一些函数声明,同时全局变量的声明也比较占地方。网页上黏代码看起来实在蛋疼,上传pdf版,自己下下来看哈:
    #include "stdafx.h"
    #include "Tetris.h"
    #include windows.h
    #include time.h
    #include conio.h
    #includestdlib.h

    /************************************************************************
    * 该工程完成得比较粗糙,还有很多功能没有实现,也还有些BUG没有更改。
    * 针对该项目有任何意见,或不解的地方都欢迎大家在群里提出!!!
    *
    * 该工程以Visual Studio 2013编写,有可能其他版本的编译编译不过
    * (1)工程属性-配置属性- 常规-平台工具集(当前编译器)
    * (2)vs2013中加入了很多C11标准 比如 结构体,数组赋值 “{}”全赋值为0
    /************************************************************************/

    // 字体颜色
    #define F_BLUE FOREGROUND_BLUE // 深蓝
    #define F_H_BLUE 0x0001|0x0008 // 亮蓝
    #define F_GREEN 0x0002 // 深绿
    #define F_H_GREEN 0x0002|0x0008 // 亮绿
    #define F_RED 0x0004 // 深红
    #define F_H_RED 0x0004|0x0008 // 亮红
    #define F_YELLOW 0x0002|0x0004 // 深黄
    #define F_H_YELLOW 0x0002|0x0004|0x0008 // 亮黄
    #define F_PURPLE 0x0001|0x0004 // 深紫
    #define F_H_PURPLE 0x0001|0x0004|0x0008 // 亮紫
    #define F_CYAN 0x0002|0x0004 // 深青
    #define F_H_CYAN 0x0002|0x0004|0x0008 // 亮青
    #define F_WHITE 0x0004|0x0002|0x0001 //白
    #define F_H_WHITE 0x0004|0x0002|0x0001|0x0008 //空白

    #define WALL 1 //墙
    #define SHAPE 2 //方块

    int g_Map[40][30] = {};
    //记录19种图形的结构体,这个思维数组初学者还是不太容易理解的,这里可能需要仔细的想一想
    char g_aCubeShape[7][4][4][4] = {
    {
    {
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 1, 1, 0, 0 }, // ■■
    { 1, 1, 0, 0 } // ■■
    },
    },

    {
    {
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 1, 1, 1, 1 } //■■■■
    },
    {
    { 0, 1, 0, 0 }, //■
    { 0, 1, 0, 0 }, //■
    { 0, 1, 0, 0 }, //■
    { 0, 1, 0, 0 }, //■
    },
    },

    {

    {
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 0, 1, 1, 0 }, // ■■
    { 1, 1, 0, 0 } //■■

    },
    {
    { 0, 0, 0, 0 },
    { 1, 0, 0, 0 }, //■
    { 1, 1, 0, 0 }, //■■
    { 0, 1, 0, 0 } // ■
    }
    },
    {
    {
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 1, 1, 0, 0 }, //■■
    { 0, 1, 1, 0 } // ■■

    },
    {
    { 0, 0, 0, 0 },
    { 0, 1, 0, 0 }, // ■
    { 1, 1, 0, 0 }, //■■
    { 1, 0, 0, 0 } //■
    }
    },
    {
    {
    { 0, 0, 0, 0 },
    { 1, 1, 0, 0 }, //■■
    { 0, 1, 0, 0 }, // ■
    { 0, 1, 0, 0 } // ■
    },
    {

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

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

    },
    {
    {
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 0, 1, 0, 0 }, // ■
    { 1, 1, 1, 0 } //■■■
    },
    {
    { 0, 0, 0, 0 },
    { 0, 0, 0, 0 },
    { 1, 1, 1, 0 }, //■■■
    { 0, 1, 0, 0 } // ■
    },
    {
    { 0, 0, 0, 0 },
    { 1, 0, 0, 0 }, //■
    { 1, 1, 0, 0 }, //■■
    { 1, 0, 0, 0 } //■
    },
    {
    { 0, 0, 0, 0 },
    { 0, 1, 0, 0 }, // ■
    { 1, 1, 0, 0 }, //■■
    { 0, 1, 0, 0 } // ■
    }
    },
    };

    typedef struct _RANDOM
    {
    int Dir; //随机出方向 0-3
    int Shape; //随机出形状 0-4
    int Colour; //随机出颜色 0-11
    }RANDOM, *pRANDOM;

    typedef struct _SHAPEINFO
    {
    BOOL IsObj; //是否正在移动
    COORD pos; //方块坐标
    int Dir; //方块方向
    int NewShape; //当前方块的形状
    DWORD Colour; //方块颜色
    }SHAPEINFO,*pSHAPEINFO;

    static int g_Score = 0; //当前分数
    static int g_Grade = 0; //当前等级


    ///////////////////////////////////////////////////////////////////////////////////
    //该函数作用:隐藏光标,设置光标位置,设置字符颜色
    void WriteChar(int Wide, int High, char*m_pszChar, int m_wArr);

    //该函数作用:欢迎界面
    void DrawPicture(void);

    // 该函数作用:初始化地图边界
    void InitMap();

    //该函数作用:在屏幕上打印地图边框
    void DrawMap();

    //该函数作用:设置控制台窗口大中及缓冲区大小
    void LniSehomepage();

    //该函数作用:当前行被填满时,消除当前行,并且将该行以上的图案向下移动一行
    void ClsShaep(int PosY);

    //该函数作用:判断该行是否填满
    BOOL CountScore();

    //该函数作用:产生随机数,随机第几类方块,该方块当前方向,随机方块颜色
    void Random(pRANDOM pRand);

    //该函数作用:擦除当前方块 在大数组中及屏幕上
    void ClcShanp(SHAPEINFO Shape);

    //该函数作用:画当前方块 在大数组中及屏幕上
    void DrawShanp(SHAPEINFO Shape);

    //该函数作用:将所有已经落下的不能移动的方块都在数组中赋值为墙,主要方便我判断碰撞
    void DrawShanpBuff(SHAPEINFO Shape);

    //该函数作用:判断方块是否能移动
    BOOL IsMove(SHAPEINFO Shape);

    //该函数作用:在地图右侧显示将要出现的图案
    void DrawOffsideInfo(SHAPEINFOShape);

    //该函数作用:相当于画,擦,判段方块都在这里面
    BOOL CollideEngine(pSHAPEINFO Shape, pSHAPEINFO OldShape);



    int _tmain(int argc, _TCHAR* argv[])
    {
    sinA:
    LniSehomepage();

    InitMap();
    DrawMap();
    COORD Pos = { 15, 3 }; //初始化方块出生点(右下角为中心点)
    RANDOM m_Rand = {};
    Random(&m_Rand); //随机

    SHAPEINFO m_NewShape = { true, Pos, 0, 1, m_Rand.Colour}; //当前出现的方块

    Random(&m_Rand);
    SHAPEINFO m_FutShape = { true, Pos, 0, 1, m_Rand.Colour}; //下一次将要出现的方块
    SHAPEINFO m_OldShape = m_NewShape;

    DrawShanp(m_NewShape); //绘制方块图案
    DrawOffsideInfo(m_FutShape); //绘制在右侧

    int iTime = 10000;
    while (true)
    {
    if (!m_NewShape.IsObj) //标志为假时,则重新生成图案
    {
    DrawShanpBuff(m_OldShape); //方块在数组中赋值为墙
    if (!CountScore()) //判断该行是否填满,并计分
    {
    break;
    }
    m_NewShape = m_FutShape;
    m_OldShape = m_FutShape;

    Random(&m_Rand);

    m_FutShape.Dir = 0;
    m_FutShape.NewShape =m_Rand.Shape;
    m_FutShape.Colour =m_Rand.Colour;

    DrawOffsideInfo(m_FutShape); //绘制在右侧
    DrawShanp(m_NewShape); //绘制方块图案
    }
    iTime--; //当iTime为假时,则自动向下移动一格
    if (!iTime)
    {
    m_NewShape.pos.Y++;
    CollideEngine(&m_NewShape,&m_OldShape); //相当于画,擦,判段方块
    iTime = 10000;

    }

    if (!_kbhit()) //没有键盘消息时,回到循环开始位置
    {
    continue;
    }
    char ch = _getch();
    switch (ch)
    {
    case 'W':
    case 'w': //变换方向
    {
    m_NewShape.Dir++;
    //方块,不用变化
    if (0 == m_NewShape.NewShape)
    {
    m_NewShape.Dir = 0;
    }
    //竖条,有两种变化
    else if (1 ==m_NewShape.NewShape)
    {
    if (m_NewShape.Dir  1)
    {
    m_NewShape.Dir = 0;
    }
    }
    //Z字型,有两种变化
    else if (2 ==m_NewShape.NewShape)
    {
    if (m_NewShape.Dir  1)
    {
    m_NewShape.Dir = 0;
    }
    }
    //倒Z字型,有两种变化
    else if (3 ==m_NewShape.NewShape)
    {
    if (m_NewShape.Dir  1)
    {
    m_NewShape.Dir = 0;
    }
    }
    //其余的都是四种变化
    else
    {
    if (m_NewShape.Dir  3)
    {
    m_NewShape.Dir = 0;
    }
    }
    }
    break;
    case 'S':
    case 's':
    {
    m_NewShape.pos.Y++;
    }
    break;
    case 'A':
    case 'a':
    {
    m_NewShape.pos.X--;
    }
    break;
    case 'D':
    case 'd':
    {
    m_NewShape.pos.X++;
    }
    break;
    case ' ':
    {

    }
    break;
    default:
    break;
    }
    CollideEngine(&m_NewShape,&m_OldShape);
    }
    //最后结束游戏未完成
    system("cls");
    WriteChar(15, 20, "游戏结束!", F_H_RED);
    while (!(_kbhit()))
    {
    WriteChar(26, 25, "PRESS ANY KEY TO CONTINUE", F_H_RED);
    Sleep(300);
    WriteChar(26, 25, " ", F_H_WHITE);
    Sleep(300);
    }
    system("cls");
    goto sinA;
    return 0;
    }


    /************************************************************************
    * 该函数作用:隐藏光标,设置光标位置,设置字符颜色
    * 参数:
    * wide: X坐标
    * High: Y坐标
    * m_pszChar: 字符
    * m_wArr: 颜色
    * 返回值:
    * void
    /************************************************************************/
    void WriteChar(int Wide, int High, char*m_pszChar, int m_wArr)
    {
    CONSOLE_CURSOR_INFO m_cci;
    m_cci.bVisible =FALSE; // 将该标志设为false 表示不显示光标
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &m_cci); // 设置某个控制台屏幕缓冲区的光标属性,如大小,是否可见
    COORD loc;
    loc.X = Wide * 2; // Y坐标的缓冲区是X的2倍,在控制台属性里能体现出来
    loc.Y = High;
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), m_wArr); // 设置某个控制台屏幕缓冲区中的字符的颜色和背景色
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), loc); // 设置光标位置
    printf("%s",m_pszChar);
    }


    /************************************************************************
    * 该函数作用:初始化地图边界
    * 参数:
    * void
    * 返回值:
    * void
    /************************************************************************/
    void InitMap()
    {
    memset(g_Map, 0, sizeof(g_Map)); //将数组清空

    for (int Y =0; Y 40;Y++)
    {
    for (int X =0; X  30;X++)
    {
    if ((0 ==Y)||(39==Y)||(0 ==X)||(29 ==X))
    {
    g_Map[Y][X] =WALL;
    }
    }
    }
    }

    /************************************************************************
    * 该函数作用:在屏幕上打印地图边框
    * 参数:
    * void
    * 返回值:
    * void
    /************************************************************************/
    void DrawMap()
    {
    for (int Y = 0;Y  40; Y++)
    {
    for (int X = 0;X  30; X++)
    {
    if (1 == g_Map[Y][X]) //根据数组中的值打印相应图案
    {
    WriteChar(X, Y, "■", F_WHITE);
    }
    else
    {
    WriteChar(X, Y, " ", F_H_WHITE);
    }
    }
    printf("n");
    }

    //打印右侧信息
    WriteChar(32, 2, "分数:", F_YELLOW);
    WriteChar(32, 4, "等级:", F_YELLOW);
    char buffer[6] = {};
    g_Score = 0;
    sprintf_s(buffer, sizeof(buffer), "%d", g_Score); //将int型数据转换成char类型
    WriteChar(36, 2, buffer, F_H_RED);

    char buffer1[6] = {};
    g_Grade = 0;
    sprintf_s(buffer1, sizeof(buffer1), "%d", g_Grade);
    WriteChar(36, 4, buffer1,F_H_RED);
    }

    /************************************************************************
    * 该函数作用:欢迎界面
    * 参数:
    * void
    * 返回值:
    * void
    /************************************************************************/
    void DrawPicture(void)
    {
    //COORD 结构体保存图型开始位置(X,Y)
    COORD PosDown ={ 9, 0 }; //下
    COORD PosRight ={ 39, 11 }; //左
    COORD PosLeft ={ 0,29 }; //右
    COORD PosUp ={ 29, 41 }; //上

    while (true)
    {
    Sleep(100); //休眠库函数(包含stdlib.h)
    //↓
    if (PosDown.Y  PosLeft.Y)
    {
    WriteChar(PosDown.X,PosDown.Y, "┃┃", F_RED);
    PosDown.Y++;
    }
    //←
    if (PosRight.X  PosDown.X+1)
    {
    WriteChar(PosRight.X,PosRight.Y, "━", F_RED);
    WriteChar(PosRight.X,PosRight.Y + 1, "━", F_RED);
    PosRight.X--;
    }
    //→
    if (PosLeft.X  PosUp.X)
    {
    WriteChar(PosLeft.X,PosLeft.Y, "━", F_RED);
    WriteChar(PosLeft.X,PosLeft.Y + 1, "━", F_RED);
    PosLeft.X++;
    }
    //↑
    if (PosUp.Y  PosRight.Y+1)
    {
    WriteChar(PosUp.X,PosUp.Y, "┃┃", F_RED);
    PosUp.Y--;
    }
    else
    break;
    }
    Sleep(1000); //消屏库函数
    system("cls");
    WriteChar(3, 11, "■■■■■ ■■■■■ ■■■■■ ■■■■ ■■■■■ ■■■■", F_RED);
    WriteChar(3, 12, "■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■", F_RED);
    WriteChar(3, 13, " ■ ■ ■ ■ ■ ■ ■ ■ ", F_RED);
    WriteChar(3, 14, " ■ ■■■ ■ ■■■ ■ ■■ ", F_RED);
    WriteChar(3, 15, " ■ ■ ■ ■ ■ ■ ■ ■ ", F_RED);
    WriteChar(3, 16, " ■ ■ ■ ■ ■ ■ ■", F_RED);
    WriteChar(3, 17, " ■ ■ ■ ■ ■ ■ ■ ■ ■", F_RED);
    WriteChar(3, 18, " ■■■ ■■■■■ ■■■ ■■■ ■■■■■■■ ■■■■", F_RED);
    WriteChar(25, 20, "--by--QQ群:420297600", F_H_RED);

    //_kbhit() 判断是否有键盘输入,有则返回1,否则返回0 库函数(conio.h)
    //_getch() 接收从键盘上输入的一个字符,不需要回车 0x0d:表示回车键 库函数(conio.h)
    while (!(_kbhit() && _getch() == 0x0d))
    {
    WriteChar(26, 25, "PRESS ENTER TO START", F_H_RED);
    Sleep(300);
    WriteChar(26, 25, " ", F_H_WHITE);
    Sleep(300);
    }
    system("cls");
    }

    /************************************************************************
    * 该函数作用:设置控制台窗口大中及缓冲区大小
    * 参数:
    * void
    * 返回值:
    * void
    /************************************************************************/
    void LniSehomepage()
    {
    //具体参考“控制台编程”
    SetConsoleTitle(L"Tetris"); //设置控制台标题
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); //输出句柄 (STD_INPUT_HANDLE)为输入宏
    COORD BufferSize ={ 80, 42 }; //初始化窗口缓冲区大小
    SMALL_RECT srctWindow ={ 0, 0, 80 - 1, 42- 1 }; //初始化窗口大小
    SetConsoleScreenBufferSize(hStdOut,BufferSize); //设置窗口的缓冲区
    SetConsoleWindowInfo(hStdOut, true, &srctWindow); //创建窗口大小
    DrawPicture();
    }

    /************************************************************************
    * 该函数作用:产生随机数,随机第几类方块,该方块当前方向,随机方块颜色
    * 参数:
    * pRANDOM 随机数结构体指针 因为要将结果返回
    * 返回值:
    * void
    /************************************************************************/
    void Random(pRANDOM pRand)
    {
    //库函数 (time.h)
    srand((unsigned)time(NULL)); //随机数 产生一个随机种子
    pRand-Shape = rand() % 5; //方块形状
    pRand-Dir = rand() % 3; //方块方向
    pRand-Colour = rand() % 11; //方块颜色
    while (true)
    {
    srand((unsigned)time(NULL)); //随机数

    //因为第一种型状的图案只有一个方向
    if (0 ==pRand-Shape) //■■
    { //■■
    pRand-Dir =0;
    break;
    }
    if (1 ==pRand-Shape&&pRand-Dir1) //同上
    {
    pRand-Dir =rand() % 4; //方块方向
    }
    else
    break;
    }

    //随机分配方块颜色
    switch (pRand-Colour)
    {
    case 0:
    case 1:
    pRand-Colour =F_BLUE;
    break;
    case 2:
    pRand-Colour = F_H_BLUE;
    break;
    case 3:
    pRand-Colour = F_GREEN;
    break;
    case 4:
    pRand-Colour = F_H_GREEN;
    break;
    case 5:
    pRand-Colour = F_RED;
    break;
    case 6:
    pRand-Colour = F_H_RED;
    break;
    case 7:
    pRand-Colour = F_YELLOW;
    break;
    case 8:
    pRand-Colour = F_H_YELLOW;
    break;
    case 9:
    pRand-Colour = F_PURPLE;
    break;
    case 10:
    pRand-Colour = F_H_PURPLE;
    break;
    case 11:
    pRand-Colour = F_CYAN;
    break;
    }
    }


    /************************************************************************
    * 该函数作用:擦除当前方块 在大数组中及屏幕上
    * 参数:
    * SHAPEINFO 方块数结构体
    * 返回值:
    * void
    /************************************************************************/
    void ClcShanp(SHAPEINFO Shape)
    {
    //以右下角为中心点 依次从左上角开始循环遍历16个点
    for (int Y = Shape.pos.Y - 3; Y = Shape.pos.Y;Y++)
    {
    for (int X =Shape.pos.X - 3; X = Shape.pos.X;X++)
    {
    //定义的方块型状结构体,根据该数组对应的值擦除大数组中的值及屏幕上的字符
    if (g_aCubeShape[Shape.NewShape][Shape.Dir][Y - Shape.pos.Y+ 3][X - Shape.pos.X + 3])
    {
    g_Map[Y][X] = 0;
    WriteChar(X, Y, " ", F_H_WHITE);
    }
    }
    }
    }


    /************************************************************************
    * 该函数作用:画当前方块 在大数组中及屏幕上
    * 参数:
    * SHAPEINFO 方块数结构体
    * 返回值:
    * void
    /************************************************************************/
    void DrawShanp(SHAPEINFO Shape)
    {
    //该函数同擦除函数 和擦除函数几乎没差别 唯一差别在传入的坐标值的不一样
    //擦除是擦除老坐标,画则画新坐标
    for (int Y = Shape.pos.Y - 3; Y = Shape.pos.Y;Y++)
    {
    for (int X = Shape.pos.X - 3; X = Shape.pos.X;X++)
    {
    if (g_aCubeShape[Shape.NewShape][Shape.Dir][Y - Shape.pos.Y+ 3][X - Shape.pos.X + 3])
    {
    g_Map[Y][X] = SHAPE;
    WriteChar(X, Y, "■", Shape.Colour);
    }
    }
    }
    //有可能方块图案出生时将边框覆盖掉。
    for (int X =12;X = 15;X++)
    {
    g_Map[0][X] = WALL;
    WriteChar(X, 0, "■", F_WHITE);
    }
    }

    /************************************************************************
    * 该函数作用:将所有已经落下的不能移动的方块都在数组中赋值为墙,主要方便我判断碰撞
    * 参数:
    * SHAPEINFO 方块数结构体
    * 返回值:
    * void
    /************************************************************************/
    void DrawShanpBuff(SHAPEINFO Shape)
    {
    for (int Y = Shape.pos.Y - 3; Y = Shape.pos.Y;Y++)
    {
    for (int X = Shape.pos.X - 3; X = Shape.pos.X;X++)
    {
    if (g_aCubeShape[Shape.NewShape][Shape.Dir][Y - Shape.pos.Y+ 3][X - Shape.pos.X + 3])
    {
    WriteChar(X, Y, "■", F_H_GREEN);
    g_Map[Y][X] = WALL; //方块在数组中赋值为墙
    }
    }
    }
    }

    /************************************************************************
    * 该函数作用:判断方块是否能移动
    * 参数:
    * SHAPEINFO 方块数结构体
    * 返回值:
    * BOOL 能移动返回true,否则返回false
    /************************************************************************/
    BOOL IsMove(SHAPEINFO Shape)
    {
    for (int Y = Shape.pos.Y; Y = Shape.pos.Y - 3; Y--)
    {
    for (int X =Shape.pos.X - 3; X = Shape.pos.X;X++)
    {
    //1.数组当前位置有值
    //2.方块型状数组对应的点有值
    if (1 == g_Map[Y][X] &&g_aCubeShape[Shape.NewShape][Shape.Dir][Y- Shape.pos.Y + 3][X - Shape.pos.X + 3])
    {
    return FALSE;
    }
    }
    }
    return TRUE;
    }


    /************************************************************************
    * 该函数作用:当前行被填满时,消除当前行,并且将该行以上的图案向下移动一行
    * 参数:
    * int PosY 当前Y坐标
    * 返回值:
    * void
    /************************************************************************/
    void ClsShaep(int PosY)
    {
    //从最后一行开始 Y=38
    //二维数组第一个下标表示行,第二个下标表示列。
    //此工程中 行都以'Y'表示,列以'X'表示
    for (int X = 1;X  29; X++)
    {
    WriteChar(X, PosY, "■", F_RED); //该行以满,用红色表示一下
    }
    Sleep(50);
    for (int X = 1;X 29 ;X++)
    {
    g_Map[PosY][X] = 0;
    WriteChar(X, PosY, " ", F_H_WHITE); //消空该行
    }

    //将以满的行以上的图案向下移动一格
    for (int X = 1;X  29; X++)
    {
    for (int Y = PosY - 1; Y  3; Y--)
    {
    if (!g_Map[Y][X])
    {
    break;
    }
    for (int J = Y +1; J = 38; J++)
    {
    if (!g_Map[J][X])
    {
    g_Map[Y][X] = 0;
    WriteChar(X, Y, " ", F_H_WHITE);
    g_Map[J][X] = WALL;
    WriteChar(X, J, "■", F_H_GREEN);
    continue;
    }
    break;
    }
    }
    }

    //计分及等级
    g_Score += 50;
    switch (g_Score / 100)
    {
    case 3:
    g_Grade++;
    break;
    case 8:
    g_Grade++;
    break;
    case 15:
    g_Grade++;
    break;
    case 24:
    g_Grade++;
    break;
    case 35:
    g_Grade++;
    break;
    case 50:
    g_Grade++;
    break;
    case 70:
    g_Grade++;
    break;
    case 95:
    g_Grade++;
    break;
    case 175:
    g_Grade++;
    break;
    case 230:
    g_Grade++;
    break;
    }
    }


    /************************************************************************
    * 该函数作用:判断该行是否填满
    * 参数:
    * void
    * 返回值:
    * BOOL
    /************************************************************************/
    BOOL CountScore()
    {
    for (int Y = 38;Y  3;Y--)
    {
    sig:
    int iCount = 0;
    int X = 1;
    for (; X  28;X++)
    {
    for (int J = 1;J  28;J++)
    {
    if (1 == g_Map[4][J])
    {
    return FALSE;
    }
    }
    if (!g_Map[Y][X])
    {
    break;
    }
    iCount++;
    }
    //当iCount为什27时,则表示填满
    if (iCount == 27)
    {
    ClsShaep(Y);
    Y = 38;
    goto sig;
    }
    }

    //显示到右侧
    char buffer[6] = {};
    sprintf_s(buffer, sizeof(buffer), "%d", g_Score);
    WriteChar(36, 2, buffer, F_H_RED);

    char buffer1[6] = {};
    sprintf_s(buffer1, sizeof(buffer1), "%d", g_Grade);
    WriteChar(36, 4, buffer1,F_H_RED);
    return TRUE;
    }

    /************************************************************************
    * 该函数作用:相当于画,擦,判段方块都在这里面
    * 参数:
    * pSHAPEINFO Shape 当前方块的信息 以向下移动,或方向有变化
    * pSHAPEINFO OldShape 上一次方块的信息
    * 返回值:
    * BOOL 能移动返回true,否则返回false
    /************************************************************************/
    BOOL CollideEngine(pSHAPEINFO Shape, pSHAPEINFO OldShape)
    {
    if (IsMove(*Shape)) //判断是否能移动
    {
    ClcShanp(*OldShape); //擦除之前的方块
    DrawShanp(*Shape); //画新的方块
    *OldShape =*Shape; //更新信息
    return TRUE;
    }

    //当前如果是往左右移动刚好也不能移动时,应该让其继续向下移动
    //将坐标 Y++ 在判断是否能移动
    SHAPEINFO obj =*OldShape;
    obj.pos.Y++;
    if (IsMove(obj))
    {
    *Shape =*OldShape;
    return TRUE;
    }
    //如果上面两种情况都为假时,则将该标志标为false
    //以便生成新的图案
    Shape-IsObj =0;
    return FALSE;
    }

    /************************************************************************
    * 该函数作用:在地图右侧显示将要出现的图案
    * 参数:
    * SHAPEINFO Shape 当前方块的信息
    * 返回值:
    * void
    /************************************************************************/
    void DrawOffsideInfo(SHAPEINFO Shape)
    {
    COORD pos ={ 36, 15 };
    for (int Y=pos.Y; Y =pos.Y - 3; Y--)
    {
    for (int X=pos.X; X =pos.X - 3; X--)
    {
    WriteChar(X, Y, " ", F_H_WHITE);
    if (g_aCubeShape[Shape.NewShape][Shape.Dir][pos.Y - Y][pos.X-X])
    {
    WriteChar(X, Y, "■", Shape.Colour);
    }
    }
    }
    }

    楼主 2015-06-20 18:24 回复

共有回帖数 0
  • 回 帖
  • 表情 图片 视频
  • 发表

登录直线网账号

Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号 意见反馈 | 关于直线 | 版权声明 | 会员须知