小言_互联网的博客

C语言刮刮乐(掩码图的范例)

442人阅读  评论(0)

程序简介

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

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

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

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

首先,背景图就是普通的 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)。

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


  
  1. // 显示刮卡效果
  2. void Show()
  3. {
  4. IMAGE tmp = imgContent;
  5. SetWorkingImage(&tmp);
  6. putimage( 0, 0, &imgMask, SRCAND); // 将背景图中未刮开的区域置为黑色
  7. SetWorkingImage();
  8. putimage(offsetx, offsety, &imgMask, 0x00220326); // 将覆盖层中已刮开的区域置为黑色
  9. putimage(offsetx, offsety, &tmp, SRCPAINT); // 将背景图合并到覆盖层中
  10. }

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

程序执行效果: 

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

完整源代码:


  
  1. //
  2. // 程序名称:C语言刮刮乐(掩码图的范例)
  3. // 编译环境:Visual C++ 6.0 ~ 2019,EasyX_20220116
  4. //
  5. #include <graphics.h>
  6. const int offsetx = 170; // 刮奖区的偏移 x 坐标
  7. const int offsety = 260; // 刮奖区的偏移 y 坐标
  8. IMAGE imgContent(300, 100); // 刮开后的内容
  9. IMAGE imgMask(300, 100); // 已刮部分的掩码层
  10. // 绘制刮刮卡
  11. void DrawCard()
  12. {
  13. // 白色背景
  14. setbkcolor( 0xf0f0f0);
  15. cleardevice();
  16. // 设置刮刮卡填充单元
  17. IMAGE unit(32, 32);
  18. SetWorkingImage(&unit); // 设置绘图设备为 unit 对象
  19. setbkcolor( 0x1a3bf0); // 设置背景色
  20. cleardevice();
  21. settextstyle( 20, 0, _T( "Webdings"), 0, 0, 400, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH); // 设置图标字体
  22. settextcolor( 0x152fe5);
  23. outtextxy( 0, 16, 0x59); // 输出两个心
  24. outtextxy( 16, 0, 0x59);
  25. settextcolor( 0x284ff5);
  26. outtextxy( 0, 0, 0x73); // 输出两个问号
  27. outtextxy( 16, 16, 0x73);
  28. SetWorkingImage();
  29. // 用 IMAGE 对象填充矩形区域
  30. setfillstyle(BS_DIBPATTERN, NULL, &unit); // 设置填充模式
  31. solidrectangle( 150, 30, 490, 450); // 画填充矩形
  32. TCHAR s[] = _T( "刮刮乐");
  33. settextstyle( 80, 0, _T( "黑体"), 0, 0, 400, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH);
  34. setbkmode(TRANSPARENT);
  35. settextcolor( 0x034089);
  36. outtextxy(offsetx + ( 300 - textwidth(s)) / 2 + 5, 105, s);
  37. settextcolor( 0x10c2fe);
  38. outtextxy(offsetx + ( 300 - textwidth(s)) / 2, 100, s);
  39. // 设置覆盖层填充单元
  40. IMAGE unit2(80, 50);
  41. SetWorkingImage(&unit2); // 设置绘图设备为 unit 对象
  42. setbkcolor(LIGHTGRAY);
  43. cleardevice();
  44. settextstyle( 20, 0, _T( "黑体"), 150, 150, 400, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH);
  45. settextcolor( 0x606060);
  46. outtextxy( 10, 20, _T( "刮奖区"));
  47. SetWorkingImage();
  48. // 用 IMAGE 对象填充矩形区域
  49. setfillstyle(BS_DIBPATTERN, NULL, &unit2); // 设置填充模式
  50. solidrectangle(offsetx, offsety, offsetx + 300, offsety + 100); // 画填充矩形
  51. }
  52. // 初始化刮奖区内容
  53. void InitContent()
  54. {
  55. // 绘制刮奖区内容
  56. SetWorkingImage(&imgContent);
  57. setbkcolor( 0x05d5ff);
  58. cleardevice();
  59. settextcolor( 0x0024b8);
  60. TCHAR s1[] = _T( "EasyX");
  61. TCHAR s2[] = _T( "点亮你的创造力");
  62. settextstyle( 40, 0, _T( "黑体"), 0, 0, 900, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH);
  63. outtextxy(( 300 - textwidth(s1)) / 2, 10, s1);
  64. outtextxy(( 300 - textwidth(s2)) / 2, 50, s2);
  65. // 绘制刮卡的掩码图
  66. SetWorkingImage(&imgMask);
  67. setbkcolor(BLACK);
  68. cleardevice();
  69. setlinestyle(PS_SOLID, 10); // 设置刮卡操作的粗细
  70. SetWorkingImage();
  71. }
  72. // 实现刮卡操作
  73. void Scrape(int x1, int y1, int x2, int y2)
  74. {
  75. SetWorkingImage(&imgMask);
  76. line(x1, y1, x2, y2);
  77. }
  78. // 显示刮卡效果
  79. void Show()
  80. {
  81. IMAGE tmp = imgContent;
  82. SetWorkingImage(&tmp);
  83. putimage( 0, 0, &imgMask, SRCAND); // 将背景图中未刮开的区域置为黑色
  84. SetWorkingImage();
  85. putimage(offsetx, offsety, &imgMask, 0x00220326); // 将覆盖层中已刮开的区域置为黑色
  86. putimage(offsetx, offsety, &tmp, SRCPAINT); // 将背景图合并到覆盖层中
  87. }
  88. // 主函数
  89. int main()
  90. {
  91. initgraph( 640, 480); // 初始化图形窗口
  92. DrawCard(); // 绘制刮刮乐卡片
  93. InitContent(); // 初始化刮奖区内容
  94. // 获取鼠标消息,实现刮卡操作
  95. ExMessage msg;
  96. int x, y, oldx, oldy;
  97. bool scrape = false;
  98. while( true)
  99. {
  100. msg = getmessage(EM_MOUSE);
  101. switch(msg.message)
  102. {
  103. case WM_LBUTTONDOWN:
  104. scrape = true;
  105. x = oldx = msg.x - offsetx;
  106. y = oldy = msg.y - offsety;
  107. Scrape(oldx, oldy, x, y);
  108. break;
  109. case WM_LBUTTONUP:
  110. scrape = false;
  111. break;
  112. case WM_MOUSEMOVE:
  113. if (scrape)
  114. {
  115. oldx = x;
  116. oldy = y;
  117. x = msg.x - offsetx;
  118. y = msg.y - offsety;
  119. Scrape(oldx, oldy, x, y);
  120. }
  121. break;
  122. }
  123. // 显示当前结果
  124. Show();
  125. }
  126. return 0;
  127. }

小鱼快来啊的个人空间-小鱼快来啊个人主页-哔哩哔哩视频哔哩哔哩小鱼快来啊的个人空间,提供小鱼快来啊分享的视频、音频、文章、动态、收藏等内容,关注小鱼快来啊账号,第一时间了解UP注动态。编程学习群:725022484 每天分享一个编程小游戏~C/C++游戏源码素材及各种安装包, 私信不常看!https://space.bilibili.com/1827181878?spm_id_from=333.788.0.0


转载:https://blog.csdn.net/yx5666/article/details/128631621
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场