從這期開始,文章參考了毛星雲老師的Windows遊戲編程之從零開始。並結合前面孫鑫老師講述的MFC編程做了一些小的程序示例。
Lesson11:GDI 2D編程基礎
GDI 2D編程是遊戲編程中的重要部分,在二維遊戲編程中應用廣泛。遊戲編程中一個重要環節是背景圖像、人物圖像的處理,絢麗的視覺衝擊可以提高玩家的體驗感。本文主要講解一些DGI 2D編程的基礎知識,包括創建程序啓動畫面、啓動音樂、播放背景音樂、窗口背景貼圖等。
1. 創建程序啓動畫面
這部分內容在前面講過,可以參考MFC——7.定製應用程序外觀:
http://blog.csdn.net/u010757264/article/details/50932180#t7
這裏需要說的一點是,如果我們想像酷我音樂一樣,每次啓動都有一個提示音,可以在void CWzdSplash::OnPaint()函數開始處添加下面一句代碼:
PlaySound(L"startmusic",NULL, SND_FILENAME | SND_ASYNC);
2. 背景音樂
在菜單資源中添加音樂菜單,並添加play和stop子菜單,通過切換兩個菜單按鈕實現音樂的播放和停止,子菜單ID號分別爲ID_MUSIC_PLAY和ID_MUSIC_STOP,然後通過類嚮導在view類裏添加命令響應函數。
爲了實現停止功能時檢測是否當前有音樂播放,我們添加一個bool型變量MusicRuning,初始化爲false,表示沒有音樂播放。
void CYuTaoView::OnMusicPlay()
{
//TODO: 在此添加命令處理程序代碼
//PlaySound(L"AIR- 夏影",NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);
MusicRuning= PlaySound(L"AIR - 夏影", NULL, SND_ASYNC);
}
void CYuTaoView::OnMusicStop()
{
//TODO: 在此添加命令處理程序代碼
if(MusicRuning&&IDYES == MessageBoxA(NULL, "是否結束播放","YuTao", MB_YESNO))
{
MusicRuning= !(PlaySound(NULL, NULL, SND_PURGE));
}
if(!MusicRuning)
MessageBox(L"當前無音樂播放");
}
3. 兩種方法貼圖
在菜單資源中添加背景菜單,並添加Background_1和Background_2子菜單,通過兩個子菜單按鈕實現背景貼圖,子菜單ID號分別爲ID_BACKGROUND1和ID_ BACKGROUND2,然後通過類嚮導在view類裏添加命令響應函數。
//方法一:按鈕點擊貼背景圖1
void CYuTaoView::OnBackground1()
{
//TODO: 在此添加命令處理程序代碼
CBitmapbitmap; //1創建位圖
bitmap.LoadBitmap(IDB_BACKGROUND1);
BITMAPbmp; //這裏爲了根據窗口大小顯示位圖,後面得到位圖的像素
bitmap.GetBitmap(&bmp);
CDCdcCompatible; //2創建兼容DC
dcCompatible.CreateCompatibleDC(GetDC());
dcCompatible.SelectObject(&bitmap); //3將位圖選到兼容DC中
CRectrect; //4將兼容DC中的位圖貼到當前DC中
GetClientRect(&rect);
//GetDC()->BitBlt(0,0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, SRCCOPY); //bitblt()是一比一顯示位圖
GetDC()->StretchBlt(0,0, rect.Width(), rect.Height(), &dcCompatible, 0, 0, bmp.bmWidth,bmp.bmHeight, SRCCOPY); //根據窗口大小顯示位圖
DeleteObject(bitmap); //清理工作
DeleteDC(dcCompatible);
}
//方法二:按鈕點擊貼背景圖2
void CYuTaoView::OnBackground2()
{
//TODO: 在此添加命令處理程序代碼
CClientDCg_hdc(this); //1創建位圖
CRectrect; //這裏是爲了得到屏幕矩形尺寸
GetClientRect(&rect);
HBITMAPbitmap = (HBITMAP)LoadImage(NULL, L"background2.bmp", IMAGE_BITMAP,rect.Width(), rect.Height(), LR_LOADFROMFILE);
HDCdcCompatible = CreateCompatibleDC(g_hdc); //2創建兼容DC
SelectObject(dcCompatible,bitmap); //3將位圖選到兼容DC中
BitBlt(g_hdc,0,0, rect.Width(), rect.Height(), dcCompatible, 0, 0, SRCCOPY); //4將兼容DC中的位圖貼到當前DC中
//StretchBlt(g_hdc,0, 0, rect.Width(), rect.Height(), dcCompatible, 0, 0, rect.Width(),rect.Height(), SRCCOPY);
//前面的代碼已經實現了貼圖工作,後面的代碼爲在一幅圖上再貼上一個人物圖像,可以將代碼註釋掉看看兩次的效果
HBITMAPhCharacter = (HBITMAP)LoadImage(NULL, L"character.bmp", IMAGE_BITMAP,640, 579, LR_LOADFROMFILE); //載入圖片,其中圖像大小爲640*579像素
SelectObject(dcCompatible,hCharacter); //選擇設備到兼容DC
BitBlt(g_hdc,50, 700 - 579, 320, 640, dcCompatible, 320, 0, SRCAND);//透明遮罩法第一步,即將遮罩圖與背景圖做"AND"運算
BitBlt(g_hdc,50, 700 - 579, 320, 640, dcCompatible, 0, 0, SRCPAINT);//透明遮罩法第二步,即將素材圖(前景圖)與背景圖做"OR"運算
}
這是程序中用到的素材圖片
background1.bmp
background2.bmp
character.bmp