首页 > 代码库 > 游戏框架其九:WASD方向控制 { MovementController }
游戏框架其九:WASD方向控制 { MovementController }
下面实现的方向控制是基于键盘上的W A S D,来控制运动物体的方向的。下面是实现~
#pragma once //======================================================================== // File: MovementController.h 就是实现键盘按钮 WASD 的方向控制 //======================================================================== #include "../GameCode4/Interfaces.h" #include "Geometry.h" // Forward declarations class SceneNode; typedef unsigned int DWORD; typedef unsigned short WORD; typedef unsigned char BYTE; typedef unsigned int ActorId; typedef unsigned int GameViewId; typedef D3DXCOLOR Color; typedef float FLOAT; typedef unsigned int UINT; #ifdef UNICODE typedef wchar_t TCHAR; #else typedef unsigned char TCHAR; #endif typedef unsigned char CHAR; typedef unsigned wchar_t WCHAR; enum HRESULT { E_INVALIDARG, E_FAIL, S_OK, }; //////////////////////////////////////////////////// // // MovementController Description // // Implements a WASD style movement controller // // class MovementController // //////////////////////////////////////////////////// class IPointerHandler { public: virtual bool VOnPointerMove(const Point &pos, const int radius) = 0; virtual bool VOnPointerButtonDown(const Point &pos, const int radius, const std::string &buttonName) = 0; virtual bool VOnPointerButtonUp(const Point &pos, const int radius, const std::string &buttonName) = 0; }; class IKeyboardHandler { public: virtual bool VOnKeyDown(const BYTE c)=0; virtual bool VOnKeyUp(const BYTE c)=0; }; class MovementController : public IPointerHandler, public IKeyboardHandler { protected: Mat4x4 m_matFromWorld; Mat4x4 m_matToWorld; Mat4x4 m_matPosition; Point m_lastMousePos; bool m_bKey[256]; // Which keys are up and down // Orientation Controls float m_fTargetYaw; float m_fTargetPitch; float m_fYaw; float m_fPitch; float m_fPitchOnDown; float m_fYawOnDown; float m_maxSpeed; float m_currentSpeed; // Added for Ch19/20 refactor bool m_mouseLButtonDown; bool m_bRotateWhenLButtonDown; shared_ptr<SceneNode> m_object; public: MovementController(shared_ptr<SceneNode> object, float initialYaw, float initialPitch, bool rotateWhenLButtonDown); void SetObject(shared_ptr<SceneNode> newObject); void OnUpdate(DWORD const elapsedMs); public: bool VOnPointerMove(const Point &mousePos, const int radius); bool VOnPointerButtonDown(const Point &mousePos, const int radius, const std::string &buttonName); bool VOnPointerButtonUp(const Point &mousePos, const int radius, const std::string &buttonName); bool VOnKeyDown(const BYTE c) { m_bKey[c] = true; return true; } bool VOnKeyUp(const BYTE c) { m_bKey[c] = false; return true; } const Mat4x4 *GetToWorld() { return &m_matToWorld; } const Mat4x4 *GetFromWorld() { return &m_matFromWorld; } };
//======================================================================== // File: MovementController.cpp //======================================================================== #include "GameCodeStd.h" #include "Geometry.h" #include "MovementController.h" #include "SceneNodes.h" //////////////////////////////////////////////////// // MovementController Implementation //////////////////////////////////////////////////// #define MAX(a, b) ((a) >= (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) MovementController::MovementController(shared_ptr<SceneNode> object, float initialYaw, float initialPitch, bool rotateWhenLButtonDown) : m_object(object) { m_object->VGet()->Transform(&m_matToWorld, &m_matFromWorld); m_fTargetYaw = m_fYaw = RADIANS_TO_DEGREES(-initialYaw); m_fTargetPitch = m_fPitch = RADIANS_TO_DEGREES(initialPitch); m_maxSpeed = 30.0f; // 30 meters per second m_currentSpeed = 0.0f; Vec3 pos = m_matToWorld.GetPosition(); m_matPosition.BuildTranslation(pos); POINT ptCursor; GetCursorPos( &ptCursor ); m_lastMousePos = ptCursor; memset(m_bKey, 0x00, sizeof(m_bKey)); m_mouseLButtonDown = false; m_bRotateWhenLButtonDown = rotateWhenLButtonDown; } // // MovementController::VOnPointerButtonDown // bool MovementController::VOnPointerButtonDown(const Point &mousePos, const int radius, const std::string &buttonName) { if (buttonName == "PointerLeft") { m_mouseLButtonDown = true; // We want mouse movement to be relative to the position // the cursor was at when the user first presses down on // the left button m_lastMousePos = mousePos; return true; } return false; } bool MovementController::VOnPointerButtonUp(const Point &mousePos, const int radius, const std::string &buttonName) { if (buttonName == "PointerLeft") { m_mouseLButtonDown = false; return true; } return false; } // class MovementController::VOnMouseMove bool MovementController::VOnPointerMove(const Point &mousePos, const int radius) { // There are two modes supported by this controller. if (m_bRotateWhenLButtonDown) { // Mode 1 - rotate the view only when the left mouse button is down // Only look around if the left button is down if(m_lastMousePos!=mousePos && m_mouseLButtonDown) { m_fTargetYaw = m_fTargetYaw + (m_lastMousePos.x - mousePos.x); m_fTargetPitch = m_fTargetPitch + (mousePos.y - m_lastMousePos.y); m_lastMousePos = mousePos; } } else if(m_lastMousePos!=mousePos) { // Mode 2 - rotate the controller when the mouse buttons are up m_fTargetYaw = m_fTargetYaw + (m_lastMousePos.x - mousePos.x); m_fTargetPitch = m_fTargetPitch + (mousePos.y - m_lastMousePos.y); m_lastMousePos = mousePos; } return true; } // class MovementController::OnUpdate void MovementController::OnUpdate(DWORD const deltaMilliseconds) { //if (m_bKey['Q']) //{ // // This code is a cheat to position the camera exactly in a given // // spot so I can take screen shots! // Mat4x4 camTranslate; // D3DXMatrixTranslation(&m_matPosition, 8.847f, 7.055f, 11.618f); // m_fTargetYaw = m_fYaw += -64.35f; // m_fTargetPitch = m_fPitch = 28.57f; // // Calculate the new rotation matrix from the camera // // yaw and pitch. // Mat4x4 matRot; // D3DXMatrixRotationYawPitchRoll(&matRot, DEGREES_TO_RADIANS(m_fYaw), DEGREES_TO_RADIANS(m_fPitch), 0); // // Create the new object-to-world matrix, and the // // new world-to-object matrix. // D3DXMatrixMultiply(&m_matToWorld, &matRot, &m_matPosition); // D3DXMatrixInverse(&m_matFromWorld, NULL, &m_matToWorld); // m_object->VSetTransform(&m_matToWorld, &m_matFromWorld); // return; //} bool bTranslating = false; Vec4 atWorld(0,0,0,0); Vec4 rightWorld(0,0,0,0); Vec4 upWorld(0,0,0,0); if (m_bKey['W'] || m_bKey['S']) { // In D3D, the "look at" default is always // the positive Z axis. Vec4 at = g_Forward4; if (m_bKey['S']) at *= -1; // This will give us the "look at" vector // in world space - we'll use that to move // the camera. atWorld = m_matToWorld.Xform(at); bTranslating = true; } if (m_bKey['A'] || m_bKey['D']) { // In D3D, the "right" default is always // the positive X axis. Vec4 right = g_Right4; if (m_bKey['A']) right *= -1; // This will give us the "right" vector // in world space - we'll use that to move // the camera rightWorld = m_matToWorld.Xform(right); bTranslating = true; } if (m_bKey[' '] || m_bKey['C'] || m_bKey['X']) { // In D3D, the "up" default is always // the positive Y axis. Vec4 up = g_Right4; if (!m_bKey[' ']) up *= -1; //Unlike strafing, Up is always up no matter //which way you are looking upWorld = up; bTranslating = true; } //Handling rotation as a result of mouse position { // The secret formula!!! Don't give it away! //If you are seeing this now, then you must be some kind of elite hacker! m_fYaw += (m_fTargetYaw - m_fYaw) * ( .35f ); m_fTargetPitch = MAX(-90, MIN(90, m_fTargetPitch)); m_fPitch += (m_fTargetPitch - m_fPitch) * ( .35f ); // Calculate the new rotation matrix from the camera // yaw and pitch. Mat4x4 matRot; matRot.BuildYawPitchRoll(DEGREES_TO_RADIANS(-m_fYaw), DEGREES_TO_RADIANS(m_fPitch), 0); // Create the new object-to-world matrix, and the // new world-to-object matrix. m_matToWorld = matRot * m_matPosition; m_matFromWorld = m_matToWorld.Inverse(); m_object->VSetTransform(&m_matToWorld, &m_matFromWorld); } if (bTranslating) { float elapsedTime = (float)deltaMilliseconds / 1000.0f; Vec3 direction = atWorld + rightWorld + upWorld; direction.Normalize(); // Ramp the acceleration by the elapsed time. float numberOfSeconds = 5.f; m_currentSpeed += m_maxSpeed * ( (elapsedTime*elapsedTime) / numberOfSeconds); if (m_currentSpeed > m_maxSpeed) m_currentSpeed = m_maxSpeed; direction *= m_currentSpeed; Vec3 pos = m_matPosition.GetPosition() + direction; m_matPosition.SetPosition(pos); m_matToWorld.SetPosition(pos); m_matFromWorld = m_matToWorld.Inverse(); m_object->VSetTransform(&m_matToWorld, &m_matFromWorld); } else { m_currentSpeed = 0.0f; } }以上是方向实现,下一篇是关于场景和场景节点( Scene , SceneNode )~~
游戏框架其九:WASD方向控制 { MovementController }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。