FPSActor.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // ----------------------------------------------------------------
  2. // From Game Programming in C++ by Sanjay Madhav
  3. // Copyright (C) 2017 Sanjay Madhav. All rights reserved.
  4. //
  5. // Released under the BSD License
  6. // See LICENSE in root directory for full details.
  7. // ----------------------------------------------------------------
  8. #include "FPSActor.h"
  9. #include "MoveComponent.h"
  10. #include "SDL/SDL_scancode.h"
  11. #include "Renderer.h"
  12. #include "AudioSystem.h"
  13. #include "Game.h"
  14. #include "AudioComponent.h"
  15. #include "FPSCamera.h"
  16. #include "MeshComponent.h"
  17. FPSActor::FPSActor(Game* game)
  18. :Actor(game)
  19. {
  20. mMoveComp = new MoveComponent(this);
  21. mAudioComp = new AudioComponent(this);
  22. mLastFootstep = 0.0f;
  23. mFootstep = mAudioComp->PlayEvent("event:/Footstep");
  24. mFootstep.SetPaused(true);
  25. mCameraComp = new FPSCamera(this);
  26. mFPSModel = new Actor(game);
  27. mFPSModel->SetScale(0.75f);
  28. mMeshComp = new MeshComponent(mFPSModel);
  29. mMeshComp->SetMesh(game->GetRenderer()->GetMesh("Assets/Rifle.gpmesh"));
  30. }
  31. void FPSActor::UpdateActor(float deltaTime)
  32. {
  33. Actor::UpdateActor(deltaTime);
  34. // Play the footstep if we're moving and haven't recently
  35. mLastFootstep -= deltaTime;
  36. if (!Math::NearZero(mMoveComp->GetForwardSpeed()) && mLastFootstep <= 0.0f)
  37. {
  38. mFootstep.SetPaused(false);
  39. mFootstep.Restart();
  40. mLastFootstep = 0.5f;
  41. }
  42. // Update position of FPS model relative to actor position
  43. const Vector3 modelOffset(Vector3(10.0f, 10.0f, -10.0f));
  44. Vector3 modelPos = GetPosition();
  45. modelPos += GetForward() * modelOffset.x;
  46. modelPos += GetRight() * modelOffset.y;
  47. modelPos.z += modelOffset.z;
  48. mFPSModel->SetPosition(modelPos);
  49. // Initialize rotation to actor rotation
  50. Quaternion q = GetRotation();
  51. // Rotate by pitch from camera
  52. q = Quaternion::Concatenate(q, Quaternion(GetRight(), mCameraComp->GetPitch()));
  53. mFPSModel->SetRotation(q);
  54. }
  55. void FPSActor::ActorInput(const uint8_t* keys)
  56. {
  57. float forwardSpeed = 0.0f;
  58. float strafeSpeed = 0.0f;
  59. // wasd movement
  60. if (keys[SDL_SCANCODE_W])
  61. {
  62. forwardSpeed += 400.0f;
  63. }
  64. if (keys[SDL_SCANCODE_S])
  65. {
  66. forwardSpeed -= 400.0f;
  67. }
  68. if (keys[SDL_SCANCODE_A])
  69. {
  70. strafeSpeed -= 400.0f;
  71. }
  72. if (keys[SDL_SCANCODE_D])
  73. {
  74. strafeSpeed += 400.0f;
  75. }
  76. mMoveComp->SetForwardSpeed(forwardSpeed);
  77. mMoveComp->SetStrafeSpeed(strafeSpeed);
  78. // Mouse movement
  79. // Get relative movement from SDL
  80. int x, y;
  81. SDL_GetRelativeMouseState(&x, &y);
  82. // Assume mouse movement is usually between -500 and +500
  83. const int maxMouseSpeed = 500;
  84. // Rotation/sec at maximum speed
  85. const float maxAngularSpeed = Math::Pi * 8;
  86. float angularSpeed = 0.0f;
  87. if (x != 0)
  88. {
  89. // Convert to ~[-1.0, 1.0]
  90. angularSpeed = static_cast<float>(x) / maxMouseSpeed;
  91. // Multiply by rotation/sec
  92. angularSpeed *= maxAngularSpeed;
  93. }
  94. mMoveComp->SetAngularSpeed(angularSpeed);
  95. // Compute pitch
  96. const float maxPitchSpeed = Math::Pi * 8;
  97. float pitchSpeed = 0.0f;
  98. if (y != 0)
  99. {
  100. // Convert to ~[-1.0, 1.0]
  101. pitchSpeed = static_cast<float>(y) / maxMouseSpeed;
  102. pitchSpeed *= maxPitchSpeed;
  103. }
  104. mCameraComp->SetPitchSpeed(pitchSpeed);
  105. }
  106. void FPSActor::SetFootstepSurface(float value)
  107. {
  108. // Pause here because the way I setup the parameter in FMOD
  109. // changing it will play a footstep
  110. mFootstep.SetPaused(true);
  111. mFootstep.SetParameter("Surface", value);
  112. }
  113. void FPSActor::SetVisible(bool visible)
  114. {
  115. mMeshComp->SetVisible(visible);
  116. }