C语言实现刮刮乐效果是示例代码

 更新时间:2023年01月11日 08:46:04   作者:编程小鱼六六六  
这篇文章主要为大家详细介绍了如何C语言模拟实现刮刮乐的效果,只要按下鼠标左键并移动就可以刮开刮卡层,感兴趣的小伙伴可以跟随小编一起学习一下

程序简介

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

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

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

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

首先,背景图就是普通的 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);            // 将背景图合并到覆盖层中
}

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

程序执行效果

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

完整源代码

 
//
// 程序名称:C语言刮刮乐(掩码图的范例)
// 编译环境: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语言进度条的实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • C语言实现一个通讯录

    C语言实现一个通讯录

    这篇文章主要为大家详细介绍了用C语言实现一个通讯录,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • 数组指针、指针数组以及二位数组的深入解析

    数组指针、指针数组以及二位数组的深入解析

    下面来讲讲多维数组与指针的关系。与普通数组一样,使用多维数组时,实际上将其自动转换为指向该数组第一个元素的指针
    2013-09-09
  • C++ 自定义控件的移植问题

    C++ 自定义控件的移植问题

    这篇文章主要介绍了C++ 自定义控件的移植问题,十分的简单实用,有需要的小伙伴可以参考下。
    2015-06-06
  • c++如何分割字符串示例代码

    c++如何分割字符串示例代码

    因为c++字符串没有split函数,所以字符串分割单词的时候必须自己手写,也相当于自己实现一个split函数吧!下面跟小编一起来看看如何实现这个功能。
    2016-08-08
  • C/C++中输入多组数据的方法

    C/C++中输入多组数据的方法

    这篇文章主要为大家详细介绍了C/C++中输入多组数据的三种方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • linux中查询dns示例

    linux中查询dns示例

    这篇文章主要介绍了linux中查询dns示例,需要的朋友可以参考下
    2014-04-04
  • Qt股票组件之自选股列表拖拽、右键常用菜单功能的实现

    Qt股票组件之自选股列表拖拽、右键常用菜单功能的实现

    这篇文章主要介绍了Qt股票组件之自选股列表拖拽、右键常用菜单功能的实现方法,本文通过实例文字相结合的形式给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-07-07
  • C语言结构体成员赋值的深拷贝与浅拷贝详解

    C语言结构体成员赋值的深拷贝与浅拷贝详解

    C语言中的浅拷贝是指在拷贝过程中,对于指针型成员变量只拷贝指针本身,而不拷贝指针所指向的目标,它按字节复制的。深拷贝除了拷贝其成员本身的值之外,还拷贝成员指向的动态内存区域内容。本文将通过示例和大家详细说说C语言的深拷贝与浅拷贝,希望对你有所帮助
    2022-09-09
  • Qt 实现钢笔画线效果示例及详细原理

    Qt 实现钢笔画线效果示例及详细原理

    这篇文章主要介绍了Qt 实现钢笔画线效果示例及详细原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04

最新评论