FlipGame-点灯游戏

Posted that-boy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FlipGame-点灯游戏相关的知识,希望对你有一定的参考价值。

FlipGame有人也叫它点灯游戏,不过叫啥不重要,随他去吧。

FlipGame8X8-GitHub

Tip: 工程中的图片是嵌入到资源中的

技术图片

/******************************
 * FlipGame8x8
 * 编译环境:VS 2019
 * 作者:that boy,2018/12/22
 * 最后修改:2020/2/14
 ******************************/

#include "Bulb.h"

int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
{
    IMAGE IMG;
    MOUSEMSG Msg = { 0 };

    loadimage(&IMG, TEXT("IMAGE"), TEXT("BK"), 640, 640);

    LED8::SetBright(IMG);
    LED8::SetBackground(BLACK);
    LED8::SetDark(DARKGRAY);
    LED8::Create();

    // 按下鼠标中键关闭或者使用关闭按钮
    for (; Msg.uMsg != WM_MBUTTONUP;)
    {
        Msg = { NULL };
        while (MouseHit())
        {
            Msg = GetMouseMsg();

            switch (Msg.uMsg)
            {
            case WM_LBUTTONDOWN:
            {
                auto x = (Msg.y - LED8::GapHeight) / (LED8::GapHeight + LED8::BulbHeight);
                auto y = (Msg.x - LED8::GapWidth) / (LED8::GapWidth + LED8::BulbWidth);
                LED8::Board ^= (DWORD64)1 << ((x << 3) | y);
                if (x > 0)
                    LED8::Board ^= (DWORD64)1 << (((x - 1) << 3) | y);
                if (x < 7)
                    LED8::Board ^= (DWORD64)1 << (((x + 1) << 3) | y);
                if (y > 0)
                    LED8::Board ^= (DWORD64)1 << ((x << 3) | (y - 1));
                if (y < 7)
                    LED8::Board ^= (DWORD64)1 << ((x << 3) | (y + 1));
                break;
            }
            default:
                break;
            }
        }
        Sleep(10);
        LED8::Update();
    }
    LED8::Destory();
}

Bulb.h

#pragma once
#ifndef BULB_H
#define BULB_H

#include <EasyX.h>

class LED8
{
private:
    static int _WndWidth;   // 窗口宽度
    static int _WndHeight;  // 窗口高度

    static HWND _Hwnd;      // 句柄
    static DWORD* _Buff;    // 显存
    static HDC _Hdc;        // HDC

    static IMAGE BackgroundImage;
    static IMAGE BrightImage;
    static IMAGE DarkImage;

    static IMAGE ActiveBackgroundImage;
    static IMAGE BrightImagePiece[64];
    static IMAGE DarkImagePiece[64];
public:
    LED8() = delete;

    // 常量引用,供访问使用,避免函数调用

    static HWND const& Hwnd;    // 句柄
    static DWORD* const& Buff;  // 显存
    static HDC const& Hdc;      // HDC

    static int const& WndWidth;
    static int const& WndHeight;

    // 可直接设置变量
    static int BulbWidth;   // 灯泡宽度
    static int BulbHeight;  // 灯泡高度
    static int GapWidth;    // 间隙宽度
    static int GapHeight;   // 间隙高度

    static DWORD64 Board;   // 画板

    static const IMAGE* SplitImage(const IMAGE&, IMAGE*, size_t, size_t, size_t = 0, size_t = 0, bool = true);

    static const IMAGE& SetBright(COLORREF);
    static const IMAGE& SetDark(COLORREF);
    static const IMAGE& SetBackground(COLORREF);

    static const IMAGE& SetBright(const IMAGE&);
    static const IMAGE& SetDark(const IMAGE&);
    static const IMAGE& SetBackground(const IMAGE&);

    static int SetBulbSize(int, int);   // 设置灯泡大小
    static int GetBulbSize(int&, int&); // 获得灯泡大小
    static int SetGapSize(int, int);    // 设置间隙大小
    static int GetGapSize(int&, int&);  // 获得间隙大小

    static int ResizeWndSize(int, int); // 调整窗口大小
    static int AutoWndSize();           // 自适应窗口大小

    static HWND Create(DWORD64 = 0);
    static int Destory();
    static DWORD64 Write(DWORD64);
    static DWORD64 Write(int, int);
    static DWORD64 Read(DWORD64&);
    static int Update(bool = true);
};

#endif // !

Bulb.cpp

/*************************************************
 * FlipGame8x8
 * 编译环境:VC++ 2017
 * 作者:that boy,2018/12/22
 * 最后修改:2018/12/27
 * E-mail:zhuguangfeng.thatboy@gmail.com
 *************************************************/

#include "Bulb.h"

HWND const& LED8::Hwnd = LED8::_Hwnd;   // 句柄
DWORD* const& LED8::Buff = LED8::_Buff; // 显存
HDC const& LED8::Hdc = LED8::_Hdc;      // HDC

int const& LED8::WndWidth = LED8::_WndWidth;
int const& LED8::WndHeight = LED8::_WndHeight;

int LED8::BulbWidth = 70;
int LED8::BulbHeight = 70;
int LED8::GapWidth = 10;
int LED8::GapHeight = 10;

IMAGE LED8::BackgroundImage;
IMAGE LED8::BrightImage;
IMAGE LED8::DarkImage;

IMAGE LED8::ActiveBackgroundImage;
IMAGE LED8::BrightImagePiece[64];
IMAGE LED8::DarkImagePiece[64];

HWND LED8::_Hwnd;       // 句柄
DWORD64 LED8::Board;    // 画板
DWORD* LED8::_Buff;     // 显存
HDC LED8::_Hdc;         // HDC
int LED8::_WndWidth;
int LED8::_WndHeight;

const IMAGE* LED8::SplitImage(const IMAGE& Src, IMAGE* Dst, size_t NumX, size_t NumY, size_t Width, size_t Height, bool AutoSize)
{
    if (Width == 0 || Height == 0 || (AutoSize && Width * NumX > (size_t)Src.getwidth() && Height* NumY > (size_t)Src.getheight()))
    {
        Width = Src.getwidth() / NumX;
        Height = Src.getheight() / NumY;
    }
    SetWorkingImage((IMAGE*)(&Src));
    for (size_t i = 0; i < NumX * NumY; ++i)
        getimage(Dst + i, (i % NumX) * Width, (i / NumX) * Height, Width, Height);
    SetWorkingImage();
    return Dst;
}

const IMAGE& LED8::SetBright(COLORREF col)
{
    BrightImage.Resize(BulbWidth * 8, BulbHeight * 8);
    SetWorkingImage(&BrightImage);
    setbkcolor(col);
    cleardevice();
    SetWorkingImage();
    SplitImage(BrightImage, BrightImagePiece, 8, 8, BulbWidth, BulbHeight);
    return BrightImage;
}

const IMAGE& LED8::SetDark(COLORREF col)
{
    DarkImage.Resize(BulbWidth * 8, BulbHeight * 8);
    SetWorkingImage(&DarkImage);
    setbkcolor(col);
    cleardevice();
    SetWorkingImage();
    SplitImage(DarkImage, DarkImagePiece, 8, 8, BulbWidth, BulbHeight);
    return DarkImage;
}

const IMAGE& LED8::SetBackground(COLORREF col)
{
    BackgroundImage.Resize(_WndWidth, _WndHeight);
    SetWorkingImage(&BackgroundImage);
    setbkcolor(col);
    cleardevice();
    SetWorkingImage();
    ActiveBackgroundImage = BackgroundImage;
    return BackgroundImage;
}

const IMAGE& LED8::SetBright(const IMAGE& img)
{
    BrightImage = img;
    SplitImage(BrightImage, BrightImagePiece, 8, 8, BulbWidth, BulbHeight);
    return BrightImage;
}

const IMAGE& LED8::SetDark(const IMAGE& img)
{
    DarkImage = img;
    SplitImage(DarkImage, DarkImagePiece, 8, 8, BulbWidth, BulbHeight);
    return DarkImage;
}

const IMAGE& LED8::SetBackground(const IMAGE& img)
{
    BackgroundImage = img;
    ActiveBackgroundImage = img;
    return BackgroundImage;
}

int LED8::SetBulbSize(int bulbwidth, int bulbheight)
{
    return (BulbWidth = bulbwidth) * (BulbHeight = bulbheight);
}

int LED8::GetBulbSize(int& bulbwidth, int& bulbheight)
{
    return (bulbwidth = BulbWidth) * (bulbheight = BulbHeight);
}

int LED8::SetGapSize(int gapwidth, int gapheight)
{
    return (GapWidth = gapwidth) * (GapHeight = gapheight);
}

int LED8::GetGapSize(int& gapwidth, int& gapheight)
{
    return (gapwidth = GapWidth) * (gapheight = GapHeight);
}

int LED8::ResizeWndSize(int wndwidth, int wndheight)
{
    if (wndwidth <= 0 || wndheight <= 0)
        return -1;
    ::Resize(nullptr, wndwidth, wndheight);
    _WndWidth = getwidth();
    _WndHeight = getheight();
    _Hwnd = GetHWnd();
    _Hdc = GetImageHDC();
    _Buff = GetImageBuffer();
    return 0;
}

int LED8::AutoWndSize()
{
    _WndWidth = GapWidth + ((GapWidth + BulbWidth) << 3);
    _WndHeight = GapHeight + ((GapHeight + BulbHeight) << 3);
    ResizeWndSize(_WndWidth, _WndHeight);
    return 0;
}

HWND LED8::Create(DWORD64 inBoard)
{
    _WndWidth = GapWidth + ((GapWidth + BulbWidth) << 3);
    _WndHeight = GapHeight + ((GapHeight + BulbHeight) << 3);
    Board = inBoard;
    _Hwnd = initgraph(_WndWidth, _WndHeight);
    _Buff = GetImageBuffer();
    _Hdc = GetImageHDC();

    BeginBatchDraw();

    // // 设置无边框
    // ::SetWindowLong(_Hwnd, GWL_STYLE, GetWindowLong(_Hwnd, GWL_STYLE)&(~(WS_CAPTION | WS_SYSMENU | WS_SIZEBOX)));
    // // 设置透明属性
    // ::SetWindowLong(_Hwnd, GWL_EXSTYLE, (GetWindowLong(_Hwnd, GWL_EXSTYLE)&(~(WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME))) | WS_EX_LAYERED | WS_EX_TOOLWINDOW);
    // // 设置居中靠前
    // SetWindowPos(_Hwnd, HWND_TOPMOST, (GetSystemMetrics(SM_CXSCREEN) - getwidth()) / 2,
    //  (GetSystemMetrics(SM_CYSCREEN) - getheight()) / 2, getwidth(), getheight(), SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_DRAWFRAME);
    // // SetLayeredWindowAttributes(_Hwnd, BackgroundColor, 0, LWA_COLORKEY);
    cleardevice();

    return _Hwnd;
}

int LED8::Destory()
{
    EndBatchDraw();
    closegraph();
    return 0;
}

DWORD64 LED8::Write(DWORD64 inBoard)
{
    Board = inBoard;
    return 0;
}

DWORD64 LED8::Write(int x, int y)
{
    Board = (DWORD64)1 << ((y & 0B0000'0111 << 3) | (x & 0B0000'0111));
    return 0;
}

DWORD64 LED8::Read(DWORD64& outBoard)
{
    outBoard = Board;
    return 0;
}

int LED8::Update(bool bFlush)
{
    cleardevice();
    for (size_t i = 0; i < 64; i++)
    {
        putimage(GapWidth + (i & 0B111) * (GapWidth + BulbWidth), GapHeight + (i >> 3)* (GapHeight + BulbHeight), Board& (DWORD64)1 << i ? BrightImagePiece + i : DarkImagePiece + i);
    }
    if (bFlush)
        FlushBatchDraw();
    return 0;
}

以上是关于FlipGame-点灯游戏的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript案例:点灯游戏

C语言零基础项目:涂格子(点灯)游戏!详细思路+源码分享

手把手教你用MATLAB制作一款 [狗头翻牌子] 小游戏(点灯游戏)

手把手教你用MATLAB制作一款 [狗头翻牌子] 小游戏(点灯游戏)

从片段调用 Google Play 游戏服务

「游戏引擎 浅入浅出」4.3 片段着色器