• 创意俄罗斯方块


    版权声明:访问者可将本网站提供的内容或服务用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯本网站及相关权利人的合法权利。除此以外,将本网站任何内容或服务用于其他用途时,须征得本网站及相关权利人的书面许可,并支付报酬。转载需表明文章地址。

    本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站,予以删除。

    作者QQ:1765813715

    由于这个游戏倾入了我大量的时间和创意 所以写了个版权声明

    这个游戏在基础的俄罗斯方块上面还添加了  两种方块

    一种是幽灵方块 (可以在方块间任意移动 直到它所在的这一列下面没有空)

    另一种是  炸弹方块  (他可以在激活和非激活中转换,激活时到达底部后会清除周围3*3的方块 非激活就和普通方块没有什么区别

    第一次用WindowsApi写游戏  注释很多。 也查了很多资料

    Windows窗口的创建以后我在写一个详细的 这里我就直接从CALLBACK WndProc 开始讲解我的程序结构了

    下面讲解每一个函数

    void DrawPanel(HDC hdc);      绘制游戏面板

    void RefreshPanel(HDC hdc); 刷新游戏面板
    void creat();          创造方块 一共有9中方块
    bool isbottom(HWND hwnd);    判断是否到达底部  幽灵方块判断方式不同  以及到达底部后的处理(即融入地图 或者炸弹方块的 爆炸) 以及检测游戏结束
    bool drop(HDC hdc,HWND hwnd); 下降 其中调用 isbottom() 如果到达底部  调用clear(),creat(),refreshpanel()
    void move_left();                      向左移动  检测碰撞(幽灵方块也是特殊处理)
    void move_right();                    同上
    void transform();        变形     变形时需要检测是否满足    炸弹方块的变形是 在激活和非激活状态之间转换
    void clear(HDC hdc);      消行    内部还实现加分
    void preview(HDC hdc);     图形预览框

     这里添加下 过程记录吧 也方便其他像学习的人有一条明确的路线

    4月28日  下午6点—晚上12点    学习窗口的创建    如何绘画出图形界面
    4月29日  上午8点—11.30   写出  已测试( 方块生成  碰撞检测  向下移动  时钟系统   暂停功能  检测游戏结束)
                 未测试( 消行 )
                中午1点—1点40   完成左右移动   测试了消行  但是没有成功 还未发现原因(先睡觉)。。。。
                  下午3点—4点   修改消行BUG  完成转换功能   到这里基本功能差不多就全部完成了
                  现在基本的俄罗斯方块已经完成了   不过我的俄罗斯方块比较高级  还有两种方块就是幽灵方块 和 炸弹方块
          下午6点—7点  游戏测试 查找BUG(别说还真有)
           晚上11点—11.半  完成幽灵方块
    4月30日  上午8点—11点  完成炸弹方块    图形预览
       晚上11点   完成BGM (找了几个小时)。。

     注意:我是在vs2017上面开发的  测试在dev上面无法编译   而且由于我这个添加BGM 所以有可能在你的电脑上也无法编译

          如果还缺少头文件请自行添加

        如果是这样,就删除播放BGM 的代码 或者自己从新加载资源文件

         在这里我把我的文件上传到百度网盘里   大家有需要的可以自己下载  其中bebug和release中的EXE文件 可以直接用来玩

         http://pan.baidu.com/s/1cpf9AA

    #include "stdafx.h"
    #include <windows.h>
    
    // C 运行时头文件
    #include <stdlib.h>
    #include <malloc.h>
    #include <memory.h>
    #include <tchar.h>
    #include<time.h>
    #include<iostream>
    #include "俄罗斯方块.h"
    #include<mmsystem.h>
    #pragma comment(lib,"winmm.lib")//知识就是财富啊  一个背景音乐搞了半天
    #define CELL 20//方块大小
    #define ROWS 25 //行数
    #define COLS 15//列数
    using namespace std;
    TCHAR str[256];
    int id; //记录当前方块种类
    int next_id;//记录下一个方块的ID 达到预览
    int len;
    int score = 0;                //得分
    int level = 0;                    //游戏等级
    int speed = 500;                //游戏速率  初始化为1秒   后面的速率为  speed-min(level,7)*100;
    UINT timer = 0;
    bool ispause = 0;            //记录是否暂停
    bool panel[25][15] = { 0 };    //记录游戏底层画面
    bool active;                //记录炸弹方块是否被激活
    int direction[8][2] = { 1,0,0,1,-1,0,0,-1,1,1,-1,-1,1,-1,-1,1 };//炸弹方块爆破的8个方向
    COORD pre_peak;
    bool pre_panel[2][4];        //预览面板
    
    bool* block=NULL;            //通过记录方块组合 最左上角(我们后面称为顶点)的坐标  和组合的宽度高度 来确定这个组合的位置。   这样做有很大的好处
    int block_top = 0;
    int block_left = 0;
    int block_height = 0;
    int block_width = 0;
    
    void DrawPanel(HDC hdc);
    void RefreshPanel(HDC hdc);
    void creat();
    bool isbottom(HWND hwnd);
    bool drop(HDC hdc,HWND hwnd);
    void move_left();
    void move_right();
    void transform();
    void clear(HDC hdc);
    void preview(HDC hdc);
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lparam);//回调函数
    
    //建立窗口需要经过5个步骤  设计窗口类型  注册窗口类型 创建 显示 消息循环
    int APIENTRY WinMain(HINSTANCE hInstance,   //程序当前运行的实例句柄
        HINSTANCE hPrevInstance,                //当前实例的前一个实例 w32下不再起作用
        LPSTR lpCmdLine,                        //表示传给程序的命令行参数
        int nCmdShow)                          //指定程序窗口如何显示,如 最大化最小化等
    {
        WNDCLASS wndclass;                    //下面都是注册的内容。。。。。(好多。。)
        HWND hwnd;
        MSG msg;
        TCHAR lpszClassName[] = TEXT("俄罗斯方块");
        wndclass.style = CS_HREDRAW | CS_VREDRAW;           //窗口样式
        wndclass.lpfnWndProc = WndProc;                     //指向窗口函数的指针
        wndclass.cbClsExtra = 0;                            //窗口类附加字节, 为该类窗口共享,一般置0
        wndclass.cbWndExtra = 0;                            //窗口字节 一般值0
        wndclass.hInstance = hInstance;                        //当前应用程序的实例句柄
        wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);    //指定窗口图标
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);        //指定窗口光标
        wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//设置背景色
        wndclass.lpszMenuName = NULL;                                //窗口菜单资源名
        wndclass.lpszClassName = lpszClassName;                        //窗口类名
        if (!RegisterClass(&wndclass))                                //注册
            return FALSE;
        hwnd = CreateWindow(lpszClassName, TEXT("俄罗斯方块"),        //创建
            WS_OVERLAPPEDWINDOW, 
            CW_USEDEFAULT, CW_USEDEFAULT, 
            CW_USEDEFAULT, CW_USEDEFAULT,
            NULL, NULL, 
            hInstance, NULL);
        ShowWindow(hwnd, nCmdShow);                                    //显示
        UpdateWindow(hwnd);                                            //上传
        while (GetMessage(&msg, NULL, 0, 0))                        //消息循环
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return msg.wParam;
    }
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)//回掉函数
    {
        switch (message)
        {
        case WM_CREATE:
            PlaySound(                        //BGM
                MAKEINTRESOURCE(130),        //不知道为什么 这里不能直接写 IDR_WAVE1 而是要写他的数字id
                GetModuleHandle(NULL),
                SND_RESOURCE | SND_ASYNC | SND_LOOP);
            MoveWindow(hwnd, 200, 200, COLS*CELL+300, ROWS*CELL+40, FALSE);//16.40
            pre_peak.X = 16; pre_peak.Y = 2; //确定预览框 顶点坐标
            srand(int(time(0)));
            next_id = rand() % 9;
            creat();
            timer = SetTimer(hwnd, 1, speed - min(7, level) * 50, NULL);  //创建一个时钟
            return 0;
        case WM_PAINT:
            HDC hdc;
            PAINTSTRUCT ps;
            hdc = BeginPaint(hwnd, &ps);
            DrawPanel(hdc);
            RefreshPanel(hdc);
            preview(hdc);
            TextOutW(hdc, 350+100, 370-330, TEXT("得分:"), 3);
            TextOutW(hdc, 350+100, 390-330, TEXT("等级:"), 3);
            TextOut(hdc, 350, 480, TEXT("Made by LYON"), strlen("Made by LYON"));
            len = wsprintf(str, TEXT("%d"),  score);  //。。。为了找这个    找了  一个小时。。。 怎么把整数转换为字符串
            TextOutW(hdc, 390+100, 370-330, str, len);            //其实也可以自己写一个转换函数的 ,,,不过。。。怎么能光用会的知识呢。。
            len = wsprintf(str, TEXT("%d"), level);
            TextOutW(hdc, 390+100, 390-330, str, len);
    
            EndPaint(hwnd, &ps);
            return 0;
        case WM_TIMER:                        //时钟发来的消息 这个时候就应该下落一个了
            if (!ispause)
            {
                hdc = GetDC(hwnd);
                drop(hdc, hwnd);
                ReleaseDC(hwnd, hdc);
            }
            return 0;
        case WM_KEYDOWN:                //有按键按下了
            hdc = GetDC(hwnd);                //获取设备上下文
            switch (wParam)
            {
            case VK_SPACE:
                if (ispause)
                {
                    ispause = !ispause;
                    timer = SetTimer(hwnd, 1, speed - min(7, level) * 50, NULL);
                }
                else
                {
                    ispause = !ispause;
                    KillTimer(hwnd, timer);            //销毁时钟
                }
                break;
            case VK_UP:
                if (ispause) break;
                transform();
                RefreshPanel(hdc);
                break;
            case VK_LEFT:
                if (ispause) break;
                if (block_left == 0) break;    //这一句也可以去掉   但是如果写在move 里面判断的话 还是会重绘界面  长按LEFT就会导致  方块 一闪一闪的
                move_left();
                RefreshPanel(hdc);
                break;
            case VK_RIGHT:
                if (ispause) break;
                if (block_left + block_width == 15) break;   //同上
                move_right();
                RefreshPanel(hdc);
                break;
            case VK_DOWN:
                if (!ispause)
                {
                    hdc = GetDC(hwnd);
                    drop(hdc, hwnd);
                    ReleaseDC(hwnd, hdc);
                }
                break;
            default:
                break;
            }
            ReleaseDC(hwnd, hdc);
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        default:
            return DefWindowProc(hwnd, message, wParam, lParam);
        }
        return 0;
    }
    
    bool isbottom(HWND hwnd)                //检测是否到达底部
    {
        if (block == NULL) return 0;
        bool flag = 0;
        if (id == 7)            //幽灵方块需要特殊判断
        {
            flag = 1;
            for (int i = 1; block_top + i < 25; i++) //判断这一列 下面还有没有空 
            {
                if (!panel[block_top + i][block_left])
                {
                    flag = 0; break;
                }
            }
        }
        else
        {
            for (int i = block_height - 1; i >= 0 && !flag; i--)
            {
                for (int j = 0; j < block_width && !flag; j++)
                {
                    if (*(block + i*block_width + j))                               //判断每一个方块下面又没有方块了
                    {
                        if (block_top + i + 1 < 0)continue;          //还没有进入地图
                        if (panel[block_top + i + 1][block_left + j] || block_top + i + 1 == 25)
                        {
                            flag = 1; break;
    
                        }
                    }
                }
            }
        }
        if (flag)            //如果到达底部了 
        {
            if (id == 8 && active)            //炸弹方块到达底部后的处理方式不同
            {
                for (int i = 0; i < 8; i++)
                {
                    if (block_top + direction[i][0] < 0 || block_top + direction[i][0] == 25 || block_left + direction[i][1] < 0 || block_left + direction[i][1] >= 15)
                        continue;
                    panel[block_top + direction[i][0]][block_left + direction[i][1]] = FALSE;
                }
                return flag;
            }
            if (block_top < 0)//游戏结束 ,方块无法进入地图  说明下面已经满了 Gameover
            {
                if (timer)
                {
                    KillTimer(hwnd,timer);
                }
                if (block) delete[] block;
                MessageBox(hwnd, TEXT("游戏结束"), TEXT("MSG"), MB_OK | MB_ICONEXCLAMATION);
                SendMessage(hwnd, WM_CLOSE, 0, 0);
            }
            else                        //将方块融入地图中
            {
                for (int i = 0; i < block_height; i++)
                {
                    for (int j = 0; j < block_width; j++)
                    {
                        if (*(block + i*block_width + j))
                        {
                            panel[block_top + i][block_left + j] = TRUE;
                        }
                    }
                }
            }
        }
        return flag;
    }
    void clear(HDC hdc)                                //有问题
    {
        bool flag; int number=0;
        for (int i = 0; i < block_height; i++)
        {
            flag = 1;
            for (int j = 0; j < 15; j++)
            {
                if (!panel[block_top + i][j])
                {
                    flag = 0; break;
                }
            }
            if (flag)
            {
                number++;
                MessageBeep(1);//消行时会有声音
                for (int k = block_top+i; k > 0; k--)
                {
                    for (int j = 0; j < 15; j++)
                    {
                        panel[k][j] = panel[k - 1][j];
                    }
                }
                for (int j = 0; j < 15; j++)
                    panel[0][j] = FALSE;
            }
        }
    
        switch (number)
        {
        case 1:score += 5;  break;
        case 2:score += 13; break;
        case 3:score += 20; break;
        case 4:score += 28; break;
        default: break;
        }
        level = score / 50;
        len = wsprintf(str, TEXT("%d"), score);  
        TextOutW(hdc, 390+100, 370-330, str, len);
        len = wsprintf(str, TEXT("%d"), level);
        TextOutW(hdc, 390+100, 390-330, str, len);
    } 
    bool drop(HDC hdc,HWND hwnd)                    //下落
    {
        if (!isbottom(hwnd))        //还没有到达底部
            block_top++;
        else                    //已经到达了底部
        {
            clear(hdc);//消行
            creat();//创建一个新组合
            preview(hdc);
            RefreshPanel(hdc);
        }
        RefreshPanel(hdc);
        return 0;
    }
    void DrawPanel(HDC hdc)          //绘制游戏面板
    {
        int x, y;
        RECT rect;//矩形类
    
        for (y = 0; y<ROWS; y++)
        {
            for (x = 0; x<COLS; x++)
            {
                //计算方块的边框范围
                rect.top = y*CELL + 1;
                rect.bottom = (y + 1) *CELL - 1;
                rect.left = x*CELL + 1;
                rect.right = (x + 1) *CELL - 1;
                FrameRect(hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));//绘画矩形边框
            }
        }
        rect.top = pre_peak.Y*CELL-1;
        rect.bottom = (pre_peak.Y + 2)*CELL+1;
        rect.left = pre_peak.X*CELL-1;
        rect.right = (pre_peak.X + 4)*CELL+1;
        FrameRect(hdc, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
        TextOut(hdc, pre_peak.X*CELL, pre_peak.Y*CELL - 30, TEXT("图形预览"), 4);
    }
    void RefreshPanel(HDC hdc)              //刷新面板
    {
        int x, y;
        RECT rect;
        HBRUSH h_bSolid = (HBRUSH)GetStockObject(GRAY_BRUSH),          //设置笔刷颜色
            h_bEmpty = (HBRUSH)GetStockObject(WHITE_BRUSH),
            h_bomb_active = CreateSolidBrush(RGB(255, 0, 0)),
            h_bomb_nactive= CreateSolidBrush(RGB(100, 0, 0)),
        h_ghost = (HBRUSH)GetStockObject(BLACK_BRUSH); 
        //先刷屏
        for (y = 0; y<ROWS; y++)
        {
            for (x = 0; x<COLS; x++)
            {
                //为避免刷掉方块的边框,rect范围必须比边框范围小1
                rect.top = y*CELL + 2;
                rect.bottom = (y + 1) *CELL - 2;
                rect.left = x*CELL + 2;
                rect.right = (x + 1) *CELL - 2;
                if (panel[y][x])
                    FillRect(hdc, &rect, h_bSolid);                    //绘画矩形内部
                else
                    FillRect(hdc, &rect, h_bEmpty);
            }
        }
        if (block == NULL) return;
        if (id == 7)  //幽灵方块为黑色
        {
            rect.top = block_top*CELL + 2;
            rect.bottom = (block_top + 1)*CELL - 2;
            rect.left = block_left*CELL + 2;
            rect.right = (block_left + 1)*CELL - 2;
            FillRect(hdc, &rect, h_ghost);
        }
        else if (id == 8)
        {
            rect.top = block_top*CELL + 2;
            rect.bottom = (block_top + 1)*CELL - 2;
            rect.left = block_left*CELL + 2;
            rect.right = (block_left + 1)*CELL - 2;
            if(active)
            FillRect(hdc, &rect, h_bomb_active);
            else
            FillRect(hdc, &rect, h_bomb_nactive);
        }
        else
        {
            for (int i = 0; i < block_height; i++)                    //画出方块组合
            {
                for (int j = 0; j < block_width; j++)
                {
                    if (*(block + i*block_width + j))
                    {
                        rect.top = (block_top + i)*CELL + 2;
                        rect.bottom = (block_top + i + 1)*CELL - 2;
                        rect.left = (block_left + j)*CELL;
                        rect.right = (block_left + j + 1)*CELL - 2;
                        FillRect(hdc, &rect, h_bSolid);
                    }
                }
            }
        }
    }
    void creat()
    {
        srand(int(time(0)));
        id = next_id;
        next_id = rand() % 9;
        if (block != NULL)
        {
            delete[] block;
        }
        switch (id)
        {
        case 0:                                    //直线型
            block_height = 1;
            block_width = 4;
            block_top = -block_height;
            block_left = (COLS - block_width) / 2 + block_width / 2;//定位到中间上面
            block = new bool[block_height*block_width];                //分配足够的空间储存组合
            *(block) = TRUE;   *(block + 1) = TRUE;   *(block + 2) = TRUE;  *(block + 3) = TRUE;
            break;
        case 1:                                    //正方形
            block_height = 2;
            block_width = 2;
            block_top = -block_height;
            block_left = (COLS - block_width) / 2 + block_width /2;
            block = new bool[block_height*block_width];        
            *(block) = TRUE;      *(block + 1) = TRUE;   
            *(block + 2) = TRUE;  *(block + 3) = TRUE;
            break;
        case 2:                                    //倒T型
            block_height = 2;
            block_width = 3;
            block_top = -block_height;
            block_left = (COLS - block_width) / 2 + block_width /2;
            block = new bool[block_height*block_width];
            *(block) = FALSE;       *(block + 1) = TRUE;    *(block + 2) = FALSE;
            *(block + 3) = TRUE;    *(block + 4) = TRUE;    *(block + 5) = TRUE;
            break;
        case 3:                                    //左L型
            block_height = 2;
            block_width = 3;
            block_top = -block_height;
            block_left = (COLS - block_width) / 2 + block_width / 2;
            block = new bool[block_height*block_width];
            *(block) = TRUE;        *(block + 1) = FALSE;   *(block + 2) = FALSE;
            *(block + 3) = TRUE;    *(block + 4) = TRUE;    *(block + 5) = TRUE;
            break;
        case 4:                                //右L型
            block_height = 2;
            block_width = 3;
            block_top = -block_height;
            block_left = (COLS - block_width) / 2 + block_width / 2;
            block = new bool[block_height*block_width];
            *(block) = FALSE;        *(block + 1) = FALSE;    *(block + 2) = TRUE;
            *(block + 3) = TRUE;    *(block + 4) = TRUE;    *(block + 5) = TRUE;
            break;
        case 5:                            //正Z型
            block_height = 2;
            block_width = 3;
            block_top = -block_height;
            block_left = (COLS - block_width) / 2 + block_width / 2;
            block = new bool[block_height*block_width];
            *(block) = TRUE;        *(block + 1) = TRUE;    *(block + 2) = FALSE;
            *(block + 3) = FALSE;    *(block + 4) = TRUE;    *(block + 5) = TRUE;
            break;
        case 6:                        //倒Z型
            block_height = 2;
            block_width = 3;
            block_top = -block_height;
            block_left = (COLS - block_width) / 2 + block_width / 2;
            block = new bool[block_height*block_width];
            *(block) = FALSE;        *(block + 1) = TRUE;    *(block + 2) = TRUE;
            *(block + 3) = TRUE;    *(block + 4) = TRUE;    *(block + 5) = FALSE;
            break;
        case 7:                        //幽灵方块
            block_height = 1;
            block_width = 1;
            block_top = -block_height;
            block_left = (COLS - block_width) / 2 + block_width / 2;
            block = new bool[block_height*block_width];
            *(block) = TRUE;
        case 8:                                //炸弹方块
            block_height = 1;
            block_width = 1;
            block_top = -block_height;
            block_left = (COLS - block_width) / 2 + block_width / 2;
            block = new bool[block_height*block_width];
            *(block) = TRUE;
            active = TRUE;
            break;
        }
    }
    void move_left()                                    //判断 方块的左边又没有方块 ,没有就可以过去
    {
        if (id == 7)
        {
            if (block_left == 0) return;
        }
        else
        {
            for (int i = 0; i < block_height; i++)
            {
                for (int j = 0; j < block_width; j++)
                {
                    if (*(block + block_width*i + j))
                    {
                        if (panel[block_top + i][block_left + j - 1] || block_left == 0)
                            return;
                    }
                }
            }
        }
        block_left--;                                        //没有就移动顶点坐标
    }
    void move_right()                                    //判断方块的右边有没有方块  
    {
        if (id == 7)
        {
            if (block_left ==14)
                return;
        }
        else
        {
            for (int i = 0; i < block_height; i++)
            {
                for (int j = block_width - 1; j >= 0; j--)
                {
                    if (*(block + i*block_width + j))
                    {
                        if (panel[block_top + i][block_left + j + 1] || block_left + block_width == 15)
                            return;
                    }
                }
            }
        }
        block_left++;
    }
    void transform()//变形
    {
        if (id == 7 || id == 1) return;//幽灵方块和 正方形方块转换后没差
        if (id == 8)                //炸弹方块直接转换激活状态
        {
            active = !active; return;
        }
        bool* zz = new bool[block_height*block_width];      //先建立一个缓存 表示转换后方块的位置
        for (int i = 0; i < block_width; i++)
        {
            for (int j = 0; j < block_height; j++)
            {
                //zz[i][j]=block[block_height-j-1][i]   转换公式
                *(zz + i*block_height + j) = *(block + (block_height-1-j)*block_width + i);  //转换
            }
        }
        //开始不重新定位 顶点 感觉转换特别死板  不是中心旋转 所以这里要改 一下顶点左边
        //嗯  改了一下感觉好多了
        int zz_top = block_top + (block_height - block_width) / 2;
        int zz_left = block_left + (block_width - block_height) / 2;
        if (zz_top + block_width >= 25 || zz_left + block_height > 15||zz_left<0) return;   //判断方块是否越界
        for (int i = 0; i < block_width; i++)                                            //判断该位置是否已经存在方块
        {
            for (int j = 0; j < block_height; j++)
            {
                if (panel[zz_top + j][zz_left + j])
                    return;
            }
        }
    
        for (int i = 0; i < block_width; i++)                                      //前面都达标了 说明可以转换 ,
        {
            for (int j = 0; j < block_height; j++)
                *(block + i*block_height + j) = *(zz + i*block_height + j);
        }
        delete[] zz;                                                                //删除缓存
        int a;
        block_top = zz_top;
        block_left = zz_left;
        a = block_width; block_width = block_height; block_height = a;
    }
    void preview(HDC hdc)        //图形预览
    {
        memset(pre_panel, 0, sizeof(pre_panel));
        RECT rect;
        HBRUSH h_brush = (HBRUSH)GetStockObject(GRAY_BRUSH);
        switch (next_id)
        {
        case 0:
            pre_panel[0][0] = TRUE; pre_panel[0][1] = TRUE; pre_panel[0][2] = TRUE; pre_panel[0][3] = TRUE;
            TextOut(hdc, pre_peak.X*CELL+20, pre_peak.Y*CELL + 50, TEXT("直线          "), 7);
            break;
        case 1:
            pre_panel[0][1] = TRUE; pre_panel[0][2] = TRUE; pre_panel[1][1] = TRUE; pre_panel[1][2] = TRUE;
            TextOut(hdc, pre_peak.X*CELL+20, pre_peak.Y*CELL + 50, TEXT("正方          "), 7);
            break;
        case 2:
            pre_panel[0][1] = TRUE; pre_panel[1][0] = TRUE; pre_panel[1][1] = TRUE; pre_panel[1][2] = TRUE;
            TextOut(hdc, pre_peak.X*CELL+20, pre_peak.Y*CELL + 50, TEXT("倒T           "), 7);
            break;
        case 3:
            pre_panel[0][0] = TRUE; pre_panel[1][0] = TRUE; pre_panel[1][1] = TRUE; pre_panel[1][2] = TRUE;
            TextOut(hdc, pre_peak.X*CELL+20, pre_peak.Y*CELL + 50, TEXT("左L           "), 7);
            break;
        case 4:
            pre_panel[0][2] = TRUE; pre_panel[1][0] = TRUE; pre_panel[1][1] = TRUE; pre_panel[1][2] = TRUE;
            TextOut(hdc, pre_peak.X*CELL+20, pre_peak.Y*CELL + 50, TEXT("右L           "), 7);
            break;
        case 5:
            pre_panel[0][0] = TRUE; pre_panel[0][1] = TRUE; pre_panel[1][1] = TRUE; pre_panel[1][2] = TRUE;
            TextOut(hdc, pre_peak.X*CELL+20, pre_peak.Y*CELL + 50, TEXT("左闪电        "), 7);
            break;
        case 6:
            pre_panel[0][2] = TRUE; pre_panel[0][1] = TRUE; pre_panel[1][1] = TRUE; pre_panel[1][0] = TRUE;
            TextOut(hdc, pre_peak.X*CELL+20, pre_peak.Y*CELL + 50, TEXT("右闪电        "), 7);
            break;
        case 7:
            pre_panel[0][1] = TRUE;
            TextOut(hdc, pre_peak.X*CELL+20, pre_peak.Y*CELL + 50, TEXT("幽灵          "), 7);
            h_brush = (HBRUSH)GetStockObject(BLACK_BRUSH);
            break;
        case 8:
            h_brush = CreateSolidBrush(RGB(255, 0, 0));
            TextOut(hdc, pre_peak.X*CELL+20, pre_peak.Y*CELL + 50, TEXT("炸弹          "), 7);
            pre_panel[0][1] = TRUE;
            break;
        }
        rect.top = pre_peak.Y*CELL;
        rect.bottom = (pre_peak.Y + 2)*CELL;
        rect.left = pre_peak.X*CELL;
        rect.right = (pre_peak.X + 4)*CELL;
        FillRect(hdc, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
        for (int i = 0; i < 2; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                if (pre_panel[i][j])
                {
                    rect.top = (pre_peak.Y + i)*CELL + 2;
                    rect.bottom = (pre_peak.Y + i + 1)*CELL - 2;
                    rect.left = (pre_peak.X + j)*CELL + 2;
                    rect.right = (pre_peak.X + j + 1)*CELL - 2;
                    FillRect(hdc, &rect, h_brush);
                }
            }
        }
    }

     回顾总结:编写过程中遇到了很多困难,很多知识都不懂 只有自己到处找问人,   而且没有抽象为类  可扩展性  和 代码重用能力太差 (一个图形预览 我还额外的编写了一个构造的函数  完全可以用creat()里面的, 但是就是由于开始考虑不完全导致后面修改起来麻烦)

  • 相关阅读:
    PostgreSQL操作-psql基本命令
    python 解决抓取网页中的中文显示乱码问题
    1018: [SHOI2008]堵塞的交通traffic
    1015: [JSOI2008]星球大战starwar
    1057: [ZJOI2007]棋盘制作
    1022: [SHOI2008]小约翰的游戏John
    1059: [ZJOI2007]矩阵游戏
    1206: [HNOI2005]虚拟内存
    1201: [HNOI2005]数三角形
    1003: [ZJOI2006]物流运输trans
  • 原文地址:https://www.cnblogs.com/Swust-lyon/p/6791524.html
Copyright © 2020-2023  润新知