text: ////////////////////////////////////////////////////////////
  // Headers
  ////////////////////////////////////////////////////////////
  #include <SFML/Graphics.hpp>
  #include <SFML/Audio.hpp>
  #include <cmath>
  
  
  ////////////////////////////////////////////////////////////
  /// Entry point of application
  ///
  /// \return Application exit code
  ///
  ////////////////////////////////////////////////////////////
  int main()
  {
  	// Defines PI
  	const float PI = 3.14159f;
  
      // Create the window of the application
      sf::RenderWindow App(sf::VideoMode(800, 600, 32), "SFML Pong");
  
      // Load the sounds used in the game
      sf::SoundBuffer BallSoundBuffer;
      if (!BallSoundBuffer.LoadFromFile("datas/pong/ball.wav"))
      {
          return EXIT_FAILURE;
      }
      sf::Sound BallSound(BallSoundBuffer);
  
      // Load the images used in the game
      sf::Image BackgroundImage, LeftPaddleImage, RightPaddleImage, BallImage;
      if (!BackgroundImage.LoadFromFile("datas/pong/background.jpg")    ||
          !LeftPaddleImage.LoadFromFile("datas/pong/paddle_left.png")   ||
          !RightPaddleImage.LoadFromFile("datas/pong/paddle_right.png") ||
          !BallImage.LoadFromFile("datas/pong/ball.png"))
      {
          return EXIT_FAILURE;
      }
  
      // Load the text font
      sf::Font Cheeseburger;
      if (!Cheeseburger.LoadFromFile("datas/pong/cheeseburger.ttf"))
          return EXIT_FAILURE;
  
  	// Initialize the end text
  	sf::String End;
      End.SetFont(Cheeseburger);
  	End.SetSize(60.f);
      End.Move(150.f, 200.f);
      End.SetColor(sf::Color(50, 50, 250));
  
      // Create the sprites of the background, the paddles and the ball
      sf::Sprite Background(BackgroundImage);
      sf::Sprite LeftPaddle(LeftPaddleImage);
      sf::Sprite RightPaddle(RightPaddleImage);
      sf::Sprite Ball(BallImage);
  
      LeftPaddle.Move(10, (App.GetView().GetRect().GetHeight() - LeftPaddle.GetSize().y) / 2);
      RightPaddle.Move(App.GetView().GetRect().GetWidth() - RightPaddle.GetSize().x - 10, (App.GetView().GetRect().GetHeight() - RightPaddle.GetSize().y) / 2);
      Ball.Move((App.GetView().GetRect().GetWidth() - Ball.GetSize().x) / 2, (App.GetView().GetRect().GetHeight() - Ball.GetSize().y) / 2);
  
      // Define the paddles properties
      sf::Clock AITimer;
  	const float AITime     = 0.1f;
      float LeftPaddleSpeed  = 400.f;
      float RightPaddleSpeed = 400.f;
  
      // Define the ball properties
      float BallSpeed = 400.f;
      float BallAngle;
      do
      {
          // Make sure the ball initial angle is not too much vertical
          BallAngle = sf::Randomizer::Random(0.f, 2 * PI);
      } while (std::abs(std::cos(BallAngle)) < 0.7f);
  
  	bool IsPlaying = true;
      while (App.IsOpened())
      {
          // Handle events
          sf::Event Event;
          while (App.GetEvent(Event))
          {
              // Window closed or escape key pressed : exit
              if ((Event.Type == sf::Event::Closed) ||
                 ((Event.Type == sf::Event::KeyPressed) && (Event.Key.Code == sf::Key::Escape)))
              {
                  App.Close();
                  break;
              }
          }
  
          if (IsPlaying)
  		{
  			// Move the player's paddle
              if (App.GetInput().IsKeyDown(sf::Key::Up) && (LeftPaddle.GetPosition().y > 5.f))
  				LeftPaddle.Move(0.f, -LeftPaddleSpeed * App.GetFrameTime());
              if (App.GetInput().IsKeyDown(sf::Key::Down) && (LeftPaddle.GetPosition().y < App.GetView().GetRect().GetHeight() - LeftPaddle.GetSize().y - 5.f))
  				LeftPaddle.Move(0.f, LeftPaddleSpeed * App.GetFrameTime());
  
  			// Move the computer's paddle
              if (((RightPaddleSpeed < 0.f) && (RightPaddle.GetPosition().y > 5.f)) ||
                  ((RightPaddleSpeed > 0.f) && (RightPaddle.GetPosition().y < App.GetView().GetRect().GetHeight() - RightPaddle.GetSize().y - 5.f)))
              {
                  RightPaddle.Move(0.f, RightPaddleSpeed * App.GetFrameTime());
              }
  
              // Update the computer's paddle direction according to the ball position
              if (AITimer.GetElapsedTime() > AITime)
              {
                  AITimer.Reset();
                  if ((RightPaddleSpeed < 0) && (Ball.GetPosition().y + Ball.GetSize().y > RightPaddle.GetPosition().y + RightPaddle.GetSize().y))
                      RightPaddleSpeed = -RightPaddleSpeed;
                  if ((RightPaddleSpeed > 0) && (Ball.GetPosition().y < RightPaddle.GetPosition().y))
                      RightPaddleSpeed = -RightPaddleSpeed;
              }
  
  			// Move the ball
  			float Factor = BallSpeed * App.GetFrameTime();
              Ball.Move(std::cos(BallAngle) * Factor, std::sin(BallAngle) * Factor);
  
  			// Check collisions between the ball and the screen
  			if (Ball.GetPosition().x < 0.f)
  			{
  				IsPlaying = false;
  				End.SetText("You lost !\n(press escape to exit)");
  			}
  			if (Ball.GetPosition().x + Ball.GetSize().x > App.GetView().GetRect().GetWidth())
  			{
  				IsPlaying = false;
  				End.SetText("You won !\n(press escape to exit)");
  			}
  			if (Ball.GetPosition().y < 0.f)
  			{
  				BallSound.Play();
  				BallAngle = -BallAngle;
  				Ball.SetY(0.1f);
  			}
  			if (Ball.GetPosition().y + Ball.GetSize().y > App.GetView().GetRect().GetHeight())
  			{
  				BallSound.Play();
  				BallAngle = -BallAngle;
  				Ball.SetY(App.GetView().GetRect().GetHeight() - Ball.GetSize().y - 0.1f);
  			}
  
  			// Check the collisions between the ball and the paddles
  			// Left Paddle
  			if (Ball.GetPosition().x < LeftPaddle.GetPosition().x + LeftPaddle.GetSize().x &&
  				Ball.GetPosition().x > LeftPaddle.GetPosition().x + (LeftPaddle.GetSize().x / 2.0f) &&
  				Ball.GetPosition().y + Ball.GetSize().y >= LeftPaddle.GetPosition().y &&
  				Ball.GetPosition().y <= LeftPaddle.GetPosition().y + LeftPaddle.GetSize().y)
  			{
  				BallSound.Play();
  				BallAngle = PI - BallAngle;
  				Ball.SetX(LeftPaddle.GetPosition().x + LeftPaddle.GetSize().x + 0.1f);
  			}
  
  			// Right Paddle
  			if (Ball.GetPosition().x + Ball.GetSize().x > RightPaddle.GetPosition().x &&
  				Ball.GetPosition().x + Ball.GetSize().x < RightPaddle.GetPosition().x + (RightPaddle.GetSize().x / 2.0f) &&
  				Ball.GetPosition().y + Ball.GetSize().y >= RightPaddle.GetPosition().y &&
  				Ball.GetPosition().y <= RightPaddle.GetPosition().y + RightPaddle.GetSize().y)
  			{
  				BallSound.Play();
  				BallAngle = PI - BallAngle;
  				Ball.SetX(RightPaddle.GetPosition().x - Ball.GetSize().x - 0.1f);
  			}
  		}
  
          // Clear the window
          App.Clear();
  
          // Draw the background, paddles and ball sprites
          App.Draw(Background);
          App.Draw(LeftPaddle);
          App.Draw(RightPaddle);
          App.Draw(Ball);
  
          // If the game is over, display the end message
          if (!IsPlaying)
              App.Draw(End);
  
          // Display things on screen
          App.Display();
      }
  
      return EXIT_SUCCESS;
  }
  