C語言實(shí)現(xiàn)刮刮樂效果是示例代碼
程序簡介
這個(gè)程序模擬了刮刮樂的刮卡操作,按下鼠標(biāo)左鍵并移動(dòng)可以刮開刮卡層。
刮卡操作是通過掩碼圖實(shí)現(xiàn)的,一張隱藏的待刮開背景圖,一張掩碼圖。
刮卡的時(shí)候,是在黑色的掩碼圖上畫線,顯示的時(shí)候,通過掩碼圖將背景圖顯示出來。
現(xiàn)在具體說一下顯示方式:
首先,背景圖就是普通的 IMAGE 對象,不做任何處理。
其次,掩碼圖中,未刮開區(qū)域?qū)?yīng)的是黑色,已刮開區(qū)域?qū)?yīng)的是白色。
顯示的步驟:
1. 將背景圖中未刮開的區(qū)域置為黑色:
操作目標(biāo)(D):背景圖
操作源(S):掩碼圖
操作:背景圖 AND 掩碼圖
⇒ 操作目標(biāo) AND 操作源 ⇒ D a S ⇒ DSa(后綴表達(dá)式),可以在三元光柵操作碼中找到 DSa 對應(yīng)的操作碼是 008800C6(SRCAND)。
2. 將覆蓋層中已刮開的區(qū)域置為黑色:
操作目標(biāo)(D):覆蓋層
操作源(S):掩碼圖
操作:覆蓋層 AND (NOT 掩碼圖)
⇒ 操作目標(biāo) AND (NOT 操作源) ⇒ D a (n S) ⇒ DSna(后綴表達(dá)式),可以在三元光柵操作碼中找到 DSna 對應(yīng)的操作碼是 00220326。
3. 將背景圖合并到覆蓋層中,就是將前兩步的 IMAGE 圖像進(jìn)行 OR 操作合并:
操作目標(biāo)(D):覆蓋層
操作源(S):背景圖
操作:覆蓋層 OR 背景圖
⇒ 操作目標(biāo) OR 操作源 ⇒ D o S ⇒ DSo(后綴表達(dá)式),可以在三元光柵操作碼中找到 DSo 對應(yīng)的操作碼是 00EE0086(SRCPAINT)。
以上步驟,就是顯示刮卡效果的函數(shù)的原理:
// 顯示刮卡效果
void Show()
{
IMAGE tmp = imgContent;
SetWorkingImage(&tmp);
putimage(0, 0, &imgMask, SRCAND); // 將背景圖中未刮開的區(qū)域置為黑色
SetWorkingImage();
putimage(offsetx, offsety, &imgMask, 0x00220326); // 將覆蓋層中已刮開的區(qū)域置為黑色
putimage(offsetx, offsety, &tmp, SRCPAINT); // 將背景圖合并到覆蓋層中
}
同時(shí),該程序還使用了用圖像填充區(qū)域的技術(shù),以及輸出字符符號(hào)的技術(shù)。
程序執(zhí)行效果

友情提示:更換一下刮獎(jiǎng)區(qū)的文字,可能是一件有趣的事情。
完整源代碼
//
// 程序名稱:C語言刮刮樂(掩碼圖的范例)
// 編譯環(huán)境:Visual C++ 6.0 ~ 2019,EasyX_20220116
//
#include <graphics.h>
const int offsetx = 170; // 刮獎(jiǎng)區(qū)的偏移 x 坐標(biāo)
const int offsety = 260; // 刮獎(jiǎng)區(qū)的偏移 y 坐標(biāo)
IMAGE imgContent(300, 100); // 刮開后的內(nèi)容
IMAGE imgMask(300, 100); // 已刮部分的掩碼層
// 繪制刮刮卡
void DrawCard()
{
// 白色背景
setbkcolor(0xf0f0f0);
cleardevice();
// 設(shè)置刮刮卡填充單元
IMAGE unit(32, 32);
SetWorkingImage(&unit); // 設(shè)置繪圖設(shè)備為 unit 對象
setbkcolor(0x1a3bf0); // 設(shè)置背景色
cleardevice();
settextstyle(20, 0, _T("Webdings"), 0, 0, 400, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH); // 設(shè)置圖標(biāo)字體
settextcolor(0x152fe5);
outtextxy(0, 16, 0x59); // 輸出兩個(gè)心
outtextxy(16, 0, 0x59);
settextcolor(0x284ff5);
outtextxy(0, 0, 0x73); // 輸出兩個(gè)問號(hào)
outtextxy(16, 16, 0x73);
SetWorkingImage();
// 用 IMAGE 對象填充矩形區(qū)域
setfillstyle(BS_DIBPATTERN, NULL, &unit); // 設(shè)置填充模式
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);
// 設(shè)置覆蓋層填充單元
IMAGE unit2(80, 50);
SetWorkingImage(&unit2); // 設(shè)置繪圖設(shè)備為 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("刮獎(jiǎng)區(qū)"));
SetWorkingImage();
// 用 IMAGE 對象填充矩形區(qū)域
setfillstyle(BS_DIBPATTERN, NULL, &unit2); // 設(shè)置填充模式
solidrectangle(offsetx, offsety, offsetx + 300, offsety + 100); // 畫填充矩形
}
// 初始化刮獎(jiǎng)區(qū)內(nèi)容
void InitContent()
{
// 繪制刮獎(jiǎng)區(qū)內(nèi)容
SetWorkingImage(&imgContent);
setbkcolor(0x05d5ff);
cleardevice();
settextcolor(0x0024b8);
TCHAR s1[] = _T("EasyX");
TCHAR s2[] = _T("點(diǎn)亮你的創(chuàng)造力");
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); // 設(shè)置刮卡操作的粗細(xì)
SetWorkingImage();
}
// 實(shí)現(xiàn)刮卡操作
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); // 將背景圖中未刮開的區(qū)域置為黑色
SetWorkingImage();
putimage(offsetx, offsety, &imgMask, 0x00220326); // 將覆蓋層中已刮開的區(qū)域置為黑色
putimage(offsetx, offsety, &tmp, SRCPAINT); // 將背景圖合并到覆蓋層中
}
// 主函數(shù)
int main()
{
initgraph(640, 480); // 初始化圖形窗口
DrawCard(); // 繪制刮刮樂卡片
InitContent(); // 初始化刮獎(jiǎng)區(qū)內(nèi)容
// 獲取鼠標(biāo)消息,實(shí)現(xiàn)刮卡操作
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;
}
// 顯示當(dāng)前結(jié)果
Show();
}
return 0;
}到此這篇關(guān)于C語言實(shí)現(xiàn)刮刮樂效果是示例代碼的文章就介紹到這了,更多相關(guān)C語言刮刮樂內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實(shí)現(xiàn)修改函數(shù)代碼HOOK的封裝方法
這篇文章主要介紹了C++實(shí)現(xiàn)修改函數(shù)代碼HOOK的封裝方法,有助于深入了解C++的HOOK原理,需要的朋友可以參考下2014-10-10
C語言實(shí)現(xiàn)撲克牌計(jì)算24點(diǎn)
這篇文章主要為大家詳細(xì)介紹了C語言如何實(shí)現(xiàn)撲克牌計(jì)算24點(diǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10
C語言運(yùn)算符及其優(yōu)先級(jí)匯總表口訣
由于C語言的運(yùn)算符優(yōu)先級(jí)與C++的不完全一樣(主要是增加了幾個(gè)運(yùn)算符),所以這個(gè)口訣不能完全實(shí)用于C++.但是應(yīng)該能夠兼容,大家可以比較一下他們的區(qū)別應(yīng)該就能夠很快掌握C++的優(yōu)先級(jí)的2013-07-07
C語言實(shí)現(xiàn)掃雷小游戲(適合初學(xué)者)
這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)掃雷小游戲,適合初學(xué)者練習(xí),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03

