📄 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
//-----------------------------------------------------------------------------
// 全局数据区,包括DirectDraw对象,DirectDraw表面,DirectDraw调色板等
//-----------------------------------------------------------------------------
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";
//-----------------------------------------------------------------------------
//函数声明
//-----------------------------------------------------------------------------
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: 初始化出错时调用此函数,显示出错信息并退出程序
//-----------------------------------------------------------------------------
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表面(读入图象而已)
// 将三幅图读入相应的表页
//
//-----------------------------------------------------------------------------
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: 恢复所有对象(在表面丢失时调用)
//-----------------------------------------------------------------------------
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();//画出相应动作的人物
//输入文字
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: 消息处理函数
//-----------------------------------------------------------------------------
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:
// 这里进行更新背景并翻转表面以显示出背景,呵呵,这里是抄别人的。
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);
///////////////////////////////////////////////////////////////////////////
// 创建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");
// 设置模式
hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "SetCooperativeLevel FAILED");
// 设置显示方式为640x480,256色
hRet = g_pDD->SetDisplayMode(640, 480, 8);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "SetDisplayMode FAILED");
// 创建主表面和一个背景表面
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");
// 创建一个离屏表面(可想象是一幅图)
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");
// 创建另一个离屏表面(可想象是另一幅图)
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSTwo, NULL);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, "CreateSurface FAILED");
// 读入调色板并设置上
g_pDDPal = DDLoadPalette(g_pDD, szBitmap1);
if (g_pDDPal)
g_pDDSPrimary->SetPalette(g_pDDPal);
//读入图象
if (!InitSurfaces())
return InitFail(hWnd, hRet, "InitSurfaces FAILED");
//设置精灵的透明色
DDSetColorKey(g_pDDSTwo, RGB(255,238,187));
// 创建页面翻转时间间隔(这个我不大懂,呵呵)
if (TIMER_ID != SetTimer(hWnd, TIMER_ID, TIMER_RATE, NULL))
return InitFail(hWnd, hRet, "SetTimer FAILED");
return DD_OK;
}
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: 入口,初始化,进行消息循环
//-----------------------------------------------------------------------------
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 + -