123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- ////////////////////////////////////////////////////////////
- // Headers
- ////////////////////////////////////////////////////////////
- #include <SFML/Graphics.hpp>
- #include <SFML/Audio.hpp>
- #include <cmath>
- #include <ctime>
- #include <cstdlib>
- #include "Ball.h"
- #include "Paddle.h"
-
- #ifdef SFML_SYSTEM_IOS
- #include <SFML/Main.hpp>
- #endif
-
- using namespace std;
-
- string resourcesDir()
- {
- #ifdef SFML_SYSTEM_IOS
- return "";
- #else
- return "resources/";
- #endif
- }
-
-
- ////////////////////////////////////////////////////////////
- /// Entry point of application
- ///
- /// \return Application exit code
- ///
- ////////////////////////////////////////////////////////////
- int main()
- {
- srand(static_cast<unsigned int>(time(NULL)));
-
- // Define some constants
- const float pi = 3.1415;
- const int gameWidth = 800;
- const int gameHeight = 600;
-
- float ballRadius = 10;
-
- // 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
- Paddle leftPaddle;
-
- // Create the right paddle
- Paddle rightPaddle;
-
- // Create the ball
- Ball ball;
-
- // 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, 150);
- //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;
- 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 + leftPaddle.getSize().x / 2, gameHeight / 2);
- rightPaddle.setPosition(gameWidth - 10 - leftPaddle.getSize().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 = (rand() % 360) * 2 * pi / 360;
- }
- while (abs(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.getY() - leftPaddle.getSize().y / 2 > 5))
- {
- leftPaddle.move(0.f, -paddleSpeed * deltaTime);
- }
- if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down) &&
- (leftPaddle.getY() + leftPaddle.getSize().y / 2 < gameHeight - 5))
- {
- 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.getX(), mappedPos.y);
- }
- // Move the computer's paddle
- if (((rightPaddleSpeed < 0.f) && (rightPaddle.getY() - leftPaddle.getSize().y / 2 > 5.f)) ||
- ((rightPaddleSpeed > 0.f) && (rightPaddle.getY() + leftPaddle.getSize().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.getY() + ballRadius > rightPaddle.getY() + leftPaddle.getSize().y / 2)
- rightPaddleSpeed = paddleSpeed;
- else if (ball.getY() - ballRadius < rightPaddle.getY() - leftPaddle.getSize().y / 2)
- rightPaddleSpeed = -paddleSpeed;
- else
- rightPaddleSpeed = 0.f;
- }
-
- // Move the ball
- float factor = ball.getSpeed() * deltaTime;
- ball.move(cos(ballAngle) * factor, sin(ballAngle) * factor);
-
- #ifdef SFML_SYSTEM_IOS
- const string inputString = "Touch the screen to restart";
- #else
- const string inputString = "Press space to restart or\nescape to exit";
- #endif
-
- // Check collisions between the ball and the screen
- if (ball.getX() - ballRadius < 0.f)
- {
- isPlaying = false;
- pauseMessage.setString("You Lost!\n" + inputString);
- }
- if (ball.getX() + ballRadius > gameWidth)
- {
- isPlaying = false;
- pauseMessage.setString("You Won!\n" + inputString);
- }
- if (ball.getY() - ballRadius < 0.f)
- {
- ballSound.play();
- ballAngle = -ballAngle;
- ball.setPosition(ball.getX(), ballRadius + 0.1f);
- }
- if (ball.getY() + ballRadius > gameHeight)
- {
- ballSound.play();
- ballAngle = -ballAngle;
- ball.setPosition(ball.getX(), gameHeight - ballRadius - 0.1f);
- }
-
- // Check the collisions between the ball and the paddles
- // Left Paddle
- if (ball.getX() - ballRadius < leftPaddle.getX() + leftPaddle.getSize().x / 2 &&
- ball.getX() - ballRadius > leftPaddle.getX() &&
- ball.getY() + ballRadius >= leftPaddle.getY() - leftPaddle.getSize().y / 2 &&
- ball.getY() - ballRadius <= leftPaddle.getY() + leftPaddle.getSize().y / 2)
- {
- if (ball.getY() > leftPaddle.getY())
- ballAngle = pi - ballAngle + (rand() % 20) * pi / 180;
- else
- ballAngle = pi - ballAngle - (rand() % 20) * pi / 180;
-
- ballSound.play();
- ball.setPosition(leftPaddle.getX() + ballRadius + leftPaddle.getSize().x / 2 + 0.1f, ball.getY());
- }
-
- // Right Paddle
- if (ball.getX() + ballRadius > rightPaddle.getX() - leftPaddle.getSize().x / 2 &&
- ball.getX() + ballRadius < rightPaddle.getX() &&
- ball.getY() + ballRadius >= rightPaddle.getY() - leftPaddle.getSize().y / 2 &&
- ball.getY() - ballRadius <= rightPaddle.getY() + leftPaddle.getSize().y / 2)
- {
- if (ball.getY() > rightPaddle.getY())
- ballAngle = pi - ballAngle + (rand() % 20) * pi / 180;
- else
- ballAngle = pi - ballAngle - (rand() % 20) * pi / 180;
-
- ballSound.play();
- ball.setPosition(rightPaddle.getX() - ballRadius - leftPaddle.getSize().x / 2 - 0.1f, ball.getY());
- }
- }
-
- // 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;
- }
|