0

我正在使用这个网站来学习 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);
        }
    }
}
4

2 回答 2

0

事实证明,键绑定正在工作。我尝试将关闭键切换到 w 并按 W 关闭窗口。问题是我移动相机的方式。感谢您的帮助!

于 2013-08-18T18:46:11.780 回答
0

为什么不尝试使用GetAsyncKeyState函数?

您可以将其放入更新功能并检查所需的密钥代码。像这样的东西:

//check if num1 is pressed, if yes switch off the lights.
if(GetAsyncKeyState('1') & 0x8000)
{
    mLightCount = 0; 
}
于 2013-08-18T01:51:36.500 回答