HUD.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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 "HUD.h"
  9. #include "Texture.h"
  10. #include "Shader.h"
  11. #include "Game.h"
  12. #include "Renderer.h"
  13. #include "PhysWorld.h"
  14. #include "FollowActor.h"
  15. #include <algorithm>
  16. #include "GBuffer.h"
  17. #include "TargetComponent.h"
  18. HUD::HUD(Game* game)
  19. :UIScreen(game)
  20. ,mRadarRange(2000.0f)
  21. ,mRadarRadius(92.0f)
  22. ,mTargetEnemy(false)
  23. {
  24. Renderer* r = mGame->GetRenderer();
  25. mHealthBar = r->GetTexture("Assets/HealthBar.png");
  26. mRadar = r->GetTexture("Assets/Radar.png");
  27. mCrosshair = r->GetTexture("Assets/Crosshair.png");
  28. mCrosshairEnemy = r->GetTexture("Assets/CrosshairRed.png");
  29. mBlipTex = r->GetTexture("Assets/Blip.png");
  30. mRadarArrow = r->GetTexture("Assets/RadarArrow.png");
  31. }
  32. HUD::~HUD()
  33. {
  34. }
  35. void HUD::Update(float deltaTime)
  36. {
  37. UIScreen::Update(deltaTime);
  38. UpdateCrosshair(deltaTime);
  39. UpdateRadar(deltaTime);
  40. }
  41. void HUD::Draw(Shader* shader)
  42. {
  43. // Crosshair
  44. //Texture* cross = mTargetEnemy ? mCrosshairEnemy : mCrosshair;
  45. //DrawTexture(shader, cross, Vector2::Zero, 2.0f);
  46. // Radar
  47. const Vector2 cRadarPos(-390.0f, 275.0f);
  48. DrawTexture(shader, mRadar, cRadarPos, 1.0f);
  49. // Blips
  50. for (Vector2& blip : mBlips)
  51. {
  52. DrawTexture(shader, mBlipTex, cRadarPos + blip, 1.0f);
  53. }
  54. // Radar arrow
  55. DrawTexture(shader, mRadarArrow, cRadarPos);
  56. //// Health bar
  57. //DrawTexture(shader, mHealthBar, Vector2(-350.0f, -350.0f));
  58. // Draw the mirror (bottom left)
  59. Texture* mirror = mGame->GetRenderer()->GetMirrorTexture();
  60. DrawTexture(shader, mirror, Vector2(-350.0f, -250.0f), 1.0f, true);
  61. //Texture* tex = mGame->GetRenderer()->GetGBuffer()->GetTexture(GBuffer::EDiffuse);
  62. //DrawTexture(shader, tex, Vector2::Zero, 1.0f, true);
  63. }
  64. void HUD::AddTargetComponent(TargetComponent* tc)
  65. {
  66. mTargetComps.emplace_back(tc);
  67. }
  68. void HUD::RemoveTargetComponent(TargetComponent* tc)
  69. {
  70. auto iter = std::find(mTargetComps.begin(), mTargetComps.end(),
  71. tc);
  72. mTargetComps.erase(iter);
  73. }
  74. void HUD::UpdateCrosshair(float deltaTime)
  75. {
  76. // Reset to regular cursor
  77. mTargetEnemy = false;
  78. // Make a line segment
  79. const float cAimDist = 5000.0f;
  80. Vector3 start, dir;
  81. mGame->GetRenderer()->GetScreenDirection(start, dir);
  82. LineSegment l(start, start + dir * cAimDist);
  83. // Segment cast
  84. PhysWorld::CollisionInfo info;
  85. if (mGame->GetPhysWorld()->SegmentCast(l, info))
  86. {
  87. // Is this a target?
  88. for (auto tc : mTargetComps)
  89. {
  90. if (tc->GetOwner() == info.mActor)
  91. {
  92. mTargetEnemy = true;
  93. break;
  94. }
  95. }
  96. }
  97. }
  98. void HUD::UpdateRadar(float deltaTime)
  99. {
  100. // Clear blip positions from last frame
  101. mBlips.clear();
  102. // Convert player position to radar coordinates (x forward, z up)
  103. Vector3 playerPos = mGame->GetPlayer()->GetPosition();
  104. Vector2 playerPos2D(playerPos.y, playerPos.x);
  105. // Ditto for player forward
  106. Vector3 playerForward = mGame->GetPlayer()->GetForward();
  107. Vector2 playerForward2D(playerForward.x, playerForward.y);
  108. // Use atan2 to get rotation of radar
  109. float angle = Math::Atan2(playerForward2D.y, playerForward2D.x);
  110. // Make a 2D rotation matrix
  111. Matrix3 rotMat = Matrix3::CreateRotation(angle);
  112. // Get positions of blips
  113. for (auto tc : mTargetComps)
  114. {
  115. Vector3 targetPos = tc->GetOwner()->GetPosition();
  116. Vector2 actorPos2D(targetPos.y, targetPos.x);
  117. // Calculate vector between player and target
  118. Vector2 playerToTarget = actorPos2D - playerPos2D;
  119. // See if within range
  120. if (playerToTarget.LengthSq() <= (mRadarRange * mRadarRange))
  121. {
  122. // Convert playerToTarget into an offset from
  123. // the center of the on-screen radar
  124. Vector2 blipPos = playerToTarget;
  125. blipPos *= mRadarRadius/mRadarRange;
  126. // Rotate blipPos
  127. blipPos = Vector2::Transform(blipPos, rotMat);
  128. mBlips.emplace_back(blipPos);
  129. }
  130. }
  131. }