C/C++实现刮刮乐-刮奖区,刮出一套房

Posted C语言编程俱乐部

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C/C++实现刮刮乐-刮奖区,刮出一套房相关的知识,希望对你有一定的参考价值。

程序简介

    这个程序模拟了刮刮乐的刮卡操作,按下鼠标左键并移动可以刮开刮卡层。

    刮卡操作是通过掩码图实现的,一张隐藏的待刮开背景图,一张掩码图。

    刮卡的时候,是在黑色的掩码图上画线,显示的时候,通过掩码图将背景图显示出来。

程序效果展示和完整源码都在后面~

现在具体说一下显示方式:

    先贴完整的三元光栅操作码:EasyX 文档 - 三元光栅操作

    首先,背景图就是普通的 IMAGE 对象,不做任何处理。

    其次,掩码图中,未刮开区域对应的是黑色,已刮开区域对应的是白色。

显示的步骤:

1. 将背景图中未刮开的区域置为黑色:

    操作目标(D):背景图

    操作源(S):掩码图

    操作:背景图 AND 掩码图

    ⇒ 操作目标 AND 操作源 ⇒ D a S ⇒ DSa(后缀表达式),可以在三元光栅操作码中找到 DSa 对应的操作码是 008800C6(SRCAND)。

2. 将覆盖层中已刮开的区域置为黑色:

    操作目标(D):覆盖层

    操作源(S):掩码图

    操作:覆盖层 AND (NOT 掩码图)

    ⇒ 操作目标 AND (NOT 操作源) ⇒ D a (n S) ⇒ DSna(后缀表达式),可以在三元光栅操作码中找到 DSna 对应的操作码是 00220326。

3. 将背景图合并到覆盖层中,就是将前两步的 IMAGE 图像进行 OR 操作合并:

    操作目标(D):覆盖层

    操作源(S):背景图

    操作:覆盖层 OR 背景图

    ⇒ 操作目标 OR 操作源 ⇒ D o S ⇒ DSo(后缀表达式),可以在三元光栅操作码中找到 DSo 对应的操作码是 00EE0086(SRCPAINT)。

———————————————————

以上步骤,就是显示刮卡效果的函数的原理:

// 显示刮卡效果

void Show()



    IMAGE tmp = imgContent;

    SetWorkingImage(&tmp);

    putimage(0, 0, &imgMask, SRCAND); // 将背景图中未刮开的区域置为黑色

    SetWorkingImage();

    putimage(offsetx, offsety, &imgMask, 0x00220326); // 将覆盖层中已刮开的区域置为黑色

    putimage(offsetx, offsety, &tmp, SRCPAINT); // 将背景图合并到覆盖层中

同时,该程序还使用了用图像填充区域的技术,以及输出字符符号的技术。

程序执行效果

友情提示:更换一下刮奖区的文字,可能是一件有趣的事情。

完整源代码



// 程序名称:刮刮乐(掩码图的范例)

// 编译环境:Visual C++ 6.0 ~ 2019,EasyX_20220116

#include <graphics.h>

const int offsetx = 170; // 刮奖区的偏移 x 坐标

const int offsety = 260; // 刮奖区的偏移 y 坐标

IMAGE imgContent(300, 100); // 刮开后的内容

IMAGE imgMask(300, 100); // 已刮部分的掩码层

// 绘制刮刮卡

void DrawCard()



    // 白色背景

    setbkcolor(0xf0f0f0);

    cleardevice();

    // 设置刮刮卡填充单元

    IMAGE unit(32, 32);

    SetWorkingImage(&unit); // 设置绘图设备为 unit 对象

    setbkcolor(0x1a3bf0); // 设置背景色

    cleardevice();

    settextstyle(20, 0, _T("Webdings"), 0, 0, 400, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH); // 设置图标字体

    settextcolor(0x152fe5);

    outtextxy(0, 16, 0x59); // 输出两个心

    outtextxy(16, 0, 0x59);

    settextcolor(0x284ff5);

    outtextxy(0, 0, 0x73); // 输出两个问号

    outtextxy(16, 16, 0x73);

    SetWorkingImage();

    // 用 IMAGE 对象填充矩形区域

    setfillstyle(BS_DIBPATTERN, NULL, &unit); // 设置填充模式

    solidrectangle(150, 30, 490, 450); // 画填充矩形

    TCHAR s[] = _T("刮刮乐");

    settextstyle(80, 0, _T("黑体"), 0, 0, 400, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH);

    setbkmode(TRANSPARENT);

    settextcolor(0x034089);

    outtextxy(offsetx + (300 - textwidth(s)) / 2 + 5, 105, s);

    settextcolor(0x10c2fe);

    outtextxy(offsetx + (300 - textwidth(s)) / 2, 100, s);

    // 设置覆盖层填充单元

    IMAGE unit2(80, 50);

    SetWorkingImage(&unit2); // 设置绘图设备为 unit 对象

    setbkcolor(LIGHTGRAY);

    cleardevice();

    settextstyle(20, 0, _T("黑体"), 150, 150, 400, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH);

    settextcolor(0x606060);

    outtextxy(10, 20, _T("刮奖区"));

    SetWorkingImage();

    // 用 IMAGE 对象填充矩形区域

    setfillstyle(BS_DIBPATTERN, NULL, &unit2); // 设置填充模式

    solidrectangle(offsetx, offsety, offsetx + 300, offsety + 100); // 画填充矩形



// 初始化刮奖区内容

void InitContent()



    // 绘制刮奖区内容

    SetWorkingImage(&imgContent);

    setbkcolor(0x05d5ff);

    cleardevice();

    settextcolor(0x0024b8);

    TCHAR s1[] = _T("EasyX");

    TCHAR s2[] = _T("点亮你的创造力");

    settextstyle(40, 0, _T("黑体"), 0, 0, 900, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH);

    outtextxy((300 - textwidth(s1)) / 2, 10, s1);

    outtextxy((300 - textwidth(s2)) / 2, 50, s2);

    // 绘制刮卡的掩码图

    SetWorkingImage(&imgMask);

    setbkcolor(BLACK);

    cleardevice();

    setlinestyle(PS_SOLID, 10); // 设置刮卡操作的粗细

    SetWorkingImage();



// 实现刮卡操作

void Scrape(int x1, int y1, int x2, int y2)



    SetWorkingImage(&imgMask);

    line(x1, y1, x2, y2);



// 显示刮卡效果

void Show()



    IMAGE tmp = imgContent;

    SetWorkingImage(&tmp);

    putimage(0, 0, &imgMask, SRCAND); // 将背景图中未刮开的区域置为黑色

    SetWorkingImage();

    putimage(offsetx, offsety, &imgMask, 0x00220326); // 将覆盖层中已刮开的区域置为黑色

    putimage(offsetx, offsety, &tmp, SRCPAINT); // 将背景图合并到覆盖层中





// 主函数

int main()



    initgraph(640, 480); // 初始化图形窗口

    DrawCard(); // 绘制刮刮乐卡片

    InitContent(); // 初始化刮奖区内容

    // 获取鼠标消息,实现刮卡操作

    ExMessage msg;

    int x, y, oldx, oldy;

    bool scrape = false;

    while(true)

    

        msg = getmessage(EM_MOUSE);

        switch(msg.message)

        

            case WM_LBUTTONDOWN:

                scrape = true;

                x = oldx = msg.x - offsetx;

                y = oldy = msg.y - offsety;

                Scrape(oldx, oldy, x, y);

                break;

            case WM_LBUTTONUP:

                scrape = false;

                break;

        case WM_MOUSEMOVE:

                if (scrape)

                

                    oldx = x;

                    oldy = y;

                    x = msg.x - offsetx;

                    y = msg.y - offsety;

                    Scrape(oldx, oldy, x, y);

                

                break;

            

            // 显示当前结果

            Show();

        

        return 0;

——————————————

因为C/C++很难,所以C/C++人才严重稀缺,这也是为什么C/C++软件工程师的薪资水平持续递增的原因。

不管你是转行也好,初学也罢,进阶也可,如果你想学编程~

【值得关注】我的 编程学习交流俱乐部【点击进入】

 

以上是关于C/C++实现刮刮乐-刮奖区,刮出一套房的主要内容,如果未能解决你的问题,请参考以下文章

canvas实现刮刮乐

Android刮刮乐效果-proterDuffXfermode

vue 刮刮乐功能实现

Unity刮刮乐效果(擦除图片像素值)

HarmonyOS 基于JSAPI实现刮刮乐效果

实现刮刮乐的效果