Я использую этот сайт для изучения DirectX: http://www.rastertek.com/tutdx10.html Я пытаюсь использовать их учебник DirectInput, чтобы добавить больше сочетаний клавиш, кроме Escape. Тем не менее, я не могу получить ключи от огня. Вот соответствующий код:
////////////////////////////////////////////////////////////////////////////////
// Filename: inputclass.cpp
////////////////////////////////////////////////////////////////////////////////
#include "inputclass.h"
InputClass::InputClass()
{
m_directInput = 0;
m_keyboard = 0;
m_mouse = 0;
}InputClass::InputClass(const InputClass& other)
{
}InputClass::~InputClass()
{
}
bool InputClass::Initialize(HINSTANCE hinstance, HWND hwnd, int screenWidth, int screenHeight)
{
HRESULT result;
//Store the screen sizew hcih will be used for positioning the mouse cursor.
m_screenWidth = screenWidth;
m_screenHeight = screenHeight;
//Initialize the location of the mouse on the screen.
m_mouseX = 0;
m_mouseY = 0;
//Initialize the main direct input interface.
result = DirectInput8Create(hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_directInput, NULL);
if(FAILED(result))
{
return false;
}
//Initialize the direct input interface for the keyboard.
result = m_directInput->CreateDevice(GUID_SysKeyboard, &m_keyboard, NULL);
if(FAILED(result))
{
return false;
}
//Set the data format. In this case since it is a keyboard we can use the predefined data format.
result = m_keyboard->SetDataFormat(&c_dfDIKeyboard);
if(FAILED(result))
{
return false;
}
//Set the cooperative level of the keyboard to not share with other programs.
result = m_keyboard->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
if(FAILED(result))
{
return false;
}
//Now aquire the keyboard.
result = m_keyboard->Acquire();
if(FAILED(result))
{
return false;
}
//Initialize the direct input interface for the mouse.
result = m_directInput->CreateDevice(GUID_SysMouse, &m_mouse, NULL);
if(FAILED(result))
{
return false;
}
//Set the data format for the mouse using the pre-defined mouse data format.
result = m_mouse->SetDataFormat(&c_dfDIMouse);
if(FAILED(result))
{
return false;
}
//Set the cooperative level of the mouse to share with other programs.
result = m_mouse->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
if(FAILED(result))
{
return false;
}
//Aquire the mouse.
result = m_mouse->Acquire();
if(FAILED(result))
{
return false;
}
return true;
}
void InputClass::Shutdown()
{
//Release the mouse.
if(m_mouse)
{
m_mouse->Unacquire();
m_mouse->Release();
m_mouse = 0;
}
//Release the keyboard.
if(m_keyboard)
{
m_keyboard->Unacquire();
m_keyboard->Release();
m_keyboard = 0;
}
//Release the main interface to direct input.
if(m_directInput)
{
m_directInput->Release();
m_directInput = 0;
}
return;
}
bool InputClass::Frame()
{
bool result;
//Read the current state of the keyboard.
result = ReadKeyboard();
if(!result)
{
return false;
}
//Read the current state of the mouse.
result = ReadMouse();
if(!result)
{
return false;
}
//Process the changes in the mouse and keyboard.
ProcessInput();
return true;
}bool InputClass::ReadKeyboard()
{
HRESULT result;
//Read the keyboard device.
result = m_keyboard->GetDeviceState(sizeof(m_keyboardState), (LPVOID)&m_keyboardState);
if(FAILED(result))
{
//If the keyboard lost focuse or was not aquired then try to get control back.
if((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED))
{
m_keyboard->Acquire();
}
else
{
return false;
}
}
return true;
}
bool InputClass::ReadMouse()
{
HRESULT result;
//Read the mouse device.
result = m_mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&m_mouseState);
if(FAILED(result))
{
//If the mouse lost focus or was not aqcuired then try to get control back.
if((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED))
{
m_mouse->Acquire();
}
else
{
return false;
}
}
return true;
}
void InputClass::ProcessInput()
{
//Update the location of the mouse cursor based on the change of the mouse location during the frame.
m_mouseX += m_mouseState.lX;
m_mouseY += m_mouseState.lY;
//Ensure the mouse location doesn't exceed the screen width or height.
if(m_mouseX < 0) {m_mouseX = 0;}
if(m_mouseY < 0) {m_mouseY = 0;}
if(m_mouseX > m_screenWidth) {m_mouseX = m_screenWidth;}
if(m_mouseY > m_screenHeight) {m_mouseY = m_screenHeight;}
return;
}
bool InputClass::IsEscapePressed()
{
//Do a bitwise and on the keyboard state to check if the escape key is currently being pressed.
std::cout << "checking ESCAPE" << std::endl;
if(m_keyboardState[DIK_ESCAPE] & 0x80)
{
std::cout << "ESCAPE" << std::endl;
return true;
}
return false;
}
bool InputClass::IsWPressed()
{
if(m_keyboardState[DIK_W] & 0x80)
{
std::cout << "W" << std::endl;
return true;
}
return false;
}
bool InputClass::IsAPressed()
{
if(m_keyboardState[DIK_A] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsSPressed()
{
if(m_keyboardState[DIK_S] & 0x80)
{
return true;
}
return false;
}
bool InputClass::IsDPressed()
{
if(m_keyboardState[DIK_D] & 0x80)
{
return true;
}
return false;
}
void InputClass::GetMouseLocation(int& mouseX, int& mouseY)
{
mouseX = m_mouseX;
mouseY = m_mouseY;
return;
}
Другой файл:
////////////////////////////////////////////////////////////////////////////////
// Filename: systemclass.cpp
////////////////////////////////////////////////////////////////////////////////
#include "systemclass.h"
SystemClass::SystemClass()
{
m_Input = 0;
m_Graphics = 0;
}SystemClass::SystemClass(const SystemClass& other)
{
}SystemClass::~SystemClass()
{
}bool SystemClass::Initialize()
{
int screenWidth, screenHeight;
bool result;// Initialize the width and height of the screen to zero before sending the variables into the function.
screenWidth = 0;
screenHeight = 0;
// Initialize the windows api.
InitializeWindows(screenWidth, screenHeight);
// Create the input object. This object will be used to handle reading the keyboard input from the user.
m_Input = new InputClass;
if(!m_Input)
{
return false;
}
// Initialize the input object.
result = m_Input->Initialize(m_hinstance, m_hwnd, screenWidth, screenHeight);
if(!result)
{
MessageBox(m_hwnd, L"Could not initialize the input object.", L"Error", MB_OK);
return false;
}
// Create the graphics object. This object will handle rendering all the graphics for this application.
m_Graphics = new GraphicsClass;
if(!m_Graphics)
{
return false;
}
// Initialize the graphics object.
result = m_Graphics->Initialize(screenWidth, screenHeight, m_hwnd);
if(!result)
{
return false;
}
return true;
}void SystemClass::Shutdown()
{
// Release the graphics object.
if(m_Graphics)
{
m_Graphics->Shutdown();
delete m_Graphics;
m_Graphics = 0;
}
// Release the input object.
if(m_Input)
{
m_Input->Shutdown();
delete m_Input;
m_Input = 0;
}
// Shutdown the window.
ShutdownWindows();
return;
}void SystemClass::Run()
{
MSG msg;
bool done, result;// Initialize the message structure.
ZeroMemory(&msg, sizeof(MSG));
// Loop until there is a quit message from the window or the user.
done = false;
while(!done)
{
// Handle the windows messages.
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// If windows signals to end the application then exit out.
if(msg.message == WM_QUIT)
{
done = true;
}
else
{
// Otherwise do the frame processing.
result = Frame();
if(!result)
{
done = true;
}
}
//Check if the user pressed escape and wants to quit.
if(m_Input->IsEscapePressed() == true)
{
std::cout << "ESCAPE" << std::endl;
done = true;
}
if(m_Input->IsWPressed() == true)
{
m_Graphics->SetCameraPos(0, 1, 0);
std::cout << "W" << std::endl;
}
if(m_Input->IsAPressed() == true)
{
m_Graphics->SetCameraPos(1, 0, 0);
std::cout << "A" << std::endl;
}
if(m_Input->IsSPressed() == true)
{
m_Graphics->SetCameraPos(0, -1, 0);
std::cout << "S" << std::endl;
}
if(m_Input->IsDPressed() == true)
{
m_Graphics->SetCameraPos(-1, 0, 0);
std::cout << "D" << std::endl;
}
}
return;
}bool SystemClass::Frame()
{
bool result;
int mouseX, mouseY;
//Do the frame processing.
result = m_Input->Frame();
if(!result)
{
return false;
}
//Get the location of the mouse from the input object.
m_Input->GetMouseLocation(mouseX, mouseY);
// Do the frame processing for the graphics object.
result = m_Graphics->Frame(mouseX, mouseY);
if(!result)
{
return false;
}
result = m_Graphics->Render();
if(!result)
{
return false;
}
return true;
}LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
return DefWindowProc(hwnd, umsg, wparam, lparam);
}void SystemClass::InitializeWindows(int& screenWidth, int& screenHeight)
{
WNDCLASSEX wc;
DEVMODE dmScreenSettings;
int posX, posY;// Get an external pointer to this object.
ApplicationHandle = this;
// Get the instance of this application.
m_hinstance = GetModuleHandle(NULL);
// Give the application a name.
m_applicationName = L"Engine";
// Setup the windows class with default settings.
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = m_hinstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hIconSm = wc.hIcon;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = m_applicationName;
wc.cbSize = sizeof(WNDCLASSEX);
// Register the window class.
RegisterClassEx(&wc);
// Determine the resolution of the clients desktop screen.
screenWidth = GetSystemMetrics(SM_CXSCREEN);
screenHeight = GetSystemMetrics(SM_CYSCREEN);
// Setup the screen settings depending on whether it is running in full screen or in windowed mode.
if(FULL_SCREEN)
{
// If full screen set the screen to maximum size of the users desktop and 32bit.
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = (unsigned long)screenWidth;
dmScreenSettings.dmPelsHeight = (unsigned long)screenHeight;
dmScreenSettings.dmBitsPerPel = 32;
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
// Change the display settings to full screen.
ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN);
// Set the position of the window to the top left corner.
posX = posY = 0;
}
else
{
// If windowed then set it to 800x600 resolution.
screenWidth = 800;
screenHeight = 600;
// Place the window in the middle of the screen.
posX = (GetSystemMetrics(SM_CXSCREEN) - screenWidth) / 2;
posY = (GetSystemMetrics(SM_CYSCREEN) - screenHeight) / 2;
}
// Create the window with the screen settings and get the handle to it.
m_hwnd = CreateWindowEx(WS_EX_APPWINDOW, m_applicationName, m_applicationName,
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_POPUP,
posX, posY, screenWidth, screenHeight, NULL, NULL, m_hinstance, NULL);
// Bring the window up on the screen and set it as main focus.
ShowWindow(m_hwnd, SW_SHOW);
SetForegroundWindow(m_hwnd);
SetFocus(m_hwnd);
// Hide the mouse cursor.
ShowCursor(false);
return;
}void SystemClass::ShutdownWindows()
{
// Show the mouse cursor.
ShowCursor(true);
// Fix the display settings if leaving full screen mode.
if(FULL_SCREEN)
{
ChangeDisplaySettings(NULL, 0);
}
// Remove the window.
DestroyWindow(m_hwnd);
m_hwnd = NULL;
// Remove the application instance.
UnregisterClass(m_applicationName, m_hinstance);
m_hinstance = NULL;
// Release the pointer to this class.
ApplicationHandle = NULL;
return;
}LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
{
switch(umessage)
{
// Check if the window is being destroyed.
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
// Check if the window is being closed.
case WM_CLOSE:
{
PostQuitMessage(0);
return 0;
}
// All other messages pass to the message handler in the system class.
default:
{
return ApplicationHandle->MessageHandler(hwnd, umessage, wparam, lparam);
}
}
}
Почему бы не попробовать с GetAsyncKeyState функционировать?
Вы можете положить это в свой Обновить и проверьте требуемый код клавиши.
Что-то вроде этого:
//check if num1 is pressed, if yes switch off the lights.
if(GetAsyncKeyState('1') & 0x8000)
{
mLightCount = 0;
}
Как оказалось, сочетания клавиш работали. Я попытался переключить ключ закрытия на w, и нажатие W закрыло окно. Что было не так, так это то, как я двигал камеру. Спасибо за помощь!