Advertisement
Cinestra

Project 3 Actor.cpp Progress 2

Jun 2nd, 2023
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.48 KB | None | 0 0
  1. #include "Actor.h"
  2. #include "StudentWorld.h"
  3.  
  4. // Students: Add code to this file, Actor.h, StudentWorld.h, and StudentWorld.cpp
  5.  
  6. #include <iostream>
  7. #include <string>
  8. using namespace std;
  9.  
  10. //
  11. // CHARACTER SECTION
  12. //
  13.  
  14. bool Character::can_move_in_direction(int dir) const
  15. {
  16. int potential_x, potential_y;
  17.  
  18. // getPositionInThisDirection() is used to calculate the position that is a particular distance
  19. // at a particular angle from the object's current position.
  20. //
  21. // void getPositionInThisDirection(int angle, int distance, int& newX, int& newY) const
  22. getPositionInThisDirection(dir, SPRITE_WIDTH, potential_x, potential_y);
  23.  
  24. // Now that we have the potential x and y from moving in that direction, check if it's empty or not
  25. return !(get_world()->is_empty_square(potential_x, potential_y));
  26. }
  27.  
  28. int Character::get_random_direction() const
  29. {
  30. int random_direction = randInt(0, 3) * 90;
  31. while (!can_move_in_direction(random_direction))
  32. random_direction = randInt(0, 3) * 90;
  33. return random_direction;
  34. }
  35.  
  36. void Character::update_sprite_direction()
  37. {
  38. if (m_walk_direction == left)
  39. setDirection(left);
  40. else
  41. setDirection(right);
  42. }
  43.  
  44. void Character::do_corner_turn()
  45. {
  46. // Going left or right prefers going up when possible
  47. if (m_walk_direction == left || m_walk_direction == right)
  48. {
  49. if (can_move_in_direction(up))
  50. m_walk_direction = up;
  51. else
  52. m_walk_direction = down;
  53. }
  54.  
  55. // Going up or down prefers going right when possible
  56. else if (m_walk_direction == up || m_walk_direction == down)
  57. {
  58. if (can_move_in_direction(right))
  59. m_walk_direction = right;
  60. else
  61. m_walk_direction = left;
  62. }
  63. }
  64.  
  65. bool Character::is_at_fork()
  66. {
  67. int number_of_possible_paths = 0;
  68.  
  69. for (int i = 0; i < 360; i += 90)
  70. {
  71. if (can_move_in_direction(i))
  72. number_of_possible_paths++;
  73. }
  74.  
  75. // There will always be one path given because it is the path it came from
  76. // Two paths present means its just moving forward in a given path
  77. // Three paths mean that there is actually a fork
  78. return (number_of_possible_paths > 2);
  79. }
  80.  
  81. //
  82. // PLAYER SECTION
  83. //
  84.  
  85. void Player::do_something()
  86. {
  87. // Two different states to account for
  88.  
  89. if (get_state() == WAITING_TO_ROLL)
  90. {
  91. const int action = get_world()->getAction(m_player_number);
  92.  
  93. if (action == ACTION_ROLL)
  94. {
  95. // Rolling the dice
  96.  
  97. const int dice_roll = randInt(1, 10);
  98. set_ticks(dice_roll * 8);
  99. set_state(WALKING);
  100.  
  101. // Comment the next line out when actually running program
  102. cout << "Rolled a " << dice_roll << endl;
  103. }
  104.  
  105. return;
  106. }
  107.  
  108. if (get_state() == WALKING)
  109. {
  110. // Check to make sure it can actually walk forward
  111. // getX() % SPRITE_WIDTH == 0 && getY() % SPRITE_HEIGHT == 0 means its arrived at a square
  112. if (getX() % SPRITE_WIDTH == 0 && getY() % SPRITE_HEIGHT == 0)
  113. {
  114. // If it cannot move forward, then do a corner turn
  115. if (!can_move_in_direction(get_walk_direction()))
  116. {
  117. do_corner_turn();
  118. update_sprite_direction();
  119. }
  120. }
  121.  
  122. // After the check, simply make it move forward and decrease the ticks
  123. moveAtAngle(get_walk_direction(), 2);
  124. set_ticks(get_ticks() - 1);
  125.  
  126. // Set back to walking state after exhausting all ticks
  127. if (get_ticks() == 0)
  128. set_state(WAITING_TO_ROLL);
  129. }
  130. }
  131.  
  132. //
  133. // BADDIE SECTION
  134. //
  135.  
  136. void Baddie :: do_something()
  137. {
  138. if (get_state() == PAUSED)
  139. {
  140. // players_on_square is DIFFERENT from m_players_on_square
  141. set<Player*> players_on_square;
  142. get_world()->get_players_on_square(players_on_square, getX(), getY());
  143.  
  144. std::set<Player*>::iterator it;
  145. for (it = players_on_square.begin(); it != players_on_square.end(); it++)
  146. {
  147. // See if each object in players_on_square is present in m_players_on_square
  148. // If there is a new object in players_on_square, then we will add it to m_players_on_square
  149. // Then do the baddie behavior
  150. if (m_players_on_square->find(*it) == m_players_on_square->end())
  151. {
  152. m_players_on_square->insert(*it);
  153. do_baddie_behavior(*it);
  154. }
  155. }
  156.  
  157. // Although we've handeled how to add new players to m_players_on_square
  158. // We also need to handle removing players on square if they're not there anymore
  159. // If they were there in the previous step, then they should still have a pointer to the player
  160.  
  161. update_players_on_square(players_on_square);
  162. m_pause_counter--;
  163.  
  164. if (m_pause_counter == 0)
  165. {
  166. // Roll the dice
  167. int squares_to_move = randInt(1, m_max_possible_squares_to_move);
  168. set_ticks(squares_to_move * 8);
  169.  
  170. // Choose random direction to move
  171. int random_direction = get_random_direction();
  172. set_walk_direction(random_direction);
  173. update_sprite_direction();
  174. set_state(WALKING);
  175. }
  176. }
  177.  
  178. if (get_state() == WALKING)
  179. {
  180. // If it has arrived at a square
  181. if (getX() % SPRITE_WIDTH == 0 && getY() % SPRITE_HEIGHT == 0)
  182. {
  183. if (is_at_fork())
  184. {
  185. int random_direction = get_random_direction();
  186. set_walk_direction(random_direction);
  187. }
  188.  
  189. else if (!can_move_in_direction(get_walk_direction()))
  190. do_corner_turn();
  191.  
  192. update_sprite_direction();
  193. }
  194.  
  195. moveAtAngle(get_walk_direction(), 2);
  196. set_ticks(get_ticks() - 1);
  197. if (get_ticks() == 0)
  198. {
  199. set_state(PAUSED);
  200. m_pause_counter = 180;
  201. do_special_pause_behavior();
  202. }
  203. }
  204.  
  205.  
  206. }
  207.  
  208. void Baddie::update_players_on_square(set<Player*>& updated)
  209. {
  210. // Remove all pointers present in m_players_on_square that isn't in updated
  211. auto itr = m_players_on_square->begin();
  212. while (itr != m_players_on_square->end())
  213. {
  214. // Iterate through m_players_on_square and check if each object pointed to is present in updated
  215. // If an object is in m_players_on_square but not on updated, then we will erase that pointer in m_players_on_square
  216. if (updated.find(*itr) == updated.end())
  217. // Erase actually shrinks the set and so we don't need to iterate just yet
  218. itr = m_players_on_square->erase(itr);
  219. else
  220. itr++;
  221. }
  222. }
  223.  
  224. void Baddie::do_impacted_behavior()
  225. {
  226. // Blank for now
  227. }
  228.  
  229. Baddie::~Baddie()
  230. {
  231. // Don't have to delete items that m_players_on_square is pointing to because it will be destructed manually by Student World
  232. m_players_on_square->clear();
  233. delete m_players_on_square;
  234. }
  235.  
  236. //
  237. // BOO SECTION
  238. //
  239.  
  240. void Boo::do_baddie_behavior(Player* player)
  241. {
  242. if (player->get_state() == WAITING_TO_ROLL)
  243. {
  244. Player* other_player = get_world()->get_other_player(player);
  245.  
  246. if (randInt(1, 2) == 1)
  247. {
  248. // 50% chance to swap coins with other player
  249.  
  250. int old_coins = player->get_coins();
  251. player->set_coins(other_player->get_coins());
  252. other_player->set_coins(old_coins);
  253. }
  254.  
  255. else
  256. {
  257. // 50% chance to swap stars with other player
  258.  
  259. int old_stars = player->get_stars();
  260. player->set_stars(other_player->get_stars());
  261. other_player->set_stars(old_stars);
  262. }
  263.  
  264. get_world()->playSound(SOUND_BOO_ACTIVATE);
  265. }
  266. }
  267.  
  268. //
  269. // BOWSER SECTION
  270. //
  271.  
  272. void Bowser::do_baddie_behavior(Player* player)
  273. {
  274. if (player->get_state() == WAITING_TO_ROLL)
  275. {
  276. if (randInt(1, 2) == 1)
  277. {
  278. player->set_stars(0);
  279. player->set_coins(0);
  280. get_world()->playSound(SOUND_BOWSER_ACTIVATE);
  281. }
  282.  
  283. }
  284. }
  285.  
  286. void Bowser::do_special_pause_behavior()
  287. {
  288. // leave blank for now
  289. }
  290.  
  291. //
  292. // SQUARE SECTION
  293. //
  294.  
  295. void Square::do_something()
  296. {
  297.  
  298. // Check if it is still alive/active (since Coin Squares can be destroyed by Bowsers).
  299. // If it is not active, the Coin Square must do nothingand immediately return.
  300.  
  301. if (is_active() == false)
  302. return;
  303. }
  304.  
  305. //
  306. // COIN SQUARE SECTION
  307. //
  308.  
  309.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement