[DirectX]はじめての3Dゲーム:Chapter3

       第3章内容相对简单些,就是通过键盘上的输入来控制上一章坦克的移动,《はじめての3Dゲーム》作者介绍了2种方式实现的案例,第1种就是通过Window自身的消息循环机制和回调函数来处理,第2种就是通过DirectInput实时处理,效果比第1种好很多。

       代码大部分跟上一章内容很相似,就截取一部分不相同的内容。上一章作者为了简化代码和可读性,省去了释放资源这一步,所以上一章的书本代码其实有内存泄漏的,本人改过的代码是没有这个问题的,释放资源的代码都是在FreeDx函数中,也是这章加上的代码。

       第1种方法很简单,就几行代码,不需要多做解释,第2种方法之前在[DirectX]Programming.Role.Playing.Games:03_Input中也有简单介绍,也不细讲了,之前手柄设备的坑也查出问题并解决了。是一个参数的问题,将DI8DEVTYPE_JOYSTICK改成DI8DEVCLASS_GAMECTRL就OK了。

错误代码:

    m_input->EnumDevices(
            DI8DEVTYPE_JOYSTICK,
             (LPDIENUMDEVICESCALLBACKW)EnumJoysticks, 
            this, 
            DIEDFL_ATTACHEDONLY);

正确代码:

    inputDevice->EnumDevices(
		DI8DEVCLASS_GAMECTRL,
		(LPDIENUMDEVICESCALLBACKW)EnumJoystick,
		(LPVOID)&joystickGUID,
		DIEDFL_ATTACHEDONLY);

Chapter3-01源码:

...

#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

...
FLOAT fPosX=270,fPosY=180;

...
VOID FreeDx();

//
//INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szStr,INT iCmdShow)
//アプリケーションのエントリー関数
// 程序的入口函数
INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szStr,INT iCmdShow)
{
	...

	 // メッセージループから抜けたらオブジェクトを全て開放する
	 // 消息循环结束后释放资源
	 FreeDx();

	...
}

//
//LRESULT CALLBACK WndProc(HWND hWnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
// ウィンドウプロシージャ関数
// 窗口回调函数,用于处理消息
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{	
	switch(iMsg)
	{
		case WM_DESTROY:
			PostQuitMessage(0);
		break;
		case WM_KEYDOWN:
		switch((CHAR)wParam)
		{
			case VK_ESCAPE:
				PostQuitMessage(0);
			break;
			// スプライトを操作するための入力処理
			// 根据输入操作Sprite
			case VK_LEFT:
				fPosX-=4;
			break;
			case VK_RIGHT:
				fPosX+=4;
			break;
			case VK_UP:
				fPosY-=4;
			break;
			case VK_DOWN:
				fPosY+=4;
			break;
		}
		break;
	}
	return DefWindowProc (hWnd, iMsg, wParam, lParam) ;	
}

//
//VOID DrawSprite()
//スプライトを描画する関数
// 绘制Sprite函数
VOID DrawSprite()
{
	pDevice->Clear( 0, NULL, D3DCLEAR_TARGET,D3DCOLOR_XRGB(100,100,100), 1.0f, 0 );
	if( SUCCEEDED( pDevice->BeginScene() ) )
	{
		RECT rect={0,0,100,100};
		D3DXVECTOR2 vec2Scale(1.0,1.0);
		D3DXVECTOR2 vec2RotationCenter(1.0,1.0);
		D3DXVECTOR2 vec2Position(fPosX,fPosY);	
		pSprite->Draw(pTexture,&rect,&vec2Scale,&vec2RotationCenter,0,&vec2Position,0xffffffff);
		pDevice->EndScene();
	}	
	pDevice->Present( NULL, NULL, NULL, NULL );	
}
//
//VOID FreeDx()
// 作成したDirectXオブジェクトの開放
// 释放之前创建的DirectX对象
VOID FreeDx()
{	
	SAFE_RELEASE( pTexture );
	SAFE_RELEASE( pSprite );
	SAFE_RELEASE( pDevice );
	SAFE_RELEASE( pD3d );

}

Chapter3-02源码:

...
#include <dinput.h>
...
LPDIRECTINPUT8 pDinput=NULL;         
LPDIRECTINPUTDEVICE8 pKeyDevice=NULL;   
...
HRESULT InitDinput(HWND);
VOID AppProcess();
...

//
//INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szStr,INT iCmdShow)
//アプリケーションのエントリー関数
// 程序的入口函数
INT WINAPI WinMain( HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szStr,INT iCmdShow)
{
	...
	// ダイレクトインプットの初期化関数を呼ぶ
	// 调用DirectInput初始化函数
	if(FAILED(InitDinput(hWnd)))
	{
		return 0;
	}
	// メッセージループ
	// 消息循环
    ZeroMemory( &msg, sizeof(msg) );
    while( msg.message!=WM_QUIT )
     {
		 if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
         {
			 TranslateMessage( &msg );
             DispatchMessage( &msg );
         }
         else
		 {
			 AppProcess();		
		 }                    
	 }
	 // メッセージループから抜けたらオブジェクトを全て開放する
	 // 消息循环结束后释放资源
	 FreeDx();
	 // OSに戻る(アプリケーションを終了する)
	 // 返回操作系统(应用程序结束)
     return (INT)msg.wParam;
}

//
//LRESULT CALLBACK WndProc(HWND hWnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
// ウィンドウプロシージャ関数
// 窗口回调函数,用于处理消息
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{	
	switch(iMsg)
	{
		case WM_DESTROY:			
			PostQuitMessage(0);
		break;
		case WM_KEYDOWN:
		switch((CHAR)wParam)
		{
			case VK_ESCAPE:
				PostQuitMessage(0);
			break;
		}
		break;
	}
	return DefWindowProc (hWnd, iMsg, wParam, lParam) ;	
}

//
//HRESULT InitDinput(HWND hWnd)
//ダイレクトインプットの初期化関数
// DirectInput初始化函数
HRESULT InitDinput(HWND hWnd)
{
	HRESULT hr;
	// 「DirectInput」オブジェクトの作成
	// 创建DirectInput对象
	 if( FAILED( hr = DirectInput8Create( GetModuleHandle(NULL), 
		 DIRECTINPUT_VERSION,IID_IDirectInput8, (VOID**)&pDinput, NULL ) ) )
	 {
		 return hr;
	 }
    // 「DirectInputデバイス」オブジェクトの作成
	// 创建DirectInput设备对象
    if( FAILED( hr = pDinput->CreateDevice( GUID_SysKeyboard,
		&pKeyDevice, NULL ) ) )
	{
		return hr;
	} 
	// デバイスをキーボードに設定
	// 设定设备为键盘
    if( FAILED( hr = pKeyDevice->SetDataFormat( &c_dfDIKeyboard ) ) )
	{
		return hr;
	}
	// 協調レベルの設定
	// 设定合作等级
    if( FAILED(hr= pKeyDevice->SetCooperativeLevel( 
		hWnd,DISCL_NONEXCLUSIVE | DISCL_BACKGROUND )) )
	{
		return hr;
	}
	// デバイスを「取得」する
	// 获取设备
    pKeyDevice->Acquire();
	return S_OK;
}

//
//VOID AppProcess()
//アプリケーション処理関数
//处理应用程序函数
VOID AppProcess()
{
	// スプライトの描画
	// 绘制Sprite
	pDevice->Clear( 0, NULL, D3DCLEAR_TARGET,D3DCOLOR_XRGB(100,100,100), 1.0f, 0 );
	if( SUCCEEDED( pDevice->BeginScene() ) )
	{
		RECT rect={0,0,100,100};
		D3DXVECTOR2 vec2Scale(1.0,1.0);
		D3DXVECTOR2 vec2RotationCenter(1.0,1.0);
		D3DXVECTOR2 vec2Position(fPosX,fPosY);	
		pSprite->Draw(pTexture,&rect,&vec2Scale,&vec2RotationCenter,0,&vec2Position,0xffffffff);
		pDevice->EndScene();
	}
	// キーボードで押されているキーを調べ、対応する方向に移動させる
	// 检测键盘按下的按键,向对应方向移动Sprite
	HRESULT hr=pKeyDevice->Acquire();
	if((hr==DI_OK) || (hr==S_FALSE))
	{
		BYTE diks[256];
		pKeyDevice->GetDeviceState(sizeof(diks),&diks);

		if(diks[DIK_LEFT] & 0x80)
		{
			fPosX-=4;
		}
		if(diks[DIK_RIGHT] & 0x80)
		{
			fPosX+=4;
		}
		if(diks[DIK_UP] & 0x80)
		{
			fPosY-=4;
		}
		if(diks[DIK_DOWN] & 0x80)
		{
			fPosY+=4;
		}
	}	
	pDevice->Present( NULL, NULL, NULL, NULL );	
}
//
//VOID FreeDx()
// 作成したDirectXオブジェクトの開放
// 释放之前创建的DirectX对象
VOID FreeDx()
{		
    if(pKeyDevice) 
	{
		pKeyDevice->Unacquire();
	}
	SAFE_RELEASE( pKeyDevice );
    SAFE_RELEASE( pDinput );
	SAFE_RELEASE( pTexture );
	SAFE_RELEASE( pSprite );
	SAFE_RELEASE( pDevice );
	SAFE_RELEASE( pD3d );
}

自己修改后的代码:

Chapter3-01:

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "legacy_stdio_definitions.lib")
#pragma comment(lib, "DxErr.lib")

#define WIN32_LEAN_AND_MEAN
#define SAFE_RELEASE(p) { if(p) { p->Release(); p = nullptr; } }

#include <Windows.h>
#include <d3dx9.h>
#include <DxErr.h>

#define DEFAULT_WINDOW_TITLE TEXT("DirectX_09_Chapter03-1")
#define DEFAULT_SCREEN_WIDTH 640
#define DEFAULT_SCREEN_HEIGHT 480

IDirect3D9* d3d9;
IDirect3DDevice9* device;
ID3DXSprite* sprite;
IDirect3DTexture9* texture;
float posX = 270, posY = 180;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
HRESULT InitD3D(HWND hwnd);
HRESULT InitSprite();
void Render();
void RenderSprite();
void Release();

int WINAPI WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	WNDCLASSEX wc;
	wc.cbClsExtra = 0;
	wc.cbSize = sizeof(wc);
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hIconSm = wc.hIcon;
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = DEFAULT_WINDOW_TITLE;
	wc.lpszMenuName = nullptr;
	wc.style = CS_HREDRAW | CS_VREDRAW;

	if (!RegisterClassEx(&wc))
	{
		MessageBox(NULL, TEXT("RegisterClassEx function failed"), TEXT("Error"), MB_OK | MB_ICONERROR);
		return 0;
	}

	auto hwnd = CreateWindowEx(WS_EX_APPWINDOW,
		wc.lpszClassName,
		wc.lpszClassName,
		WS_OVERLAPPEDWINDOW,
		0, 0,
		DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT,
		NULL,
		NULL,
		hInstance,
		nullptr);
	if (!hwnd)
	{
		MessageBox(NULL, TEXT("CreateWindowEx function failed"), TEXT("Error"), MB_OK | MB_ICONERROR);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	auto result = InitD3D(hwnd);
	if (FAILED(result))
		return 0;

	MSG msg;
	memset(&msg, 0, sizeof(msg));

	while (msg.message != WM_QUIT)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		Render();
	}

	Release();

	return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_KEYDOWN:
		{
			switch ((char)wParam)
			{
			case VK_ESCAPE:
				PostQuitMessage(0);
				break;
			case 'A':
				posX -= 4;
				break;
			case 'D':
				posX += 4;
				break;
			case 'W':
				posY -= 4;
				break;
			case 'S':
				posY += 4;
				break;
			}
		}
		break;
	}

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

HRESULT InitD3D(HWND hwnd)
{
	d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
	if (!d3d9)
	{
		MessageBox(NULL, TEXT("Direct3DCreate9 function failed"), TEXT("Error"), MB_OK | MB_ICONERROR);
		return E_FAIL;
	}

	D3DPRESENT_PARAMETERS d3dpp;
	memset(&d3dpp, 0, sizeof(d3dpp));
	d3dpp.BackBufferCount = 1;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.Windowed = true;

	auto result = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("The HAL mode of Direct3D device create failed,\ntry to create the REF mode"), result);
		result = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
		if (FAILED(result))
		{
			DXTRACE_ERR_MSGBOX(TEXT("Direct3D device create failed"), result);
			return E_FAIL;
		}
	}

	result = InitSprite();
	if (FAILED(result))
		return E_FAIL;

	return S_OK;
}

HRESULT InitSprite()
{
	auto result = D3DXCreateSprite(device, &sprite);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("D3DXCreateSprite function failed"), result);
		return E_FAIL;
	}

	result = D3DXCreateTextureFromFileEx(device, TEXT("Sprite.bmp"), 100, 100, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
		D3DX_FILTER_NONE, D3DX_DEFAULT, 0xff000000, nullptr, nullptr, &texture);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("D3DXCreateTextureFromFileEx function failed"), result);
		return E_FAIL;
	}

	return S_OK;
}

void Render()
{
	auto color = D3DCOLOR_COLORVALUE(0.5f, 0.5f, 0.5f, 1.0f);
	device->Clear(0, nullptr, D3DCLEAR_TARGET, color, 1.0f, 0);
	device->BeginScene();

	RenderSprite();

	device->EndScene();
	device->Present(nullptr, nullptr, NULL, nullptr);
}

void RenderSprite()
{
	sprite->Begin(D3DXSPRITE_ALPHABLEND);
	RECT rect = { 0, 0, 100, 100 };
	D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 position(posX, posY, 0.0f);
	auto color = D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, 1.0f);
	sprite->Draw(texture, &rect, &center, &position, color);
	sprite->End();
}

void Release()
{
	SAFE_RELEASE(texture);
	SAFE_RELEASE(sprite);
	SAFE_RELEASE(device);
	SAFE_RELEASE(d3d9);
}

Chapter3-02:

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "legacy_stdio_definitions.lib")
#pragma comment(lib, "DxErr.lib")
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")

#define DIRECTINPUT_VERSION 0x0800
#define WIN32_LEAN_AND_MEAN
#define SAFE_RELEASE(p) { if(p) { p->Release(); p = nullptr; } }

#include <Windows.h>
#include <d3dx9.h>
#include <DxErr.h>
#include <dinput.h>

#define DEFAULT_WINDOW_TITLE TEXT("DirectX_09_Chapter03-2")
#define DEFAULT_SCREEN_WIDTH 640
#define DEFAULT_SCREEN_HEIGHT 480

IDirect3D9* d3d9;
IDirect3DDevice9* device;
ID3DXSprite* sprite;
IDirect3DTexture9* texture;
IDirectInput8* input;
IDirectInputDevice8* keyboard;
float posX = 270, posY = 180;

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
HRESULT InitD3D(HWND hwnd);
HRESULT InitSprite();
HRESULT InitInput(HWND hwnd);
void ReadInput();
void Render();
void RenderSprite();
void Release();

int WINAPI WinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPSTR lpCmdLine,
	int nCmdShow)
{
	WNDCLASSEX wc;
	wc.cbClsExtra = 0;
	wc.cbSize = sizeof(wc);
	wc.cbWndExtra = 0;
	wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hIconSm = wc.hIcon;
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = DEFAULT_WINDOW_TITLE;
	wc.lpszMenuName = nullptr;
	wc.style = CS_HREDRAW | CS_VREDRAW;

	if (!RegisterClassEx(&wc))
	{
		MessageBox(NULL, TEXT("RegisterClassEx function failed"), TEXT("Error"), MB_OK | MB_ICONERROR);
		return 0;
	}

	auto hwnd = CreateWindowEx(WS_EX_APPWINDOW,
		wc.lpszClassName,
		wc.lpszClassName,
		WS_OVERLAPPEDWINDOW,
		0, 0,
		DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT,
		NULL,
		NULL,
		hInstance,
		nullptr);
	if (!hwnd)
	{
		MessageBox(NULL, TEXT("CreateWindowEx function failed"), TEXT("Error"), MB_OK | MB_ICONERROR);
		return 0;
	}

	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);

	auto result = InitD3D(hwnd);
	if (FAILED(result))
		return 0;

	result = InitInput(hwnd);
	if (FAILED(result))
		return 0;

	MSG msg;
	memset(&msg, 0, sizeof(msg));

	while (msg.message != WM_QUIT)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		ReadInput();
		Render();
	}

	Release();

	return (int)msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_KEYDOWN:
		{
			switch ((char)wParam)
			{
			case VK_ESCAPE:
				PostQuitMessage(0);
				break;
			}
		}
		break;
	}

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

HRESULT InitD3D(HWND hwnd)
{
	d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
	if (!d3d9)
	{
		MessageBox(NULL, TEXT("Direct3DCreate9 function failed"), TEXT("Error"), MB_OK | MB_ICONERROR);
		return E_FAIL;
	}

	D3DPRESENT_PARAMETERS d3dpp;
	memset(&d3dpp, 0, sizeof(d3dpp));
	d3dpp.BackBufferCount = 1;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.Windowed = true;

	auto result = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("The HAL mode of Direct3D device create failed,\ntry to create the REF mode"), result);
		result = d3d9->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device);
		if (FAILED(result))
		{
			DXTRACE_ERR_MSGBOX(TEXT("Direct3D device create failed"), result);
			return E_FAIL;
		}
	}

	result = InitSprite();
	if (FAILED(result))
		return E_FAIL;

	return S_OK;
}

HRESULT InitSprite()
{
	auto result = D3DXCreateSprite(device, &sprite);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("D3DXCreateSprite function failed"), result);
		return E_FAIL;
	}

	result = D3DXCreateTextureFromFileEx(device, TEXT("Sprite.bmp"), 100, 100, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT,
		D3DX_FILTER_NONE, D3DX_DEFAULT, 0xff000000, nullptr, nullptr, &texture);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("D3DXCreateTextureFromFileEx function failed"), result);
		return E_FAIL;
	}

	return S_OK;
}

HRESULT InitInput(HWND hwnd)
{
	auto result = DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&input, nullptr);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("DirectInput8Create function failed"), result);
		return result;
	}

	result = input->CreateDevice(GUID_SysKeyboard, &keyboard, nullptr);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("DirectInput CreateDevice function failed"), result);
		return result;
	}

	result = keyboard->SetDataFormat(&c_dfDIKeyboard);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("The device of Keyboard SetDataFormat function failed"), result);
		return result;
	}

	result = keyboard->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("The device of Keyboard SetCooperativeLevel function failed"), result);
		return result;
	}

	result = keyboard->Acquire();
	if (FAILED(result))
	{
		DXTRACE_ERR_MSGBOX(TEXT("The device of Keyboard Acquire function failed"), result);
		return result;
	}

	return S_OK;
}

void ReadInput()
{
	auto result = keyboard->Acquire();
	if (DI_OK == result || S_FALSE == result)
	{
		unsigned char keyboardState[256];
		keyboard->GetDeviceState(sizeof(keyboardState), &keyboardState);

		if (keyboardState[DIK_A] & 0x80)
			posX -= 4;
		if (keyboardState[DIK_D] & 0x80)
			posX += 4;
		if (keyboardState[DIK_W] & 0x80)
			posY -= 4;
		if (keyboardState[DIK_S] & 0x80)
			posY += 4;
	}
}

void Render()
{
	auto color = D3DCOLOR_COLORVALUE(0.5f, 0.5f, 0.5f, 1.0f);
	device->Clear(0, nullptr, D3DCLEAR_TARGET, color, 1.0f, 0);
	device->BeginScene();

	RenderSprite();

	device->EndScene();
	device->Present(nullptr, nullptr, NULL, nullptr);
}

void RenderSprite()
{
	sprite->Begin(D3DXSPRITE_ALPHABLEND);
	RECT rect = { 0, 0, 100, 100 };
	D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 position(posX, posY, 0.0f);
	auto color = D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, 1.0f);
	sprite->Draw(texture, &rect, &center, &position, color);
	sprite->End();
}

void Release()
{
	if (keyboard)
		keyboard->Unacquire();
	SAFE_RELEASE(keyboard);
	SAFE_RELEASE(input);
	SAFE_RELEASE(texture);
	SAFE_RELEASE(sprite);
	SAFE_RELEASE(device);
	SAFE_RELEASE(d3d9);
}

源码下载:下载地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值