?? sdx3.cpp
字號:
//-----------------------------------------------------------------------------
//鍵盤控制人物動畫
//
//
// 制作:耗子
// email: chain@km169.net
// 主頁:http://clicknow.yeah.net
//-----------------------------------------------------------------------------
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
//-----------------------------------------------------------------------------
// 所要包涵的文件
//-----------------------------------------------------------------------------
#include <windows.h>
#include <ddraw.h>
#include <stdio.h>
#include <stdarg.h>
#include "ddutil.h"
//-----------------------------------------------------------------------------
// 定義程序類名稱與程序標題
//-----------------------------------------------------------------------------
#define NAME "keymove"
#define TITLE "鍵盤控制人物動畫"
//-----------------------------------------------------------------------------
// Default settings
//-----------------------------------------------------------------------------
#define TIMER_ID 1
#define TIMER_RATE 100
//-----------------------------------------------------------------------------
// 全局數(shù)據(jù)區(qū),包括DirectDraw對象,DirectDraw表面,DirectDraw調(diào)色板等
//-----------------------------------------------------------------------------
LPDIRECTDRAW g_pDD = NULL; // DirectDraw object
LPDIRECTDRAWSURFACE g_pDDSPrimary = NULL;// DirectDraw primary surface
LPDIRECTDRAWSURFACE g_pDDSBack = NULL; // DirectDraw back surface
LPDIRECTDRAWSURFACE g_pDDSOne = NULL; // Offscreen surface 1
LPDIRECTDRAWSURFACE g_pDDSTwo = NULL; // Offscreen surface 2
LPDIRECTDRAWPALETTE g_pDDPal = NULL; // The primary surface palette
BOOL g_bActive = FALSE; // Is application active?
//-----------------------------------------------------------------------------
// Local data
//-----------------------------------------------------------------------------
// 圖象文件名
static char szBitmap1[] = "MAP1.bmp";
static char szBitmap2[] = "player.bmp";
//-----------------------------------------------------------------------------
//函數(shù)聲明
//-----------------------------------------------------------------------------
void drawplayer();
//-----------------------------------------------------------------------------
// Name: ReleaseAllObjects()
// Desc: 釋放所有對象
//-----------------------------------------------------------------------------
static void
ReleaseAllObjects(void)
{
if (g_pDD != NULL)
{
if (g_pDDSPrimary != NULL)
{
g_pDDSPrimary->Release();
g_pDDSPrimary = NULL;
}
if (g_pDDSOne != NULL)
{
g_pDDSOne->Release();
g_pDDSOne = NULL;
}
if (g_pDDSTwo != NULL)
{
g_pDDSTwo->Release();
g_pDDSTwo = NULL;
}
if (g_pDDPal != NULL)
{
g_pDDPal->Release();
g_pDDPal = NULL;
}
g_pDD->Release();
g_pDD = NULL;
}
}
//-----------------------------------------------------------------------------
// Name: InitFail()
// Desc: 初始化出錯時調(diào)用此函數(shù),顯示出錯信息并退出程序
//-----------------------------------------------------------------------------
HRESULT
InitFail(HWND hWnd, HRESULT hRet, LPCTSTR szError,...)
{
char szBuff[128];
va_list vl;
va_start(vl, szError);
vsprintf(szBuff, szError, vl);
ReleaseAllObjects();
MessageBox(hWnd, szBuff, TITLE, MB_OK);
DestroyWindow(hWnd);
va_end(vl);
return hRet;
}
//-----------------------------------------------------------------------------
// Name: InitSurfaces()
// Desc: 初始化DirectDraw表面(讀入圖象而已)
// 將三幅圖讀入相應(yīng)的表頁
//
//-----------------------------------------------------------------------------
BOOL
InitSurfaces(void)
{
// Load our bitmap resource.
g_pDDSOne =DDLoadBitmap(g_pDD, szBitmap1, 0, 0);
g_pDDSTwo =DDLoadBitmap(g_pDD, szBitmap2, 0, 0);
return TRUE;
}
//-----------------------------------------------------------------------------
// Name: RestoreAll()
// Desc: 恢復所有對象(在表面丟失時調(diào)用)
//-----------------------------------------------------------------------------
HRESULT
RestoreAll(void)
{
HRESULT hRet;
hRet = g_pDDSPrimary->Restore();
if (hRet == DD_OK)
{
hRet = g_pDDSOne->Restore();
if (hRet == DD_OK)
{
hRet = g_pDDSTwo->Restore();
if (hRet == DD_OK)
{
InitSurfaces();
}
}
}
return hRet;
}
//-----------------------------------------------------------------------------
// Name: UpdateFrame()
// Desc:
//
//
//
//-----------------------------------------------------------------------------
static void
UpdateFrame()
{
//精靈顯示坐標
static int ix=500,iy=200;
HRESULT hRet;
RECT rcRect;
int i,j;
//填充黑色
DDBLTFX ddBltFx;
ddBltFx.dwSize = sizeof(DDBLTFX);
ddBltFx.dwFillColor = 0;
g_pDDSBack->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx);
//顯示地圖
for(i=0;i<21;i++)
{
for(j=0;j<16;j++)
{
rcRect.left = 0;
rcRect.top = 32;
rcRect.right = 30;
rcRect.bottom = 62;
hRet = g_pDDSBack->BltFast(i*30, j*30, g_pDDSOne, &rcRect, DDBLTFAST_NOCOLORKEY);
}
}
drawplayer();//畫出相應(yīng)動作的人物
//輸入文字
HDC hdc;
char temp[256];
if (g_pDDSBack->GetDC(&hdc) == DD_OK)
{
SetBkMode(hdc,TRANSPARENT);
SetTextColor( hdc, RGB( 0, 0, 0 ) );
sprintf(temp,"鍵盤控制人物動畫");
TextOut( hdc, 10, 10, temp, lstrlen(temp) );
SetTextColor( hdc, RGB( 242, 109, 53 ) );
sprintf(temp,"耗子 制作");
TextOut( hdc, 500, 400, temp, lstrlen(temp) );
sprintf(temp,"Email:Chain@km169.net");
TextOut( hdc, 450, 415, temp, lstrlen(temp) );
sprintf(temp,"主頁:http://clicknow.yeah.net");
TextOut( hdc, 420, 430, temp, lstrlen(temp) );
g_pDDSBack->ReleaseDC(hdc);
}
}
//-----------------------------------------------------------------------------
// Name: WindowProc()
// Desc: 消息處理函數(shù)
//-----------------------------------------------------------------------------
long FAR PASCAL
WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HRESULT hRet;
switch (message)
{
case WM_ACTIVATEAPP:
// Pause if minimized or not the top window
g_bActive = (wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE);
return 0L;
case WM_DESTROY:
// Clean up and close the app
ReleaseAllObjects();
PostQuitMessage(0);
return 0L;
case WM_KEYDOWN:
// Handle any non-accelerated key commands
switch( wParam )
{
case VK_ESCAPE://退出
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_SETCURSOR:
// Turn off the cursor since this is a full-screen app
SetCursor(NULL);
return TRUE;
case WM_TIMER:
// 這里進行更新背景并翻轉(zhuǎn)表面以顯示出背景,呵呵,這里是抄別人的。
if (g_bActive && TIMER_ID == wParam)
{
UpdateFrame();
while (TRUE)
{
hRet = g_pDDSPrimary->Flip(NULL, 0);
if (hRet == DD_OK)
break;
if (hRet == DDERR_SURFACELOST)
{
hRet = RestoreAll();
if (hRet != DD_OK)
break;
}
if (hRet != DDERR_WASSTILLDRAWING)
break;
}
}
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
//-----------------------------------------------------------------------------
// Name: InitApp()
// Desc: 初始化程序,窗口,DirectDraw與顯示時間間隔
//-----------------------------------------------------------------------------
static HRESULT
InitApp(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
WNDCLASS wc;
DDSURFACEDESC ddsd;
DDSCAPS ddscaps;
HRESULT hRet;
LPDIRECTDRAW pDD;
// Set up and register window class
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(NULL));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NAME;
wc.lpszClassName = NAME;
RegisterClass(&wc);
// Create a window
hWnd = CreateWindowEx(WS_EX_TOPMOST,
NAME,
TITLE,
WS_POPUP,
0,
0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL,
NULL,
hInstance,
NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
SetFocus(hWnd);
///////////////////////////////////////////////////////////////////////////
// 創(chuàng)建DirectDraw對象
///////////////////////////////////////////////////////////////////////////
hRet = DirectDrawCreate(NULL, &pDD, NULL);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "DirectDrawCreate FAILED");
hRet = pDD->QueryInterface(IID_IDirectDraw, (LPVOID *) & g_pDD);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "QueryInterface FAILED");
// 設(shè)置模式
hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "SetCooperativeLevel FAILED");
// 設(shè)置顯示方式為640x480,256色
hRet = g_pDD->SetDisplayMode(640, 480, 8);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "SetDisplayMode FAILED");
// 創(chuàng)建主表面和一個背景表面
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP |
DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "CreateSurface FAILED");
// 取得背景表面指針
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
hRet = g_pDDSPrimary->GetAttachedSurface(&ddscaps, &g_pDDSBack);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "GetAttachedSurface FAILED");
// 創(chuàng)建一個離屏表面(可想象是一幅圖)
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwHeight = 480;
ddsd.dwWidth = 640;
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOne, NULL);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "CreateSurface FAILED");
// 創(chuàng)建另一個離屏表面(可想象是另一幅圖)
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSTwo, NULL);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "CreateSurface FAILED");
// 讀入調(diào)色板并設(shè)置上
g_pDDPal = DDLoadPalette(g_pDD, szBitmap1);
if (g_pDDPal)
g_pDDSPrimary->SetPalette(g_pDDPal);
//讀入圖象
if (!InitSurfaces())
return InitFail(hWnd, hRet, "InitSurfaces FAILED");
//設(shè)置精靈的透明色
DDSetColorKey(g_pDDSTwo, RGB(255,238,187));
// 創(chuàng)建頁面翻轉(zhuǎn)時間間隔(這個我不大懂,呵呵)
if (TIMER_ID != SetTimer(hWnd, TIMER_ID, TIMER_RATE, NULL))
return InitFail(hWnd, hRet, "SetTimer FAILED");
return DD_OK;
}
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: 入口,初始化,進行消息循環(huán)
//-----------------------------------------------------------------------------
int PASCAL
WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
if (InitApp(hInstance, nCmdShow) != DD_OK)
return FALSE;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void drawplayer(void)
{
static int phase = 0;//顯示精靈哪個動作的標志
static int direction=0;//人物面對的方向,0 for south,1 for west,2 for east,3 for north;
HRESULT hRet;
RECT rcRect;
if(GetAsyncKeyState(VK_UP)) {direction=3;phase++;}
if(GetAsyncKeyState(VK_DOWN)) {direction=0;phase++;}
if(GetAsyncKeyState(VK_LEFT)) {direction=1;phase++;}
if(GetAsyncKeyState(VK_RIGHT)) {direction=2;phase++;}
if (phase>2) phase=0;
rcRect.left = phase*32;
rcRect.top = direction*48+0;
rcRect.right = phase*32+32;
rcRect.bottom = direction*48+48;
hRet = g_pDDSBack->BltFast(320, 240, g_pDDSTwo, &rcRect, DDBLTFAST_SRCCOLORKEY);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -