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

📄 examplh2.cpp

📁 uses DirectX7 DirectDraw and DirectInput to create a small game
💻 CPP
字号:
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include "stdafx.h"
#include "resource.h"
#define INITGUID
#include <ddraw.h>
#include <dinput.h>

DWORD KeyColor;
BOOL bInit=FALSE;
float X = 399.0;
float Y = 299.0;
float P2X = 700;
float P2Y = 500;
float AIX = 100.0;
float AIY = 100.0;
float AISpeedX = 0.0;
float AISpeedY = 0.0;
float P2SpeedX = 0.0;
float P2SpeedY = 0.0;
float SpeedX = 0.0;
float SpeedY = 0.0;
LPDIRECTINPUT7       g_lpdi;
LPDIRECTINPUTDEVICE7 g_lpDIDEVICE;
LPDIRECTDRAW4        lpDD = NULL;
LPDIRECTDRAWSURFACE4 lpDDSPrimary = NULL;
LPDIRECTDRAWSURFACE4 lpDDSBack = NULL;
LPDIRECTDRAWSURFACE4 Fly = NULL;
LPDIRECTDRAWSURFACE4 Background = NULL;
BOOL DiDone = FALSE;
BOOL BackBuffer = FALSE;
BOOL CleaningUp = FALSE;
static char szClass[]   = "FlyFly";
static char szCaption[] = "Fly";
const char *ErrStr;			
const char Err_Reg_Class[]        = "Error Registering Window Class";
const char Err_Create_Win[]       = "Error Creating Window";
const char Err_DirectDrawCreate[] = "DirectDrawCreate FAILED";
const char Err_Query[]            = "QueryInterface FAILED";
const char Err_Coop[]             = "SetCooperativeLevel FAILED";
const char Err_CreateClip[]       = "CreateClip FAILED";
const char Err_CreateSurf[]       = "CreateSurface FAILED";
const char Err_LoadBMP[]          = "Error Loading Image";
const char Err_Lose[]             = "Ha ha. You lose.";
void MoveAI()
{
	// See who he's closest to:
	int DistFromP1 = AIX - X;
	int DistFromP2 = AIX - P2X;
	if(DistFromP1 < 0)	-DistFromP1;
	if(DistFromP2 < 0)	-DistFromP2;

	if(DistFromP1 < DistFromP2)
		{
		if(X < AIX)	AISpeedX -= 0.3;
		if(X > AIX)	AISpeedX += 0.3;
		if(Y < AIY)	AISpeedY -= 0.3;
		if(Y > AIY)	AISpeedY += 0.3;
		}
	else
		{
		if(P2X < AIX)	AISpeedX -= 0.3;
		if(P2X > AIX)	AISpeedX += 0.3;
		if(P2Y < AIY)	AISpeedY -= 0.3;
		if(P2Y > AIY)	AISpeedY += 0.3;
		}

		if(AISpeedX < -3.0)	AISpeedX = -3.0;
		if(AISpeedX > 3.0)	AISpeedX = 3.0;
		if(AISpeedY < -3.0)	AISpeedY = -3.0;
		if(AISpeedY > 3.0)	AISpeedY = 3.0;
}

void WINAPI ProcessKBInput() 
{
	char buffer[256];
	g_lpDIDEVICE->GetDeviceState(sizeof(buffer),(LPVOID)&buffer);

	if(buffer[DIK_UP] & 0x80)
		{
		if(SpeedY > -5.0)	SpeedY -= 0.3;
		}
	if(buffer[DIK_DOWN] & 0x80)
		{
		if(SpeedY < 5.0)	SpeedY += 0.3;
		}
	if(buffer[DIK_LEFT] & 0x80)
		{
		if(SpeedX > -5.0)	SpeedX -= 0.3;
		}
	if(buffer[DIK_RIGHT] & 0x80)
		{
		if(SpeedX < 5.0)	SpeedX += 0.3;
		}

	if(buffer[DIK_W] & 0x80)
		{
		if(P2SpeedY > -5.0)	P2SpeedY -= 0.3;
		}
	if(buffer[DIK_S] & 0x80)
		{
		if(P2SpeedY < 5.0)	P2SpeedY += 0.3;
		}
	if(buffer[DIK_A] & 0x80)
		{
		if(P2SpeedX > -5.0)	P2SpeedX -= 0.3;
		}
	if(buffer[DIK_D] & 0x80)
		{
		if(P2SpeedX < 5.0)	P2SpeedX += 0.3;
		}

}

#define SafeRelease(x) if (x) { x->Release(); x=NULL; }
void Cleanup(void)
{
	int times = 0;
	while(lpDDSPrimary->GetBltStatus(DDGBS_ISBLTDONE) != DD_OK && lpDDSBack->GetBltStatus(DDGBS_ISBLTDONE) != DD_OK)
		{
		times++;
		if(times = 100)	return;
		}
	SafeRelease(Fly);
	SafeRelease(lpDDSPrimary);
	SafeRelease(Background);
	SafeRelease(lpDD);
	if(DiDone)
		{
		g_lpDIDEVICE->Unacquire();
		g_lpDIDEVICE->Release();
		g_lpdi->Release();
		}
	DestroyWindow(0);
	PostQuitMessage(0);
	if(ErrStr)	MessageBox(NULL, ErrStr, szCaption, MB_OK);
}

void DetectCollision()
{
	if((AIX > X && AIX < X + 36) && (AIY > Y && AIY < Y + 47))
		{
		Cleanup();
		}
	if(((AIX + 36) > X && AIX < X + 36) && ((AIY + 47) > Y && AIY < Y + 47))
		{
		Cleanup();
		}
	if((AIX > P2X && AIX < P2X + 36) && (AIY > P2Y && AIY < P2Y + 47))
		{
		Cleanup();
		}
	if(((AIX + 36) > P2X && AIX < P2X + 36) && ((AIY + 47) > P2Y && AIY < P2Y + 47))
		{
		Cleanup();
		}
}

LPDIRECTDRAWSURFACE4 bitmap_surface(LPCTSTR file_name)
{
	HDC hdc;
	HBITMAP bit;
	LPDIRECTDRAWSURFACE4 surf;

	// load the interface bitmap

	bit=(HBITMAP) LoadImage(NULL,file_name,IMAGE_BITMAP,0,0,
								LR_DEFAULTSIZE|LR_LOADFROMFILE);
	if (!bit) 

		// failed to load, return failure to caller

		return NULL;

	// get bitmap dimensions

	BITMAP bitmap;
    GetObject( bit, sizeof(BITMAP), &bitmap );
	int surf_width=bitmap.bmWidth;
	int surf_height=bitmap.bmHeight;

	DDPIXELFORMAT ddpf;
	ddpf.dwSize=sizeof(ddpf);
	lpDDSPrimary->GetPixelFormat(&ddpf);

	// Determine proper key for pixel format

	KeyColor = ddpf.dwGBitMask;

	// create surface

	HRESULT ddrval;
	DDSURFACEDESC2 ddsd;
	ZeroMemory(&ddsd,sizeof(ddsd));
	ddsd.dwSize = sizeof(DDSURFACEDESC2);
	ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT ;
	ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY; 
	ddsd.dwWidth = surf_width;
	ddsd.dwHeight = surf_height; 

	// attempt to create surface

	ddrval=lpDD->CreateSurface(&ddsd,&surf,NULL);

	// created ok?

	if (ddrval!=DD_OK) {

		// no, release the bitmap and return failure to caller

		DeleteObject(bit);
		return NULL;

	} else {

		// yes, get a DC for the surface

		surf->GetDC(&hdc);

		// generate a compatible DC

		HDC bit_dc=CreateCompatibleDC(hdc);

		// blit the interface to the surface

		SelectObject(bit_dc,bit);
		BitBlt(hdc,0,0,surf_width,surf_height,bit_dc,0,0,SRCCOPY);

		// release the DCs

		surf->ReleaseDC(hdc);
		DeleteDC(bit_dc);
	}

	// clear bitmap 

	DeleteObject(bit);

	// return pointer to caller

	DDCOLORKEY key;
	key.dwColorSpaceLowValue = KeyColor;
	key.dwColorSpaceHighValue = KeyColor;
	surf->SetColorKey(DDCKEY_SRCBLT, &key);
	return surf;
}

void DrawImage()
{
	lpDDSBack->BltFast(0, 0, Background, NULL, DDBLTFAST_WAIT);
	lpDDSBack->BltFast(X, Y, Fly, NULL, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
	lpDDSBack->BltFast(AIX, AIY, Fly, NULL, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
	lpDDSBack->BltFast(P2X, P2Y, Fly, NULL, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY);
	lpDDSPrimary->Flip(0,DDFLIP_WAIT);
}

LRESULT CALLBACK WindowProc(HWND hWnd, unsigned uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
		{
        case WM_COMMAND:
            switch (LOWORD(wParam))
				{
                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;
				}
            break;

        case WM_PAINT:
			PAINTSTRUCT ps;
            BeginPaint(hWnd, &ps);
            EndPaint(hWnd, &ps);
            break;

        case WM_DESTROY:
            Cleanup();
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
		}
	return 0L;
}

BOOL Init(HINSTANCE hInstance, int nCmdShow)
{
    WNDCLASS                    wc;
    HRESULT                     hRet;
    DDSURFACEDESC2              ddsd;
    LPDIRECTDRAW                pDD;

    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = (WNDPROC) WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = sizeof(DWORD);
    wc.hInstance = hInstance;
    wc.hIcon = NULL;
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
    wc.lpszClassName = szClass;
    if(!RegisterClass(&wc))
		{
		ErrStr=Err_Reg_Class;
        return FALSE;
		}
	HWND hWnd;
	hWnd = CreateWindow(szClass, szCaption, WS_VISIBLE | WS_POPUP, 0, 0, 800, 600, NULL, NULL, hInstance, NULL);
    if(!hWnd)
		{
		ErrStr = Err_Create_Win;
        return FALSE;
		}
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    hRet = DirectDrawCreate(NULL, &pDD, NULL);
	if(hRet != DD_OK)
		{
		ErrStr = Err_DirectDrawCreate;
		return FALSE;
		}
	hRet = pDD->QueryInterface(IID_IDirectDraw4, (LPVOID *) &lpDD);
    if(hRet != DD_OK)
		{
		ErrStr = Err_Query;
		return FALSE;
		}
	hRet = lpDD->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
	if(hRet != DD_OK)
		{
		ErrStr=Err_Coop;
		return FALSE;
		}
	/*
    ZeroMemory(&ddsd, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    hRet = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
    if (hRet != DD_OK)
		{
		ErrStr = Err_CreateSurf;
		return FALSE;
		}*/
	
	DDSCAPS2 ddscaps;
	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 = lpDD->CreateSurface(&ddsd, &lpDDSPrimary, NULL);
	if(hRet!=DD_OK)
		{
		ErrStr=Err_CreateSurf;
		return FALSE;
		}
	// Fetch back buffer interface
	ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
	hRet = lpDDSPrimary->GetAttachedSurface(&ddscaps,&lpDDSBack);
	if(hRet!=DD_OK)
		{
		ErrStr = Err_CreateSurf;
		return FALSE;
		}

	bInit=TRUE;

	Fly = bitmap_surface("Fly.bmp");
	Background = bitmap_surface("Background.bmp");
	if(!Fly)
		{
		ErrStr = Err_LoadBMP;
		return FALSE;
		}
	if(!Background)
		{
		ErrStr = Err_LoadBMP;
		return FALSE;
		}
	DrawImage();

	DirectInputCreateEx(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput7, (void**)&g_lpdi, NULL);
	g_lpdi->CreateDeviceEx(GUID_SysKeyboard, IID_IDirectInputDevice7, (void**)&g_lpDIDEVICE, NULL);
	g_lpDIDEVICE->SetDataFormat(&c_dfDIKeyboard);
	g_lpDIDEVICE->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
	g_lpDIDEVICE->Acquire();
	DiDone = TRUE;
    return TRUE;
}

int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg;

	if(!Init(hInstance, nCmdShow))
		{
		Cleanup();
		return FALSE;
		}
	for(;;)
		{
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
			{
			if(msg.message == WM_QUIT)
				{
				Cleanup();
				exit(0);
				}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
			}
		DrawImage();
		ProcessKBInput();
		MoveAI();
		DetectCollision();

		// Move player and AI:
		X = X + SpeedX;
		Y = Y + SpeedY;

		AIX = AIX + AISpeedX;
		AIY = AIY + AISpeedY;

		P2X = P2X + P2SpeedX;
		P2Y = P2Y + P2SpeedY;

		if(AISpeedX < 0)	AISpeedX += 0.1;
		if(AISpeedX > 0)	AISpeedX -= 0.1;
		if(AISpeedY < 0)	AISpeedY += 0.1;
		if(AISpeedY > 0)	AISpeedY -= 0.1;

		if(SpeedX < 0)	SpeedX += 0.1;
		if(SpeedX > 0)	SpeedX -= 0.1;
		if(SpeedY < 0)	SpeedY += 0.1;
		if(SpeedY > 0)	SpeedY -= 0.1;

		if(P2SpeedX < 0)	P2SpeedX += 0.1;
		if(P2SpeedX > 0)	P2SpeedX -= 0.1;
		if(P2SpeedY < 0)	P2SpeedY += 0.1;
		if(P2SpeedY > 0)	P2SpeedY -= 0.1;
		}
	return (msg.wParam);
}

⌨️ 快捷键说明

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