Defender.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /*
  2. * This source file is part of RmlUi, the HTML/CSS Interface Middleware
  3. *
  4. * For the latest information, see http://github.com/mikke89/RmlUi
  5. *
  6. * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
  7. * Copyright (c) 2019-2023 The RmlUi Team, and contributors
  8. *
  9. * Permission is hereby granted, free of charge, to any person obtaining a copy
  10. * of this software and associated documentation files (the "Software"), to deal
  11. * in the Software without restriction, including without limitation the rights
  12. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  13. * copies of the Software, and to permit persons to whom the Software is
  14. * furnished to do so, subject to the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be included in
  17. * all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  22. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  23. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  24. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  25. * THE SOFTWARE.
  26. *
  27. */
  28. #include "Defender.h"
  29. #include "Game.h"
  30. #include "GameDetails.h"
  31. #include "Invader.h"
  32. #include "Mothership.h"
  33. #include "Shield.h"
  34. #include "Sprite.h"
  35. #include <Shell.h>
  36. const float UPDATE_FREQ = 0.01f;
  37. const float MOVEMENT_SPEED = 300;
  38. const float BULLET_SPEED = 15;
  39. const int SPRITE_WIDTH = 64;
  40. const float RESPAWN_TIME = 1.0f;
  41. Sprite defender_sprite(Rml::Vector2f(60, 31), Rml::Vector2f(0, 0.5), Rml::Vector2f(0.23437500, 0.98437500));
  42. Sprite bullet_sprite(Rml::Vector2f(4, 20), Rml::Vector2f(0.4921875, 0.515625), Rml::Vector2f(0.5078125, 0.828125));
  43. Sprite explosion_sprite(Rml::Vector2f(52, 28), Rml::Vector2f(0.71484375f, 0.51562500f), Rml::Vector2f(0.91796875f, 0.95312500f));
  44. Defender::Defender(Game* _game)
  45. {
  46. move_direction = 0;
  47. defender_frame_start = 0;
  48. bullet_in_flight = false;
  49. respawn_start = 0;
  50. game = _game;
  51. position.x = game->GetWindowDimensions().x / 2;
  52. position.y = game->GetWindowDimensions().y - 50;
  53. state = ALIVE;
  54. render = true;
  55. }
  56. Defender::~Defender() {}
  57. void Defender::Update(double t)
  58. {
  59. float dt = float(t - defender_frame_start);
  60. if (dt < UPDATE_FREQ)
  61. return;
  62. dt = Rml::Math::Min(dt, 0.1f);
  63. defender_frame_start = t;
  64. position.x += (move_direction * dt * MOVEMENT_SPEED);
  65. if (position.x < 5)
  66. position.x = 5;
  67. else if (position.x > (game->GetWindowDimensions().x - SPRITE_WIDTH - 5))
  68. position.x = game->GetWindowDimensions().x - SPRITE_WIDTH - 5;
  69. UpdateBullet(t);
  70. if (state == RESPAWN)
  71. {
  72. // Switch the render flag so the defender "flickers"
  73. render = !render;
  74. // Check if we should switch back to our alive state
  75. if (float(t - respawn_start) > RESPAWN_TIME)
  76. {
  77. state = ALIVE;
  78. render = true;
  79. }
  80. }
  81. }
  82. void Defender::Render(Rml::RenderManager& render_manager, float dp_ratio, Rml::Texture texture)
  83. {
  84. Rml::ColourbPremultiplied color = GameDetails::GetDefenderColour().ToPremultiplied();
  85. // Render our sprite if rendering is enabled
  86. if (render)
  87. defender_sprite.Render(render_manager, position, dp_ratio, color, texture);
  88. // Render the bullet
  89. if (bullet_in_flight)
  90. bullet_sprite.Render(render_manager, bullet_position, dp_ratio, color, texture);
  91. }
  92. void Defender::StartMove(float direction)
  93. {
  94. move_direction = direction > 0.0f ? 1.0f : -1.0f;
  95. }
  96. void Defender::StopMove(float direction)
  97. {
  98. float stop_direction = direction > 0.0f ? 1.0f : -1.0f;
  99. if (stop_direction == move_direction)
  100. move_direction = 0.0f;
  101. }
  102. void Defender::Fire()
  103. {
  104. if (!bullet_in_flight)
  105. {
  106. bullet_position = position + Rml::Vector2f((SPRITE_WIDTH / 2) - 4, 0);
  107. bullet_in_flight = true;
  108. }
  109. }
  110. bool Defender::CheckHit(double t, const Rml::Vector2f& check_position)
  111. {
  112. float sprite_width = defender_sprite.dimensions.x;
  113. float sprite_height = defender_sprite.dimensions.y;
  114. // If the position is within our bounds, set ourselves
  115. // as exploding and return a valid hit.
  116. if (state == ALIVE && check_position.x >= position.x && check_position.x <= position.x + sprite_width && check_position.y >= position.y &&
  117. check_position.y <= position.y + sprite_height)
  118. {
  119. game->RemoveLife();
  120. state = RESPAWN;
  121. respawn_start = t;
  122. return true;
  123. }
  124. return false;
  125. }
  126. void Defender::UpdateBullet(double t)
  127. {
  128. if (bullet_in_flight)
  129. {
  130. // Move the bullet up and mark it dead if it flies off the top of the screen
  131. bullet_position.y -= BULLET_SPEED;
  132. if (bullet_position.y < 0)
  133. {
  134. bullet_in_flight = false;
  135. return;
  136. }
  137. // Check if we hit the shields
  138. for (int i = 0; i < game->GetNumShields(); i++)
  139. {
  140. if (game->GetShield(i)->CheckHit(bullet_position))
  141. {
  142. bullet_in_flight = false;
  143. return;
  144. }
  145. }
  146. // Check if we hit any invaders
  147. for (int i = 0; i < game->GetNumInvaders(); i++)
  148. {
  149. if (game->GetInvader(i)->CheckHit(t, bullet_position))
  150. {
  151. bullet_in_flight = false;
  152. return;
  153. }
  154. }
  155. }
  156. }