123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282 |
-
- ////////////////////////////////////////////////////////////
- // Headers
- ////////////////////////////////////////////////////////////
- #include <SFML/Graphics.hpp>
- #include <SFML/Audio.hpp>
- #include <cmath>
- #include <ctime>
- #include <cstdlib>
-
- #ifdef SFML_SYSTEM_IOS
- #include <SFML/Main.hpp>
- #endif
-
- std::string resourcesDir()
- {
- #ifdef SFML_SYSTEM_IOS
- return "";
- #else
- return "resources/";
- #endif
- }
-
- ////////////////////////////////////////////////////////////
- /// Entry point of application
- ///
- /// \return Application exit code
- ///
- ////////////////////////////////////////////////////////////
- int main()
- {
- std::srand(static_cast<unsigned int>(std::time(NULL)));
-
- // Define some constants
- const float pi = 3.14159f;
- const int gameWidth = 800;
- const int gameHeight = 600;
- sf::Vector2f paddleSize(25, 100);
- float ballRadius = 10.f;
-
- // Create the window of the application
- sf::RenderWindow window(sf::VideoMode(gameWidth, gameHeight, 32), "SFML Pong",
- sf::Style::Titlebar | sf::Style::Close);
- window.setVerticalSyncEnabled(true);
-
- // Load the sounds used in the game
- sf::SoundBuffer ballSoundBuffer;
- if (!ballSoundBuffer.loadFromFile(resourcesDir() + "ball.wav"))
- return EXIT_FAILURE;
- sf::Sound ballSound(ballSoundBuffer);
-
- // Create the left paddle
- sf::RectangleShape leftPaddle;
- leftPaddle.setSize(paddleSize - sf::Vector2f(3, 3));
- leftPaddle.setOutlineThickness(3);
- leftPaddle.setOutlineColor(sf::Color::Black);
- leftPaddle.setFillColor(sf::Color(100, 100, 200));
- leftPaddle.setOrigin(paddleSize / 2.f);
-
- // Create the right paddle
- sf::RectangleShape rightPaddle;
- rightPaddle.setSize(paddleSize - sf::Vector2f(3, 3));
- rightPaddle.setOutlineThickness(3);
- rightPaddle.setOutlineColor(sf::Color::Black);
- rightPaddle.setFillColor(sf::Color(200, 100, 100));
- rightPaddle.setOrigin(paddleSize / 2.f);
-
- // Create the ball
- sf::CircleShape ball;
- ball.setRadius(ballRadius - 3);
- ball.setOutlineThickness(3);
- ball.setOutlineColor(sf::Color::Black);
- ball.setFillColor(sf::Color::White);
- ball.setOrigin(ballRadius / 2, ballRadius / 2);
-
- // Load the text font
- sf::Font font;
- if (!font.loadFromFile(resourcesDir() + "sansation.ttf"))
- return EXIT_FAILURE;
-
- // Initialize the pause message
- sf::Text pauseMessage;
- pauseMessage.setFont(font);
- pauseMessage.setCharacterSize(40);
- pauseMessage.setPosition(170.f, 150.f);
- //pauseMessage.setFillColor(sf::Color::White);
-
- #ifdef SFML_SYSTEM_IOS
- pauseMessage.setString("Welcome to SFML pong!\nTouch the screen to start the game");
- #else
- pauseMessage.setString("Welcome to SFML pong!\nPress space to start the game");
- #endif
-
- // Define the paddles properties
- sf::Clock AITimer;
- const sf::Time AITime = sf::seconds(0.1f);
- const float paddleSpeed = 400.f;
- float rightPaddleSpeed = 0.f;
- const float ballSpeed = 400.f;
- float ballAngle = 0.f; // to be changed later
-
- sf::Clock clock;
- bool isPlaying = false;
- while (window.isOpen())
- {
- // Handle events
- sf::Event event;
- while (window.pollEvent(event))
- {
- // Window closed or escape key pressed: exit
- if ((event.type == sf::Event::Closed) ||
- ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape)))
- {
- window.close();
- break;
- }
-
- // Space key pressed: play
- if (((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Space)) ||
- (event.type == sf::Event::TouchBegan))
- {
- if (!isPlaying)
- {
- // (re)start the game
- isPlaying = true;
- clock.restart();
-
- // Reset the position of the paddles and ball
- leftPaddle.setPosition(10 + paddleSize.x / 2, gameHeight / 2);
- rightPaddle.setPosition(gameWidth - 10 - paddleSize.x / 2, gameHeight / 2);
- ball.setPosition(gameWidth / 2, gameHeight / 2);
-
- // Reset the ball angle
- do
- {
- // Make sure the ball initial angle is not too much vertical
- ballAngle = (std::rand() % 360) * 2 * pi / 360;
- }
- while (std::abs(std::cos(ballAngle)) < 0.7f);
- }
- }
-
- // Window size changed, adjust view appropriately
- if (event.type == sf::Event::Resized)
- {
- sf::View view;
- view.setSize(gameWidth, gameHeight);
- view.setCenter(gameWidth/2.f, gameHeight/2.f);
- window.setView(view);
- }
- }
-
- if (isPlaying)
- {
- float deltaTime = clock.restart().asSeconds();
-
- // Move the player's paddle
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up) &&
- (leftPaddle.getPosition().y - paddleSize.y / 2 > 5.f))
- {
- leftPaddle.move(0.f, -paddleSpeed * deltaTime);
- }
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) &&
- (leftPaddle.getPosition().y + paddleSize.y / 2 < gameHeight - 5.f))
- {
- leftPaddle.move(0.f, paddleSpeed * deltaTime);
- }
-
- if (sf::Touch::isDown(0))
- {
- sf::Vector2i pos = sf::Touch::getPosition(0);
- sf::Vector2f mappedPos = window.mapPixelToCoords(pos);
- leftPaddle.setPosition(leftPaddle.getPosition().x, mappedPos.y);
- }
-
- // Move the computer's paddle
- if (((rightPaddleSpeed < 0.f) && (rightPaddle.getPosition().y - paddleSize.y / 2 > 5.f)) ||
- ((rightPaddleSpeed > 0.f) && (rightPaddle.getPosition().y + paddleSize.y / 2 < gameHeight - 5.f)))
- {
- rightPaddle.move(0.f, rightPaddleSpeed * deltaTime);
- }
-
- // Update the computer's paddle direction according to the ball position
- if (AITimer.getElapsedTime() > AITime)
- {
- AITimer.restart();
- if (ball.getPosition().y + ballRadius > rightPaddle.getPosition().y + paddleSize.y / 2)
- rightPaddleSpeed = paddleSpeed;
- else if (ball.getPosition().y - ballRadius < rightPaddle.getPosition().y - paddleSize.y / 2)
- rightPaddleSpeed = -paddleSpeed;
- else
- rightPaddleSpeed = 0.f;
- }
-
- // Move the ball
- float factor = ballSpeed * deltaTime;
- ball.move(std::cos(ballAngle) * factor, std::sin(ballAngle) * factor);
-
- #ifdef SFML_SYSTEM_IOS
- const std::string inputString = "Touch the screen to restart";
- #else
- const std::string inputString = "Press space to restart or\nescape to exit";
- #endif
-
- // Check collisions between the ball and the screen
- if (ball.getPosition().x - ballRadius < 0.f)
- {
- isPlaying = false;
- pauseMessage.setString("You Lost!\n" + inputString);
- }
- if (ball.getPosition().x + ballRadius > gameWidth)
- {
- isPlaying = false;
- pauseMessage.setString("You Won!\n" + inputString);
- }
- if (ball.getPosition().y - ballRadius < 0.f)
- {
- ballSound.play();
- ballAngle = -ballAngle;
- ball.setPosition(ball.getPosition().x, ballRadius + 0.1f);
- }
- if (ball.getPosition().y + ballRadius > gameHeight)
- {
- ballSound.play();
- ballAngle = -ballAngle;
- ball.setPosition(ball.getPosition().x, gameHeight - ballRadius - 0.1f);
- }
-
- // Check the collisions between the ball and the paddles
- // Left Paddle
- if (ball.getPosition().x - ballRadius < leftPaddle.getPosition().x + paddleSize.x / 2 &&
- ball.getPosition().x - ballRadius > leftPaddle.getPosition().x &&
- ball.getPosition().y + ballRadius >= leftPaddle.getPosition().y - paddleSize.y / 2 &&
- ball.getPosition().y - ballRadius <= leftPaddle.getPosition().y + paddleSize.y / 2)
- {
- if (ball.getPosition().y > leftPaddle.getPosition().y)
- ballAngle = pi - ballAngle + (std::rand() % 20) * pi / 180;
- else
- ballAngle = pi - ballAngle - (std::rand() % 20) * pi / 180;
-
- ballSound.play();
- ball.setPosition(leftPaddle.getPosition().x + ballRadius + paddleSize.x / 2 + 0.1f, ball.getPosition().y);
- }
-
- // Right Paddle
- if (ball.getPosition().x + ballRadius > rightPaddle.getPosition().x - paddleSize.x / 2 &&
- ball.getPosition().x + ballRadius < rightPaddle.getPosition().x &&
- ball.getPosition().y + ballRadius >= rightPaddle.getPosition().y - paddleSize.y / 2 &&
- ball.getPosition().y - ballRadius <= rightPaddle.getPosition().y + paddleSize.y / 2)
- {
- if (ball.getPosition().y > rightPaddle.getPosition().y)
- ballAngle = pi - ballAngle + (std::rand() % 20) * pi / 180;
- else
- ballAngle = pi - ballAngle - (std::rand() % 20) * pi / 180;
-
- ballSound.play();
- ball.setPosition(rightPaddle.getPosition().x - ballRadius - paddleSize.x / 2 - 0.1f, ball.getPosition().y);
- }
- }
-
- // Clear the window
- window.clear(sf::Color(50, 200, 50));
-
- if (isPlaying)
- {
- // Draw the paddles and the ball
- window.draw(leftPaddle);
- window.draw(rightPaddle);
- window.draw(ball);
- }
- else
- {
- // Draw the pause message
- window.draw(pauseMessage);
- }
-
- // Display things on screen
- window.display();
- }
-
- return EXIT_SUCCESS;
- }
|