⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddex1.cpp

📁 windows mobile 6.0下,用DirectDraw写的sprite的动画程序,有兴趣的可以看一下.
💻 CPP
字号:
//
//
//

#include <windows.h>
#include <ddraw.h>
#include "resource.h"

#define NAME                TEXT("DDExample1")
#define TITLE               TEXT("Direct Draw Example 1")
#define IMAGE_COUNT			2
#define NUM_SPRITES			5

#define SCREEN_WIDTH	240
#define SCREEN_HEIGHT	320
#define SCREEN_BPP		8
#define SPRITE_DIAMETER	32

TCHAR fileNames[IMAGE_COUNT][MAX_PATH] =
{
	L"\\Windows\\1.bmp",
	L"\\Windows\\2.bmp"
};

static const TCHAR          szMsg[] = TEXT("Page Flipping Test: Press F12 to exit");
static const TCHAR          szFrontMsg[] = TEXT("Front buffer (F12 to quit)");
static const TCHAR          szBackMsg[] = TEXT("Back buffer (F12 to quit)");

HINSTANCE g_hInst = NULL;
HWND g_hwnd = NULL;
int curImage = 0;
RECT rect;
DWORD g_dwLastTick;
BOOL g_bActive = FALSE;

LPDIRECTDRAW                g_pDD = NULL;            // DirectDraw object
LPDIRECTDRAWSURFACE         g_pDDSPrimary = NULL;    // DirectDraw primary surface
LPDIRECTDRAWSURFACE         g_pDDSBack = NULL;       // DirectDraw back surface
LPDIRECTDRAWSURFACE			g_pBmp = NULL;
//LPDIRECTDRAWSURFACE			g_pBmp[IMAGE_COUNT] = {0};
LPDIRECTDRAWSURFACE			g_pDDSLogo = NULL;

struct SPRITE_STRUCT
{
	FLOAT fPosX;
	FLOAT fPosY;
	FLOAT fVelX;
	FLOAT fVelY;
};

SPRITE_STRUCT g_Sprite[NUM_SPRITES];

void UpdateSprite(SPRITE_STRUCT* pSprite, FLOAT fTimeDelta);
HRESULT ProcessNextFrame();
void ReleaseAllObjects(void);
void UpdateFrame();
void MakeRect(int left, int top, int right, int bottom);
LPDIRECTDRAWSURFACE BitmapSurface(LPCTSTR fileName);
LPDIRECTDRAWSURFACE SpriteSurface(LPCTSTR fileName);
BOOL InitDDraw();
BOOL InitWindow(HINSTANCE hInstance, int nShowCmd);
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
static HRESULT PASCAL EnumFunction(LPDIRECTDRAWSURFACE pSurface, LPDDSURFACEDESC lpSurfaceDesc, LPVOID  lpContext);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
{
	g_hInst = hInstance;

	ZeroMemory(&g_Sprite, sizeof(SPRITE_STRUCT) * NUM_SPRITES);
	srand( GetTickCount());
	if(!InitWindow(hInstance, nShowCmd))
	{
		return FALSE;
	}

	g_dwLastTick = timeGetTime();

	MSG msg;
	//while(GetMessage(&msg, NULL, 0, 0))
	//{
	//	TranslateMessage(&msg);
	//	DispatchMessage(&msg);
	//}
	while(TRUE)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if(0 == GetMessage(&msg, NULL, 0, 0))
			{
				return (int)msg.wParam;
			}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			if(g_bActive)
			{
				if(FAILED(ProcessNextFrame()))
				{
					return FALSE;
				}
			}
			else
			{
				// Make sure we go to sleep if we have nothing else to do
				//WaitMessage();
				// Ignore time spent inactive 
				g_dwLastTick = timeGetTime();//获得当前系统时间
			}
		}
	}

	return (int)msg.wParam;
}

BOOL InitWindow(HINSTANCE hInstance, int nShowCmd)
{
	WNDCLASS wc;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hbrBackground	= (HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.hCursor			= NULL;
	wc.hIcon			= LoadIcon(NULL, MAKEINTRESOURCE(IDI_ICON1));
	wc.hInstance		= hInstance;
	wc.lpfnWndProc		= WndProc;
	wc.lpszClassName	= NAME;
	wc.lpszMenuName		= NULL;
	wc.style			= CS_HREDRAW | CS_VREDRAW;

	if(!RegisterClass(&wc))
	{
		return FALSE;
	}

	g_hwnd = CreateWindow(/*WS_EX_TOPMOST,*/
							NAME,
							TITLE,
							WS_POPUP,
							0,
							0,
							GetSystemMetrics(SM_CXSCREEN),
							GetSystemMetrics(SM_CYSCREEN),
							NULL,
							NULL,
							hInstance,
							NULL);
	if(!g_hwnd)
	{
		return FALSE;
	}
	ShowWindow(g_hwnd, nShowCmd);
	UpdateWindow(g_hwnd);
	SetFocus(g_hwnd);
	InitDDraw();

	return TRUE;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
	case WM_LBUTTONUP:
		PostMessage(hwnd, WM_DESTROY, 0, 0);
		break;

	case WM_DESTROY:
		{
			ReleaseAllObjects();
			PostQuitMessage(0);
		}
		break;

	case WM_SIZE:
		if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
			g_bActive = FALSE;
		else
			g_bActive = TRUE;

		//UpdateFrame();

		break;

	case WM_EXITMENULOOP:
		g_dwLastTick = timeGetTime();
		break;

	case WM_MOVE:
		//UpdateFrame();
		break;

	case WM_TIMER:
		{
			//KillTimer(hwnd, 1);
			//curImage++;
			//if(curImage>1)
			//{
			//	curImage = 0;
			//}
			UpdateFrame();
		}
		break;
	}

	return DefWindowProc(hwnd, message, wParam, lParam);
}

BOOL InitDDraw()
{
	DDSURFACEDESC ddsd;

	if(DD_OK != DirectDrawCreate(NULL, &g_pDD, NULL))
	{
		return FALSE;
	}

	if(DD_OK != g_pDD->SetCooperativeLevel(g_hwnd, DDSCL_FULLSCREEN))
	{
		return FALSE;
	}

	//if(DD_OK != g_pDD->SetDisplayMode(240,320,24,0,0))
	//{
	//	return FALSE;
	//}

    DDCAPS ddCaps;
    DDCAPS ddHelCaps;

    g_pDD->GetCaps(&ddCaps, &ddHelCaps);

    if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER)) 
    {
		return FALSE;
        //return InitFail(hWnd, E_FAIL, szNoBackBufferMsg);
    }

    if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_FLIP)) 
    {
		return FALSE;
        //return InitFail(hWnd, E_FAIL, szNoFlipSurfacesMsg);
    }

	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP;
	ddsd.dwBackBufferCount = 1;
	if(DD_OK != g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL))
	{
		return FALSE;
	}

	//ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
	if(DD_OK != g_pDDSPrimary->EnumAttachedSurfaces(&g_pDDSBack, EnumFunction))
	{
		return FALSE;
	}

	g_pBmp = BitmapSurface(MAKEINTRESOURCE(IDB_BITMAP1));
	if(!g_pBmp)
	{
		return FALSE;
	}

	g_pDDSLogo = SpriteSurface(MAKEINTRESOURCE(IDB_DIRECTX));
	if(!g_pDDSLogo)
	{
		return FALSE;
	}
	DDCOLORKEY ddck;
	ddck.dwColorSpaceLowValue  = RGB(0,0,0);
    ddck.dwColorSpaceHighValue = RGB(0,0,0);
	g_pDDSLogo->SetColorKey(DDCKEY_SRCBLT, &ddck);

	for(int iSprite = 0; iSprite < NUM_SPRITES; iSprite++)
	{
		// Set the sprite's position and velocity
		// 设置这些 sprite(小怪物)的初始坐标随机产生

		g_Sprite[iSprite].fPosX = (float) (rand() % SCREEN_WIDTH);
		g_Sprite[iSprite].fPosY = (float) (rand() % SCREEN_HEIGHT); 

		// 速度也随机产生

		g_Sprite[iSprite].fVelX = 500.0f * rand() / RAND_MAX - 250.0f;
		g_Sprite[iSprite].fVelY = 500.0f * rand() / RAND_MAX - 250.0f;
		//g_Sprite[iSprite].fVelX = (FLOAT)(500.0f * rand() / RAND_MAX);
		//g_Sprite[iSprite].fVelY = (FLOAT)(500.0f * rand() / RAND_MAX);
	}
	UpdateFrame();

	//SetTimer(g_hwnd, 1, 50, 0);

	return TRUE;
}

static HRESULT PASCAL EnumFunction(LPDIRECTDRAWSURFACE pSurface, LPDDSURFACEDESC lpSurfaceDesc, LPVOID  lpContext)
{
    static BOOL bCalled = FALSE;

    if(!bCalled)
	{
		//lpSurfaceDesc->ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
        *((LPDIRECTDRAWSURFACE *)lpContext) = pSurface;
        bCalled = TRUE;
        return DDENUMRET_OK;
    }
    else
	{
        OutputDebugString(L"DDEX1: Enumerated more than surface?");
        pSurface->Release();
        return DDENUMRET_CANCEL;
    }
}

LPDIRECTDRAWSURFACE SpriteSurface(LPCTSTR fileName)
{
	HDC hdc;
	HBITMAP hBitmap;
	LPDIRECTDRAWSURFACE surf;

	hBitmap = LoadBitmap(g_hInst, fileName);
	//hBitmap = (HBITMAP)LoadImage(g_hInst, fileName, IMAGE_BITMAP, 0, 0, 0);
	if(!hBitmap)
	{
		return NULL;
	}

	BITMAP bmp;
	GetObject(hBitmap, sizeof(BITMAP), &bmp);
	int surfWidth = bmp.bmWidth;
	int surfHeight = bmp.bmHeight;

	DDSURFACEDESC ddsd;
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
	ddsd.dwWidth = 32;
	ddsd.dwHeight = 32;

	if(DD_OK != g_pDD->CreateSurface(&ddsd, &surf, NULL))
	{
		DeleteObject(hBitmap);
		return NULL;
	}
	else
	{
		surf->GetDC(&hdc);
		HDC bitDC = CreateCompatibleDC(hdc);
		//hBitmap = CreateCompatibleBitmap(hdc, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
		//FillRect();
		SelectObject(bitDC, hBitmap);
		//TransparentImage(bitDC,  0, 0, surfWidth, surfHeight, hBitmap, 0, 0, surfWidth, surfHeight, RGB(255,255,255));
		//TransparentBlt(hdc, 0, 0, surfWidth, surfHeight, bitDC, 0, 0, surfWidth, surfHeight, RGB(255,255,255));
		BitBlt(hdc, 0, 0, surfWidth, surfHeight, bitDC, 0, 0, SRCCOPY);
		surf->ReleaseDC(hdc);
		DeleteDC(bitDC);
	}
	DeleteObject(hBitmap);

	return surf;
}

LPDIRECTDRAWSURFACE BitmapSurface(LPCTSTR fileName)
{
	HDC hdc;
	HBITMAP hBitmap;
	LPDIRECTDRAWSURFACE surf;

	hBitmap = LoadBitmap(g_hInst, fileName);
	//hBitmap = (HBITMAP)LoadImage(g_hInst, fileName, IMAGE_BITMAP, 0, 0, 0);
	if(!hBitmap)
	{
		return NULL;
	}

	BITMAP bmp;
	GetObject(hBitmap, sizeof(BITMAP), &bmp);
	int surfWidth = bmp.bmWidth;
	int surfHeight = bmp.bmHeight;

	DDSURFACEDESC ddsd;
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
	ddsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY;
	ddsd.dwWidth = 240;
	ddsd.dwHeight = 320;

	if(DD_OK != g_pDD->CreateSurface(&ddsd, &surf, NULL))
	{
		DeleteObject(hBitmap);
		return NULL;
	}
	else
	{
		surf->GetDC(&hdc);
		HDC bitDC = CreateCompatibleDC(hdc);
		//hBitmap = CreateCompatibleBitmap(hdc, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
		//FillRect();
		SelectObject(bitDC, hBitmap);
		BitBlt(hdc, 0, 0, surfWidth, surfHeight, bitDC, 0, 0, SRCCOPY);
		surf->ReleaseDC(hdc);
		DeleteDC(bitDC);
	}
	DeleteObject(hBitmap);

	return surf;
}

void UpdateFrame()
{
	if(!g_pBmp)
	{
		g_pBmp = BitmapSurface(MAKEINTRESOURCE(IDB_BITMAP1));
		if(!g_pBmp)
		{
			return;
		}
	}

	static BYTE phase = 0;
	//RECT rc;
	//SIZE size;
	//int nMsg;
	//HDC hdc;
	DDBLTFX ddbltfx;
    memset(&ddbltfx, 0, sizeof(ddbltfx));
    ddbltfx.dwSize = sizeof(ddbltfx);
    ddbltfx.dwFillColor = 0;
	MakeRect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));

	//if(DD_OK == g_pDDSBack->GetDC(&hdc))
	//{
	//	SetBkColor(hdc, RGB(0,255,255));
	//	SetTextColor(hdc, RGB(255,0,0));
	//	GetClientRect(g_hwnd, &rc);
	//	if(phase)
	//	{
	//		nMsg = lstrlen(szMsg);
	//		GetTextExtentPoint(hdc, szMsg, nMsg, &size);
	//		ExtTextOut(hdc, (rc.right-size.cx)/2, (rc.bottom-size.cy)/2, 0, NULL, szMsg, nMsg, NULL);

	//		nMsg = lstrlen(szFrontMsg);
	//		GetTextExtentPoint(hdc, szFrontMsg, nMsg, &size);
	//		ExtTextOut(hdc, (rc.right-size.cx)/2, 0, 0, NULL, szFrontMsg, nMsg, NULL);

	//		phase = 0;
	//	}
	//	else
	//	{
	//		nMsg = lstrlen(szBackMsg);
 //           GetTextExtentPoint(hdc, szBackMsg, nMsg, &size);
	//		ExtTextOut(hdc, (rc.right-size.cx)/2, 0, 0, NULL, szBackMsg, nMsg, NULL);
	//		phase = 1;
	//	}
	//	g_pDDSBack->ReleaseDC(hdc);
	//}

	//if(DD_OK == g_pBmp[curImage]->GetDC(&hdc))
	//{
	//	SetBkColor(hdc, RGB(0,255,255));
	//	SetTextColor(hdc, RGB(255,0,0));
	//	GetClientRect(g_hwnd, &rc);
	//	if(phase)
	//	{
	//		nMsg = lstrlen(szMsg);
	//		GetTextExtentPoint(hdc, szMsg, nMsg, &size);
	//		ExtTextOut(hdc, (rc.right-size.cx)/2, (rc.bottom-size.cy)/2, 0, NULL, szMsg, nMsg, NULL);

	//		nMsg = lstrlen(szFrontMsg);
	//		GetTextExtentPoint(hdc, szFrontMsg, nMsg, &size);
	//		ExtTextOut(hdc, (rc.right-size.cx)/2, 0, 0, NULL, szFrontMsg, nMsg, NULL);
	//		phase = 0;
	//	}
	//	else
	//	{
	//		nMsg = lstrlen(szBackMsg);
 //           GetTextExtentPoint(hdc, szBackMsg, nMsg, &size);
	//		ExtTextOut(hdc, (rc.right-size.cx)/2, 0, 0, NULL, szBackMsg, nMsg, NULL);
	//		phase = 1;
	//	}
	//	g_pBmp[curImage]->ReleaseDC(hdc);
	//}

	g_pDDSBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx);
	g_pDDSBack->Blt(NULL, g_pBmp, &rect, DDBLT_WAITNOTBUSY, 0);
	RECT rcSprite;
	for(int iSprite = 0; iSprite < NUM_SPRITES; iSprite++)
	{
		rcSprite.left	= (LONG)g_Sprite[iSprite].fPosX;
		rcSprite.top	= (LONG)g_Sprite[iSprite].fPosY;
		rcSprite.right	= (LONG)g_Sprite[iSprite].fPosX + 32;
		rcSprite.bottom = (LONG)g_Sprite[iSprite].fPosY + 32;

		g_pDDSBack->Blt(&rcSprite, g_pDDSLogo, NULL, DDBLT_WAITNOTBUSY|DDBLT_KEYSRC, 0);
	}
	g_pDDSPrimary->Blt(NULL, g_pDDSBack, &rect, DDBLT_WAITNOTBUSY, 0);
	//HRESULT hRet = g_pDDSPrimary->Flip(NULL, 0);

	//int nextSlide = (curImage >= IMAGE_COUNT-1) ? 0 : curImage+1;
	//if(!g_pBmp[nextSlide])
	//{
	//	g_pBmp[nextSlide] = BitmapSurface(MAKEINTRESOURCE(IDB_BITMAP1+nextSlide));
	//}
	//int prevSlide = (curImage < 1) ? IMAGE_COUNT-1 : curImage-1;
	//if(!g_pBmp[prevSlide])
	//{
	//	g_pBmp[prevSlide] = BitmapSurface(MAKEINTRESOURCE(IDB_BITMAP1+prevSlide));
	//}
}

void MakeRect(int left, int top, int right, int bottom)
{
	rect.left	= left;
	rect.top	= top;
	rect.right	= right;
	rect.bottom	= bottom;
}

void ReleaseAllObjects(void)
{
	//for(int i = 0; i < IMAGE_COUNT; i++)
	//{
	//	if(g_pBmp[i] != NULL)
	//	{
	//		g_pBmp[i]->Release();
	//		g_pBmp[i] = NULL;
	//	}
	//}
	if(g_pBmp != NULL)
	{
		g_pBmp->Release();
		g_pBmp = NULL;
	}

	if(g_pDDSLogo != NULL)
	{
		g_pDDSLogo->Release();
		g_pDDSLogo = NULL;
	}

    if (g_pDDSBack != NULL)
    {
        g_pDDSBack->Release();
        g_pDDSBack = NULL;
    }
    if (g_pDDSPrimary != NULL)
    {
        g_pDDSPrimary->Release();
        g_pDDSPrimary = NULL;
    }
    if (g_pDD != NULL)
    {
        g_pDD->Release();
        g_pDD = NULL;
    }
}

HRESULT ProcessNextFrame()
{
	//HRESULT hr;

	DWORD dwCurrTick = timeGetTime();
	DWORD dwTickDiff = dwCurrTick - g_dwLastTick;

	if(dwTickDiff == 0)
	{
		return S_OK;
	}
	g_dwLastTick = dwCurrTick;

	for(int iSprite = 0; iSprite < NUM_SPRITES; iSprite++)
	{
		UpdateSprite(&g_Sprite[iSprite], dwTickDiff / 1000.0f);
	}

	UpdateFrame();

	return S_OK;
}

void UpdateSprite(SPRITE_STRUCT* pSprite, FLOAT fTimeDelta)
{
	pSprite->fPosX += pSprite->fVelX * fTimeDelta;
	pSprite->fPosY += pSprite->fVelY * fTimeDelta;

	if(pSprite->fPosX < 0.0f)
	{
		pSprite->fPosX = 0;
		pSprite->fVelX = -pSprite->fVelX;
	}

	if(pSprite->fPosX >= SCREEN_WIDTH - SPRITE_DIAMETER)
	{
		pSprite->fPosX = SCREEN_WIDTH - SPRITE_DIAMETER - 1;
		pSprite->fVelX = -pSprite->fVelX;
	}

	if(pSprite->fPosY < 0)
	{
		pSprite->fPosY = 0;
		pSprite->fVelY = -pSprite->fVelY;
	}

	if(pSprite->fPosY > SCREEN_HEIGHT - SPRITE_DIAMETER)
	{
		pSprite->fPosY = SCREEN_HEIGHT - 1 - SPRITE_DIAMETER;
		pSprite->fVelY = -pSprite->fVelY;
	} 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -