SFML Pong, but object oriented

pong.cpp 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. ////////////////////////////////////////////////////////////
  2. // Headers
  3. ////////////////////////////////////////////////////////////
  4. #include <SFML/Graphics.hpp>
  5. #include <SFML/Audio.hpp>
  6. #include <cmath>
  7. #include <ctime>
  8. #include <cstdlib>
  9. #include "Classes.h"
  10. #ifdef SFML_SYSTEM_IOS
  11. #include <SFML/Main.hpp>
  12. #endif
  13. using namespace std;
  14. string resourcesDir()
  15. {
  16. #ifdef SFML_SYSTEM_IOS
  17. return "";
  18. #else
  19. return "resources/";
  20. #endif
  21. }
  22. ////////////////////////////////////////////////////////////
  23. /// Entry point of application
  24. ///
  25. /// \return Application exit code
  26. ///
  27. ////////////////////////////////////////////////////////////
  28. int main()
  29. {
  30. srand(static_cast<unsigned int>(time(NULL)));
  31. // Define some constants
  32. const float pi = 3.1415;
  33. const int gameWidth = 800;
  34. const int gameHeight = 600;
  35. // Create the window of the application
  36. sf::RenderWindow window(sf::VideoMode(gameWidth, gameHeight, 32), "SFML Pong",
  37. sf::Style::Titlebar | sf::Style::Close);
  38. window.setVerticalSyncEnabled(true);
  39. // Load the sounds used in the game
  40. sf::SoundBuffer ballSoundBuffer;
  41. if (!ballSoundBuffer.loadFromFile(resourcesDir() + "ball.wav"))
  42. return EXIT_FAILURE;
  43. sf::Sound ballSound(ballSoundBuffer);
  44. // Create the left paddle
  45. Paddle leftPaddle;
  46. // Create the right paddle
  47. Paddle rightPaddle;
  48. // Create the ball
  49. Ball ball;
  50. // Load the text font
  51. sf::Font font;
  52. if (!font.loadFromFile(resourcesDir() + "sansation.ttf"))
  53. return EXIT_FAILURE;
  54. // Initialize the pause message
  55. sf::Text pauseMessage;
  56. pauseMessage.setFont(font);
  57. pauseMessage.setCharacterSize(40);
  58. pauseMessage.setPosition(170, 150);
  59. //pauseMessage.setFillColor(sf::Color::White);
  60. #ifdef SFML_SYSTEM_IOS
  61. pauseMessage.setString("Welcome to SFML pong!\nTouch the screen to start the game");
  62. #else
  63. pauseMessage.setString("Welcome to SFML pong!\nPress space to start the game");
  64. #endif
  65. // Define the paddles properties
  66. sf::Clock AITimer;
  67. const sf::Time AITime = sf::seconds(0.1f);
  68. const float paddleSpeed = 400.f;
  69. float rightPaddleSpeed = 0.f; // to be changed later
  70. sf::Clock clock;
  71. bool isPlaying = false;
  72. while (window.isOpen())
  73. {
  74. // Handle events
  75. sf::Event event;
  76. while (window.pollEvent(event))
  77. {
  78. // Window closed or escape key pressed: exit
  79. if ((event.type == sf::Event::Closed) ||
  80. ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
  81. {
  82. window.close();
  83. break;
  84. }
  85. // Space key pressed: play
  86. if (((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Space)) ||
  87. (event.type == sf::Event::TouchBegan))
  88. {
  89. if (!isPlaying)
  90. {
  91. // (re)start the game
  92. isPlaying = true;
  93. clock.restart();
  94. // Reset the position of the paddles and ball
  95. leftPaddle.setPosition(10 + leftPaddle.getSize().x / 2, gameHeight / 2);
  96. rightPaddle.setPosition(gameWidth - 10 - leftPaddle.getSize().x / 2, gameHeight / 2);
  97. ball.setPosition(gameWidth / 2, gameHeight / 2);
  98. // Reset the ball angle
  99. do
  100. {
  101. // Make sure the ball initial angle is not too much vertical
  102. ball.setAngle((rand() % 360) * 2 * pi / 360);
  103. }
  104. while (abs(cos(ball.getAngle())) < 0.7f);
  105. }
  106. }
  107. // Window size changed, adjust view appropriately
  108. if (event.type == sf::Event::Resized)
  109. {
  110. sf::View view;
  111. view.setSize(gameWidth, gameHeight);
  112. view.setCenter(gameWidth/2.f, gameHeight/2.f);
  113. window.setView(view);
  114. }
  115. }
  116. if (isPlaying)
  117. {
  118. float deltaTime = clock.restart().asSeconds();
  119. // Move the player's paddle
  120. if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) &&
  121. (leftPaddle.getY() - leftPaddle.getSize().y / 2 > 5))
  122. {
  123. leftPaddle.move(0.f, -paddleSpeed * deltaTime);
  124. }
  125. if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) &&
  126. (leftPaddle.getY() + leftPaddle.getSize().y / 2 < gameHeight - 5))
  127. {
  128. leftPaddle.move(0.f, paddleSpeed * deltaTime);
  129. }
  130. if (sf::Touch::isDown(0))
  131. {
  132. sf::Vector2i pos = sf::Touch::getPosition(0);
  133. sf::Vector2f mappedPos = window.mapPixelToCoords(pos);
  134. leftPaddle.setPosition(leftPaddle.getX(), mappedPos.y);
  135. }
  136. // Move the computer's paddle
  137. if (((rightPaddleSpeed < 0.f) && (rightPaddle.getY() - leftPaddle.getSize().y / 2 > 5.f)) ||
  138. ((rightPaddleSpeed > 0.f) && (rightPaddle.getY() + leftPaddle.getSize().y / 2 < gameHeight - 5.f)))
  139. {
  140. rightPaddle.move(0.f, rightPaddleSpeed * deltaTime);
  141. }
  142. // Update the computer's paddle direction according to the ball position
  143. if (AITimer.getElapsedTime() > AITime)
  144. {
  145. AITimer.restart();
  146. if (ball.getY() + ball.getRadius() > rightPaddle.getY() + leftPaddle.getSize().y / 2)
  147. rightPaddleSpeed = paddleSpeed;
  148. else if (ball.getY() - ball.getRadius() < rightPaddle.getY() - leftPaddle.getSize().y / 2)
  149. rightPaddleSpeed = -paddleSpeed;
  150. else
  151. rightPaddleSpeed = 0.f;
  152. }
  153. // Move the ball
  154. float factor = ball.getSpeed() * deltaTime;
  155. ball.move(cos(ball.getAngle()) * factor, sin(ball.getAngle()) * factor);
  156. #ifdef SFML_SYSTEM_IOS
  157. const string inputString = "Touch the screen to restart";
  158. #else
  159. const string inputString = "Press space to restart or\nescape to exit";
  160. #endif
  161. // Check collisions between the ball and the screen
  162. if (ball.getX() - ball.getRadius() < 0)
  163. {
  164. isPlaying = false;
  165. pauseMessage.setString("You Lost!\n" + inputString);
  166. }
  167. if (ball.getX() + ball.getRadius() > gameWidth)
  168. {
  169. isPlaying = false;
  170. pauseMessage.setString("You Won!\n" + inputString);
  171. }
  172. if (ball.getY() - ball.getRadius() < 0.f)
  173. {
  174. ballSound.play();
  175. ball.setAngle(-ball.getAngle());
  176. ball.setPosition(ball.getX(), ball.getRadius() + 0.1f);
  177. }
  178. if (ball.getY() + ball.getRadius() > gameHeight)
  179. {
  180. ballSound.play();
  181. ball.setAngle(-ball.getAngle());
  182. ball.setPosition(ball.getX(), gameHeight - ball.getRadius() - 0.1f);
  183. }
  184. // Check the collisions between the ball and the paddles
  185. // Left Paddle
  186. ball.checkLeftPaddle(leftPaddle, ballSound);
  187. // Right Paddle
  188. ball.checkRightPaddle(rightPaddle, ballSound);
  189. }
  190. // Clear the window
  191. window.clear(sf::Color(50, 200, 50));
  192. if (isPlaying)
  193. {
  194. // Draw the paddles and the ball
  195. window.draw(leftPaddle);
  196. window.draw(rightPaddle);
  197. window.draw(ball);
  198. }
  199. else
  200. {
  201. // Draw the pause message
  202. window.draw(pauseMessage);
  203. }
  204. // Display things on screen
  205. window.display();
  206. }
  207. return EXIT_SUCCESS;
  208. }