#include "stdafx.h"
#include "MyGameFrame.h" //源cpp文件引申出的頭文件 也可以用resource.h代替
#include <stdio.h> //標準輸入輸出頭文件
// 全局變量:
HINSTANCE hInst; // 當前實例
HWND hWnd;
HDC hdc; //窗口DC
HDC mdc; //內存DC
HBITMAP bg; //背景圖
HBITMAP dra, draa; //前景圖
BITMAP bm1, bm2; //位圖指針
const int xstart = 320;
const int ystart = 240;
// 此代碼模塊中包含的函數的前向聲明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitWindow(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 初始化全局字符串
MyRegisterClass(hInstance);
// 執行應用程序初始化:
if (!InitWindow(hInstance, nCmdShow))//初始化窗口
{
return FALSE;//如果不成功則返回FALSE,並退出程序
}
/*
MSG類型見 https://blog.csdn.net/wanghaofeng/article/details/6632165
*/
MSG msg; //創建消息類對象
// TODO: 在此放置運行代碼。
bg = (HBITMAP)LoadImage(NULL, _T("bg.bmp"), IMAGE_BITMAP, 640, 480, LR_LOADFROMFILE);//加載背景圖
dra = (HBITMAP)LoadImage(NULL, _T("dra.bmp"), IMAGE_BITMAP, 170, 99, LR_LOADFROMFILE);//加載前景圖
hdc = GetDC(hWnd);//創建內存DC
mdc = CreateCompatibleDC(hdc);//創建窗口DC,CreateCompatibleDC( )函數建立建立內存設備描述表,把存儲在內存DC上的位圖貼到窗口DC中
HDC bufdc;
bufdc = CreateCompatibleDC(hdc);
draa = CreateCompatibleBitmap(hdc, 85, 99);
SelectObject(mdc, draa);
SelectObject(bufdc, bg);
BitBlt(mdc, 0, 0, 85, 99, bufdc, xstart, ystart, SRCCOPY);
SelectObject(bufdc, dra); //bmp爲載入的恐龍位圖句柄
BitBlt(mdc, 0, 0, 85, 99, bufdc, 85, 0, SRCAND);
BitBlt(mdc, 0, 0, 85, 99, bufdc, 0, 0, SRCPAINT);
/*------------------------------------------------------半透明理------------------------------------------------------------------------------*/
unsigned char *px1, *px2;
//取得位圖結構
/*
半透明技術改變位圖部分像素值,需加載位圖結構
int GetObject(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject);
hgdiobj:圖形對象句柄。可指向一個邏輯位圖、字體或調色板,可通過CreateDIBsection( )創建與設備無關的位圖。
cbBuffer:寫到緩衝區信息的字節數目。
lpvObject:指向緩衝區指針,該緩衝區指定將要檢索圖形對象的信息。緩衝區可接收的信息和類型用hgdiobj來指定。
*/
GetObject(bg, sizeof(BITMAP), &bm1);
if (bm1.bmBitsPixel != 32 && bm1.bmBitsPixel != 24) {
MessageBox(NULL, "只能在32bit 或24bit 顯示模式下運行", "警告", 0);
return FALSE;
}
//建立暫存數組
/*
取得位圖的結構後,必須建立一個暫存數組準備存儲位圖中所有像素的顏色值。
暫存數組大小是由取得位圖的bmHeight與bmWidthBytes信息來決定的。
*/
px1 = new unsigned char[bm1.bmHeight*bm1.bmWidthBytes];
//取得位圖數值
/*
建立了暫存數組之後,可使用GetBitmapBits( )函數取出位圖的所有顏色值並存儲到數組中。
*/
GetBitmapBits(bg, bm1.bmHeight*bm1.bmWidthBytes, px1);
//取得位圖結構
/*
半透明技術改變位圖部分像素值,需加載位圖結構
int GetObject(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject);
hgdiobj:圖形對象句柄。可指向一個邏輯位圖、字體或調色板,可通過CreateDIBsection( )創建與設備無關的位圖。
cbBuffer:寫到緩衝區信息的字節數目。
lpvObject:指向緩衝區指針,該緩衝區指定將要檢索圖形對象的信息。緩衝區可接收的信息和類型用hgdiobj來指定。
*/
GetObject(draa, sizeof(BITMAP), &bm2);
//建立暫存數組
/*
取得位圖的結構後,必須建立一個暫存數組準備存儲位圖中所有像素的顏色值。
暫存數組大小是由取得位圖的bmHeight與bmWidthBytes信息來決定的。
*/
px2 = new unsigned char[bm2.bmHeight*bm2.bmWidthBytes];
//取得位圖數值
/*
建立了暫存數組之後,可使用GetBitmapBits( )函數取出位圖的所有顏色值並存儲到數組中。
*/
GetBitmapBits(draa, bm2.bmHeight*bm2.bmWidthBytes, px2);
int x, y;
int i;
int rgb_b;
int PxBytes = bm1.bmBitsPixel / 8;
int xend = xstart + 85;
int yend = ystart + 99;
for (y = ystart; y<yend; y++) {
for (x = xstart; x<xend; x++) {
rgb_b = y * bm1.bmWidthBytes + x * PxBytes;
px1[rgb_b] = px1[rgb_b] * 3 / 10;
px1[rgb_b + 1] = px1[rgb_b + 1] * 3 / 10;
px1[rgb_b + 2] = px1[rgb_b + 2] * 3 / 10;
}
}
for (y = 0; y<(bm2.bmHeight); y++) {
for (x = 0; x<bm2.bmWidth; x++) {
rgb_b = y * bm2.bmWidthBytes + x * PxBytes;
i = (ystart + y) * bm1.bmWidthBytes + (xstart + x) * PxBytes;
px2[rgb_b] = px2[rgb_b] * 7 / 10 + px1[i];
px2[rgb_b + 1] = px2[rgb_b + 1] * 7 / 10 + px1[i + 1];
px2[rgb_b + 2] = px2[rgb_b + 2] * 7 / 10 + px1[i + 2];
}
}
SetBitmapBits(draa, bm2.bmHeight*bm2.bmWidthBytes, px2); //根據數組的內容來重設位圖的顏色
SelectObject(mdc, bg);
BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY);
SelectObject(mdc, draa);
BitBlt(hdc, xstart, ystart, 85, 99, mdc, 0, 0, SRCCOPY);
//主消息循環:
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);//賦初值
while (msg.message != WM_QUIT) //進入遊戲消息循環:
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg); //獲得遊戲玩家輸入的消息;
DispatchMessage(&msg);//分配玩家消息並響應用戶消息。
}
}
return (int)msg.wParam;
}
//
// 函數: MyRegisterClass()
//
// 註冊Windows類,一款遊戲有且僅有一個主窗口,與遊戲程序唯一對應。創建遊戲窗口前要填寫窗口類結構體WNDCLASSEX
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex =
{
wcex.cbSize = sizeof(WNDCLASSEX),
CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
WndProc,0,0,
hInstance,
LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYGAMEFRAME)),
LoadCursor(NULL, IDC_ARROW),
(HBRUSH)(COLOR_WINDOW + 1),NULL,
_T("GameFrame"),
LoadIcon(NULL,MAKEINTRESOURCE(IDI_SMALL))
};
return RegisterClassEx(&wcex);
}
//
// 函數: InitInstance(HINSTANCE, int)
//
// 目的: 保存實例句柄並創建主窗口
//
// 註釋:
//
// 在此函數中,我們在全局變量中保存實例句柄並
// 創建和顯示主程序窗口。
//
BOOL InitWindow(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 將實例句柄存儲在全局變量中
hWnd = CreateWindow
(
_T("GameFrame"),
_T("遊戲框架"),
WS_OVERLAPPEDWINDOW^WS_THICKFRAME^WS_MAXIMIZEBOX,//普通樣式,不能改變大小,不能最大化
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, nullptr, nullptr, hInstance, nullptr
);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函數: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 處理主窗口的消息。
//
// WM_COMMAND - 處理應用程序菜單
// WM_PAINT - 繪製主窗口
// WM_DESTROY - 發送退出消息並返回
//
//
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
PAINTSTRUCT ps; //用於WM_PAINT
switch (msg) //判斷消息
{
case WM_CREATE:
//執行初始化代碼
return(0);
break;
case WM_PAINT:
//確定窗口是否有效
hdc = BeginPaint(hwnd, &ps);
//執行繪製代碼
SelectObject(mdc, bg);
BitBlt(hdc, 0, 0, 640, 480, mdc, 0, 0, SRCCOPY);
SelectObject(mdc, draa);
BitBlt(hdc, xstart, ystart, 85, 99, mdc, 0, 0, SRCCOPY);
//BitBlt(hdc, 320, 240, 85, 99, mdc, 85, 0, SRCAND);
//BitBlt(hdc, 320, 240, 85, 99, mdc, 0, 0, SRCPAINT);
//結束代碼
EndPaint(hwnd, &ps);
return(0);
break;
case WM_DESTROY:
//關閉程序,發送WM_QUIT消息
PostQuitMessage(0);
return(0);
break;
default:
break;
}
return (DefWindowProc(hwnd, msg, wparam, lparam));
}