zoukankan      html  css  js  c++  java
  • GDI打砖块游戏

    //header.h文件

    #pragma once
    #include <windows.h>
    #include <stdio.h>
    
    #define KEYDOWN(vk_code)((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
    #define KEYUP(vk_code)    ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

    //Game.h文件

    #pragma once
    #include "header.h"
    
    const int    BRICKNUM = 20;
    typedef struct
    {
        int            x;        //球的位置
        int            y;
        int            radius;    //球的半径
        int            speed;    //球的速度
        int            moveX;    //每次移动的值(带正负)
        int            moveY;    //每次移动的值
        COLORREF        color;    //球的颜色
    }BALL;
    
    typedef struct
    {
        int            width;    //砖的宽度
        int            height;    //砖的高度
        RECT        rect;
        COLORREF    color;    //砖的颜色
        bool        exist;
    }BRICK;
    
    class CGame
    {
    private:
        HWND        m_hWnd;
        HDC            m_hdc;
        RECT        m_wndRect;
        BALL        m_Ball;
        BRICK*        m_pBrick;
        BRICK        m_Bar;
    public:
        CGame(HWND  hWnd);
        ~CGame(void);
    
        void    Render();
        void    ClearScreen();        //清除屏幕
        void    DrawBrick();        //画砖块
        void    DrawBar();            //画挡板
        void    DrawBall();            //画小球
        void    MoveBall();            //小球移动
        void    TestBrickCollide();    //判断碰撞砖块
        void    TestBarCollide();    //判断碰撞挡板
        void    MoveBar(int speed);    //移动挡板
    };

    //Game.cpp文件

    #include "Game.h"
    //---------------------------------------------------------
    // Name: CGame
    // Desc: 构造函数,初始化
    //---------------------------------------------------------
    CGame::CGame(HWND  hWnd)
    {
        m_hWnd    = hWnd;
        m_hdc    = GetDC(m_hWnd);
        GetWindowRect(m_hWnd, &m_wndRect);
    
        //初始化砖块
        m_pBrick    = new BRICK[BRICKNUM];
        int StartX    = m_wndRect.right / 5;    //第一块砖块的位置
        int StartY    = m_wndRect.bottom / 6;
        for(int i = 0; i < BRICKNUM; i++)
        {
            (m_pBrick + i)->width = 50;
            (m_pBrick + i)->height = 25;
            (m_pBrick + i)->color = RGB(255, 40, 100);
            (m_pBrick + i)->rect.left = StartX +(i % 5) *(m_pBrick + i)->width;
            (m_pBrick + i)->rect.top = StartY +(i / 5) *(m_pBrick + i)->height;
            (m_pBrick + i)->rect.right =(m_pBrick + i)->rect.left +(m_pBrick + i)->width;
            (m_pBrick + i)->rect.bottom    =(m_pBrick + i)->rect.top +(m_pBrick + i)->height;
            (m_pBrick + i)->exist = true;
        }
    
        //初始化挡板
        m_Bar.color = RGB(0, 0, 255);
        m_Bar.exist = true;
        m_Bar.height = 15;
        m_Bar.width = 60;
        m_Bar.rect.left = m_wndRect.right / 2 - m_Bar.width / 2;    //游戏开始画在//窗口中央底部
        m_Bar.rect.top = m_wndRect.bottom *(8.0 / 10);
        m_Bar.rect.right = m_Bar.rect.left + m_Bar.width;
        m_Bar.rect.bottom = m_Bar.rect.top  + m_Bar.height;
    
        //初始化小球
        m_Ball.color = RGB(0, 255, 255);
        m_Ball.radius = 10;
        m_Ball.x = m_Bar.rect.left + m_Bar.width / 2;    //小球开始出现在挡板的正上方//中央
    
        m_Ball.y = m_Bar.rect.top  - m_Ball.radius;
        m_Ball.speed = 1;
        m_Ball.moveX = m_Ball.speed;
        m_Ball.moveY = -m_Ball.speed;
    
    }
    //---------------------------------------------------------
    // Name: ~CGame
    // Desc: 析构函数
    //---------------------------------------------------------
    CGame::~CGame(void)
    {
        ReleaseDC(m_hWnd, m_hdc);
    }
    
    //---------------------------------------------------------
    // Name: Render
    // Desc: 游戏的渲染部分
    //---------------------------------------------------------
    void CGame::Render()
    {
        ClearScreen();
        DrawBrick();
        MoveBar(3);
        DrawBar();
        TestBrickCollide();
        TestBarCollide();
        MoveBall();
        DrawBall();
    }
    
    //---------------------------------------------------------
    // Name: DrawBrick
    // Desc: 画出没被小球打中的砖块
    //---------------------------------------------------------
    void CGame::DrawBrick()
    {
        bool gamesuccess = true;
        for(int i = 0; i < BRICKNUM; i++)
        {
            if((m_pBrick + i)->exist)
            {
                //画实心矩形
                HBRUSH    hBrush    = ::CreateSolidBrush((m_pBrick + i)->color);
                SelectObject(m_hdc, hBrush);
                ::FillRect(m_hdc, &(m_pBrick + i)->rect, hBrush);
                SelectObject(m_hdc, hBrush);
                DeleteObject(hBrush);
    
                //画矩形外框
                HPEN hPen = ::CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
                SelectObject(m_hdc, hPen);
                MoveToEx(m_hdc,(m_pBrick + i)->rect.left, (m_pBrick + i)->rect.top, NULL);
                LineTo(m_hdc, (m_pBrick + i)->rect.right, (m_pBrick + i)->rect.top);
                LineTo(m_hdc, (m_pBrick + i)->rect.right, (m_pBrick + i)->
    rect.bottom);
                LineTo(m_hdc, (m_pBrick + i)->rect.left, (m_pBrick + i)->
    rect.bottom);
                LineTo(m_hdc, (m_pBrick + i)->rect.left, (m_pBrick + i)->rect.top);
                SelectObject(m_hdc, hPen);
                DeleteObject(hPen);
    
                gamesuccess = false;
            }
        }
        
        if(gamesuccess)
        {
            MessageBox(m_hWnd, L"游戏成功!", L"Congratulation!", MB_OK);
            exit(0);
        }
    }
    
    //---------------------------------------------------------
    // Name: DrawBar
    // Desc: 画挡板
    //---------------------------------------------------------
    void CGame::DrawBar()
    {
        HBRUSH hBrush = CreateSolidBrush(m_Bar.color);
        SelectObject(m_hdc, hBrush);
        FillRect(m_hdc, &m_Bar.rect, hBrush);
        SelectObject(m_hdc, hBrush);
        DeleteObject(hBrush);
    
        HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 255, 0));
        SelectObject(m_hdc, hPen);
        MoveToEx(m_hdc, m_Bar.rect.left, m_Bar.rect.top, NULL);
        LineTo(m_hdc, m_Bar.rect.right, m_Bar.rect.top);
        LineTo(m_hdc, m_Bar.rect.right, m_Bar.rect.bottom);
        LineTo(m_hdc, m_Bar.rect.left, m_Bar.rect.bottom);
        LineTo(m_hdc, m_Bar.rect.left, m_Bar.rect.top);
        SelectObject(m_hdc, hPen);
        DeleteObject(hPen);
    }
    
    //---------------------------------------------------------
    // Name: DrawBall
    // Desc: 画小球
    //---------------------------------------------------------
    void CGame::DrawBall()
    {
        HBRUSH hBrush = CreateSolidBrush(m_Ball.color);
        HPEN hPen = CreatePen(PS_SOLID, 1, RGB(255, 0, 255));
        SelectObject(m_hdc, hBrush);
        SelectObject(m_hdc, hPen);
        Ellipse(m_hdc, m_Ball.x - m_Ball.radius, m_Ball.y - m_Ball.radius, m_Ball.x + m_Ball.radius, m_Ball.y + m_Ball.radius);
        SelectObject(m_hdc, hPen);
        SelectObject(m_hdc, hBrush);
        DeleteObject(hPen);
        DeleteObject(hBrush);
    }
    
    //---------------------------------------------------------
    // Name: ClearScreen
    // Desc: 清屏
    //---------------------------------------------------------
    void CGame::ClearScreen()
    {
        HBRUSH hBrush = CreateSolidBrush(RGB(0, 0, 0));
        SelectObject(m_hdc, hBrush);
        FillRect(m_hdc, &m_wndRect, hBrush);
        SelectObject(m_hdc, hBrush);
        DeleteObject(hBrush);
    }
    
    //---------------------------------------------------------
    // Name: MoveBall
    // Desc: 移动小球
    //---------------------------------------------------------
    void CGame::MoveBall()
    {
        if(m_Ball.x + m_Ball.moveX + m_Ball.radius > m_wndRect.right ||
            m_Ball.x + m_Ball.moveX - m_Ball.radius < m_wndRect.left)
        {
            m_Ball.moveX = -m_Ball.moveX;
        }
        if(m_Ball.y + m_Ball.moveY - m_Ball.radius < m_wndRect.top)
        {
            m_Ball.moveY = -m_Ball.moveY;
        }
        if(m_Ball.y + m_Ball.moveY + m_Ball.radius > m_wndRect.bottom)
        {
            MessageBox(m_hWnd, L"游戏结束!", L"GameOver", MB_OK);
            exit(0);
        }
        m_Ball.x += m_Ball.moveX;
        m_Ball.y += m_Ball.moveY;
    }
    
    //---------------------------------------------------------
    // Name: TestBrickCollide
    // Desc: 测试小球是否与砖块碰撞
    //---------------------------------------------------------
    void CGame::TestBrickCollide()
    {
        POINT    pt;
        pt.x = m_Ball.x;
        pt.y = m_Ball.y;
        HRGN hrgn = ::CreateRectRgn(m_Ball.x - m_Ball.radius, m_Ball.y - 
    m_Ball.radius, m_Ball.x + m_Ball.radius, m_Ball.y + m_Ball.radius);
        for(int i = 0; i < BRICKNUM; i++)
        {
            
            if((m_pBrick + i)->exist &&
                RectInRegion(hrgn, &(m_pBrick + i)->rect))
            {
                if(m_Ball.x <(m_pBrick + i)->rect.left &&
                    m_Ball.moveX > 0)
                {
                    (m_pBrick + i)->exist = false;
                    m_Ball.moveX = -m_Ball.moveX;
                    return;
                }
                if(m_Ball.x >(m_pBrick + i)->rect.right &&
                    m_Ball.moveX < 0)
                {
                    (m_pBrick + i)->exist = false;
                    m_Ball.moveX = -m_Ball.moveX;
                    return;
                }
                if(m_Ball.y <(m_pBrick + i)->rect.top &&
                    m_Ball.moveY > 0)
                {
                    (m_pBrick + i)->exist = false;
                    m_Ball.moveY = -m_Ball.moveY;
                    return;
                }
                if(m_Ball.y >(m_pBrick + i)->rect.bottom &&
                    m_Ball.moveY < 0)
                {
                    (m_pBrick + i)->exist = false;
                    m_Ball.moveY = -m_Ball.moveY;
                    return;
                }
            }
        }
        DeleteObject(hrgn);
    }
    //---------------------------------------------------------
    // Name: TestBarCollide
    // Desc: 测试小球是否与挡板碰撞
    //---------------------------------------------------------
    void CGame::TestBarCollide()
    {
        HRGN hrgn = ::CreateRectRgn(m_Ball.x - m_Ball.radius, m_Ball.y - 
    m_Ball.radius, m_Ball.x + m_Ball.radius, m_Ball.y + m_Ball.radius);
        if(RectInRegion(hrgn, &m_Bar.rect))
        {
            m_Ball.moveY = -m_Ball.moveY;
            float a =(m_Ball.x - m_Bar.rect.left);
            float b = a / m_Bar.width;
            m_Ball.moveX =((b - 0.5) * 5);
        }
        DeleteObject(hrgn);
    }
    
    //---------------------------------------------------------
    // Name: MoveBar
    // Desc: 移动挡板
    //---------------------------------------------------------
    void CGame::MoveBar(int speed)
    {
        if(KEYDOWN(VK_LEFT))
        {
            if(m_Bar.rect.left - speed < m_wndRect.left)
                return;
            m_Bar.rect.left  -= speed;
            m_Bar.rect.right -= speed;
        }
        if(KEYDOWN(VK_RIGHT))
        {
            if(m_Bar.rect.right + speed > m_wndRect.right)
                return;
            m_Bar.rect.left  += speed;
            m_Bar.rect.right += speed;
        }
    }

    //main.cpp文件

    #include "header.h"
    #include "Game.h"
    
    CGame* g_pGame;
    //windows 的回调函数
    long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM    lParam)
    {
        switch(message)
        {
        case WM_DESTROY:
            PostQuitMessage(0);    //向操作系统传递退出的消息,只有当窗口销毁之后,WM_QUIT才能生效结束这个进程
        return 0;
    
        case WM_KEYDOWN:
            switch(wParam)
            {
                case VK_ESCAPE:
                PostMessage(hWnd, WM_CLOSE, 0, 0);    //向操作系统传递关闭窗口消息,WM_CLOSE会触发WM_DESTROY消息
                break;
            }
            break;
        }
    
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    
    int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)    //缩放,如按最小化时,都由这个控制
    {
        MSG msg;    //定义一个消息的对象
        HWND hWnd;    //窗口句柄
        WNDCLASS wc;        //定义窗口类
    
        //创建窗口类
        wc.style = CS_HREDRAW | CS_VREDRAW;    //支持水平和垂直重绘
        wc.lpfnWndProc = WindowProc;        //相应的消息处理函数
        wc.cbClsExtra = 0;                //附加内存空间
        wc.cbWndExtra = 0;                //附加内存空间
        wc.hInstance = hInstance;            //窗口的实例句柄
        wc.hIcon = NULL;                    //窗口的小图标
        wc.hCursor = NULL;                            //窗口的鼠标形状
        wc.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);//背景颜色
        wc.lpszMenuName = NULL;                        //窗口菜单
        wc.lpszClassName = L"createwindows";            //窗口名称
    
        RegisterClass(&wc);    //注册窗口句柄
        
        hWnd = CreateWindowEx(WS_EX_TOPMOST, L"createwindows", L"Create Window Title", WS_OVERLAPPEDWINDOW, 0,    0, 400, 300, NULL, NULL, hInstance,     NULL);            
        
        if(!hWnd)        //判断窗口是否建立成功
        {
            MessageBox(NULL, L"窗口建立失败!", L"error", NULL);
            return FALSE;
        }
    
        g_pGame = new CGame(hWnd);
    
        ShowWindow(hWnd, nCmdShow);        //显示窗口
        UpdateWindow(hWnd);                //更新窗口,默认调用了回调函数
        
        while(true)
        {
            //接受系统消息(&msg 为 MSG 类型的信息结构体,NULL 窗口句柄,0, 0 表示
            //接受所有的窗口信息)
            if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
            {
                if(msg.message == WM_QUIT)
                    break;
                TranslateMessage(&msg);        //转化信息
                DispatchMessage(&msg);        //分配信息到相应的消息处理
            }
            else
            {
                g_pGame->Render();
                Sleep(10);
            }
        }
        return 1;
    }
  • 相关阅读:
    电容
    51单片机
    三极管
    Scala 面向对象(八):特质(接口) 一
    Scala 面向对象(七):静态属性和静态方法
    Scala 面向对象(六):面向对象的特征二:继承 (一)
    Scala 面向对象(五):面向对象的特征一:封装性
    Scala 面向对象(四):import
    Scala 面向对象(三):package 包 (二)
    Scala 面向对象(二):package 包 (一) 入门
  • 原文地址:https://www.cnblogs.com/WinonaJia/p/8670892.html
Copyright © 2011-2022 走看看