==============================================.HPP FILE=========================================================== #pragma once //C++ Headers #include #include #include #include #include #include #include #include //Library Headers #include #include #include #include #include const int Width = 800; const int Height = 600; using namespace std; ============================================.CPP FILE============================================================= //Class Headers #include "Globals.hpp" bool Collided(const sf::Shape & s1, const sf::Shape & s2); void ResetBall(sf::CircleShape & s1, float & a, float & b, sf::Vector2f & Pos); void ChangeBallDir(sf::CircleShape & s1, const float & speed, float& dirX, float & dirY); void EnemyAi(sf::RectangleShape & r1, sf::CircleShape c1, float & a, const float & speed, int & difficulty); void PlayerMovement(sf::Shape &PlayerShape); void StringChange(sf::Text & t1, int & a); void StringChangeDif(sf::Text & t1, int & a); void DrawText(sf::Font &Font, sf::Text &text, int &Size, sf::Vector2f &Pos, const sf::Color &Color, sf::String &str, sf::RenderWindow &rw); void Reset(sf::Shape & s1, sf::Shape & s2, sf::Shape & s3, sf::Vector2f & v1, sf::Vector2f & v2, sf::Vector2f & v3, int & x, int & y); void Save(); //Start of main int main() { //Window Objects sf::RenderWindow Window(sf::VideoMode(Width, Height), "SFML Window"); Window.setKeyRepeatEnabled(false); Window.setFramerateLimit(60); //Init //Misc things enum State{MainMenu, Options, Playing, Paused, EndScreen, Quit}; sf::Font Font; if(!Font.loadFromFile("arial.ttf")) cout << "Could not load font from file!\n"; int f = 32; int MaxScore = 10; sf::Text ModifiableText; //Game "Board" Init sf::RectangleShape BoardMid; BoardMid.setSize(sf::Vector2f(20, 600)); BoardMid.setFillColor(sf::Color(220,220,220,255)); BoardMid.setPosition(Width/2, 0); sf::CircleShape BoardCircle; BoardCircle.setRadius(180); BoardCircle.setFillColor(sf::Color::Transparent); BoardCircle.setOutlineColor(sf::Color(220,220,220,255)); BoardCircle.setOutlineThickness(12); BoardCircle.setPosition(225, 130); //Rand srand(time(NULL)); //Player Init sf::Text pText; pText.setFont(Font); pText.setCharacterSize(32); pText.setColor(sf::Color::Blue); pText.setPosition(Width/2 - 20, 20); sf::RectangleShape PlayerShape; sf::Vector2f Pos; PlayerShape.setFillColor(sf::Color::Blue); PlayerShape.setPosition(Pos.x = 10, Pos.y = Height/2 - 64); PlayerShape.setSize(sf::Vector2f(32, 128)); int PlayerScore = 0; //Enemy Init sf::Text eText; eText.setFont(Font); eText.setCharacterSize(32); eText.setColor(sf::Color::Red); eText.setPosition(Width/2 + 20, 20); sf::RectangleShape EnemyShape; sf::Vector2f ePos; EnemyShape.setFillColor(sf::Color::Red); EnemyShape.setPosition(ePos.x = Width - 42, ePos.y = Height/2 - 64); EnemyShape.setSize(sf::Vector2f(32, 128)); float eDirX = 0, eDirY = 1; int EnemyScore = 0; //Ball Init sf::CircleShape Ball; sf::Vector2f bPos; Ball.setFillColor(sf::Color::Green); Ball.setPosition(bPos.x = Width/2, bPos.y = Height/2); Ball.setRadius(16); float dirX = -1, dirY = 0; const float speed = 5; float k = 0.5f; //End of Init enum Difficulty {Cake, Easy, Medium, Hard, Impossible}; State state = MainMenu; int difficulty = Easy; int MaxScoreChange = 1; while (Window.isOpen()) { while(state == MainMenu) { sf::Vector2i MousePosition = sf::Mouse::getPosition(Window); sf::Text Text; sf::Text Text2; DrawText(Font, Text, f, sf::Vector2f(Width/2 - Text.getCharacterSize() * Text.getScale().x, Height/2 - Text.getCharacterSize() * Text.getScale().y), sf::Color::White, sf::String("Play!"), Window); DrawText(Font, Text2, f, sf::Vector2f(Width/2 - Text2.getCharacterSize() * Text2.getScale().x, Height/2 - Text2.getCharacterSize() * Text2.getScale().y + Text.getGlobalBounds().height + 20), sf::Color::White, sf::String("Options!"), Window); //cout << Text.getPosition().x << " " << Text.getPosition().y << endl; sf::Event Event; while(Window.pollEvent(Event)) { switch(Event.type) { case sf::Event::Closed: Window.close(); break; case sf::Event::KeyPressed: if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) state = Quit; break; }//end of switch Event.type }//end of window.pollEvent //start of mouse bounds checking if(MousePosition.x >= Text.getPosition().x - 10 && MousePosition.x <= Text.getPosition().x + Text.getGlobalBounds().width + 10 && //x MousePosition.y >= Text.getPosition().y - 10 && MousePosition.y <= Text.getPosition().y + Text.getGlobalBounds().height + 5) //y { Text.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { state = Playing; }//end of if mouse button is pressed }//end of mouse bounds checking //start of mouse bounds checking if(MousePosition.x >= Text2.getPosition().x - 10 && MousePosition.x <= Text2.getPosition().x + Text2.getGlobalBounds().width + 10 && //x MousePosition.y >= Text2.getPosition().y - 10 && MousePosition.y <= Text2.getPosition().y + Text2.getGlobalBounds().height + 10) //y { Text2.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { state = Options; }//end of if mouse button is pressed }//end of mouse bounds checking Window.clear(); Window.draw(Text); Window.draw(Text2); Window.display(); } //end of While state == MainMenu while(state == Options) { sf::Vector2i MousePosition = sf::Mouse::getPosition(Window); sf::Text OT1; sf::Text t1, t2, t3, t4; t2.setFont(Font); t2.setCharacterSize(32); t2.setPosition(sf::Vector2f(Width/2 + 160, Height - 100)); t2.setColor(sf::Color::White); t4.setFont(Font); t4.setCharacterSize(32); t4.setPosition(sf::Vector2f(Width/2 + 140, Height - 150)); t4.setColor(sf::Color::White); DrawText(Font, OT1, f, sf::Vector2f(Width/2, Height - 50), sf::Color::White, sf::String("Back"), Window); DrawText(Font, t1, f, sf::Vector2f(Width/2, Height - 100), sf::Color::White, sf::String("Max Score: "), Window); DrawText(Font, t3, f, sf::Vector2f(Width/2, Height - 150), sf::Color::White, sf::String("Difficulty: "), Window); sf::Event Event; while(Window.pollEvent(Event)) { switch(Event.type) { case sf::Event::Closed: Window.close(); break; case sf::Event::KeyPressed: if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) state = Paused; break; }//end of switch Event.type }//end of window.pollEvent //start of mouse bounds checking if(MousePosition.x >= OT1.getPosition().x - 10 && MousePosition.x <= OT1.getPosition().x + OT1.getGlobalBounds().width + 10 && //x MousePosition.y >= OT1.getPosition().y - 10 && MousePosition.y <= OT1.getPosition().y + OT1.getGlobalBounds().height + 10) //y { OT1.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { state = MainMenu; }//end of if mouse button is pressed } if(MousePosition.x >= t1.getPosition().x - 10 && MousePosition.x <= t1.getPosition().x + t1.getGlobalBounds().width + 10 && //x MousePosition.y >= t1.getPosition().y - 10 && MousePosition.y <= t1.getPosition().y + t1.getGlobalBounds().height + 20) //y { t1.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { if(MaxScoreChange != 20) MaxScoreChange++; StringChange(t2, MaxScoreChange); MaxScore = MaxScoreChange; }//end of if mouse button is pressed if(sf::Mouse::isButtonPressed(sf::Mouse::Right)) { if(MaxScoreChange != 1) MaxScoreChange--; StringChange(t2, MaxScoreChange); MaxScore = MaxScoreChange; }//end of if mouse button is pressed } if(MousePosition.x >= t3.getPosition().x - 10 && MousePosition.x <= t3.getPosition().x + t3.getGlobalBounds().width + 10 && //x MousePosition.y >= t3.getPosition().y - 10 && MousePosition.y <= t3.getPosition().y + t3.getGlobalBounds().height + 10) //y { t3.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { if(difficulty != 4) ++difficulty; }//end of if mouse button is pressed if(sf::Mouse::isButtonPressed(sf::Mouse::Right)) { if(difficulty != 0) --difficulty; }//end of if mouse button is pressed }//end of mouse bounds checking StringChange(t2, MaxScoreChange); StringChangeDif(t4, difficulty); Window.clear(); Window.draw(OT1); Window.draw(t1); Window.draw(t2); Window.draw(t3); Window.draw(t4); Window.display(); } //End of while state == Options while(state == Playing) { sf::Event Event; while(Window.pollEvent(Event)) { switch(Event.type) { case sf::Event::Closed: Window.close(); break; case sf::Event::KeyPressed: if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) state = Paused; else if(sf::Keyboard::isKeyPressed(sf::Keyboard::K)) ResetBall(Ball, dirX, dirY, bPos); break; }//end of switch Event.type }//end of window.pollEvent //Update PlayerMovement(PlayerShape); EnemyAi(EnemyShape, Ball, eDirY, speed, difficulty); Ball.move(dirX, dirY); //Keeping Images in bounds if(PlayerShape.getPosition().y <= 0) PlayerShape.setPosition(10, 0); if(PlayerShape.getPosition().y >= Height - PlayerShape.getSize().y) PlayerShape.setPosition(10, Height - PlayerShape.getSize().y); if(EnemyShape.getPosition().y <= 0) EnemyShape.setPosition(Width - 42, 0); if(EnemyShape.getPosition().y >= Height - EnemyShape.getSize().y) EnemyShape.setPosition(Width - 42, Height - EnemyShape.getSize().y); if(Ball.getPosition().y <= 0) dirY = -dirY; if(Ball.getPosition().y >= Height - 32) dirY = -dirY; //Collision Detection if(Collided(PlayerShape, Ball)) { dirX = -dirX; //dirY = -dirY - (float)rand()/(float)RAND_MAX; //dirX = cos(PlayerShape.getPosition().x) * speed + k * PlayerShape.getPosition().x; //dirX = sin(PlayerShape.getPosition().x) * 2; //dirX = atan2(PlayerShape.getPosition().y, PlayerShape.getPosition().x) * 3; dirY = cos(PlayerShape.getPosition().y); //dirY = sin(PlayerShape.getPosition().y); //dirY = atan2(PlayerShape.getPosition().x, PlayerShape.getPosition().y); } else if(Collided(EnemyShape, Ball)) { dirX = -dirX; //dirY = -dirY - (float)rand()/(float)RAND_MAX; //dirX = cos(-EnemyShape.getPosition().x); //dirX = -cos(EnemyShape.getPosition().x) * 10; //dirX = -sin(EnemyShape.getPosition().x) * 10; //dirX = -atan2(EnemyShape.getPosition().y, EnemyShape.getPosition().x) * 10; dirY = -cos(-EnemyShape.getPosition().y); //dirY = -sin(EnemyShape.getPosition().y); //dirY = -atan2(EnemyShape.getPosition().y, EnemyShape.getPosition().x); // doesnt work well } //Update StringChange(pText, PlayerScore); StringChange(eText, EnemyScore); EnemyAi(EnemyShape, Ball, eDirY, speed, difficulty); //Points if(Ball.getPosition().x < 0 - 32) { EnemyScore++; ResetBall(Ball, dirX, dirY, bPos); ChangeBallDir(Ball, speed, dirX, dirY); dirX = -dirX + 0.2f; dirY = -dirY + 0.2f; } else if(Ball.getPosition().x > Width) { PlayerScore++; ResetBall(Ball, dirX, dirY, bPos); ChangeBallDir(Ball, speed, dirX, dirY); dirX = -dirX + 0.2f; dirY = -dirY + 0.2f; } Ball.move(dirX * speed, dirY * speed); if(PlayerScore >= MaxScore) state = EndScreen; if(EnemyScore >= MaxScore) state = EndScreen; Window.clear(); Window.draw(pText); Window.draw(eText); Window.draw(BoardCircle); Window.draw(BoardMid); Window.draw(PlayerShape); Window.draw(EnemyShape); Window.draw(Ball); Window.display(); } //end of while state == Playing while(state == Paused) { sf::Text ModifiableText; sf::Text ModifiableText2; sf::Text ModifiableText3; DrawText(Font, ModifiableText, f, sf::Vector2f(Width/2, Height/2 - 100), sf::Color::White, sf::String("Resume"), Window); DrawText(Font, ModifiableText2, f, sf::Vector2f(Width/2, Height/2 - 50), sf::Color::White, sf::String("Options"), Window); DrawText(Font, ModifiableText3, f, sf::Vector2f(Width/2, Height/2), sf::Color::White, sf::String("Quit"), Window); sf::Event Event; while(Window.pollEvent(Event)) { switch(Event.type) { case sf::Event::Closed: Window.close(); break; case sf::Event::KeyPressed: if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) state = Playing; }//end of switch Event.type }//end of window.pollEvent sf::Vector2i MousePosition = sf::Mouse::getPosition(Window); //start of mouse bounds checking if(MousePosition.x >= ModifiableText.getPosition().x - 10 && MousePosition.x <= ModifiableText.getPosition().x + ModifiableText.getGlobalBounds().width + 10 && //x MousePosition.y >= ModifiableText.getPosition().y - 10 && MousePosition.y <= ModifiableText.getPosition().y + ModifiableText.getGlobalBounds().height + 10) //y { ModifiableText.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { state = Playing; }//end of if mouse button is pressed }//end of mouse bounds checking //start of mouse bounds checking if(MousePosition.x >= ModifiableText2.getPosition().x - 10 && MousePosition.x <= ModifiableText2.getPosition().x + ModifiableText2.getGlobalBounds().width + 10 && //x MousePosition.y >= ModifiableText2.getPosition().y - 10 && MousePosition.y <= ModifiableText2.getPosition().y + ModifiableText2.getGlobalBounds().height + 10) //y { ModifiableText2.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { state = Options; }//end of if mouse button is pressed }//end of mouse bounds checking if(MousePosition.x >= ModifiableText3.getPosition().x - 10 && MousePosition.x <= ModifiableText3.getPosition().x + ModifiableText3.getGlobalBounds().width + 10 && //x MousePosition.y >= ModifiableText3.getPosition().y - 10 && MousePosition.y <= ModifiableText3.getPosition().y + ModifiableText3.getGlobalBounds().height + 10) //y { ModifiableText3.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { state = Quit; }//end of if mouse button is pressed }//end of mouse bounds checking Window.clear(); Window.draw(ModifiableText); Window.draw(ModifiableText2); Window.draw(ModifiableText3); Window.display(); } //end of while state == Paused while (state == EndScreen) { sf::Vector2i MousePosition = sf::Mouse::getPosition(Window); sf::Text t1, t2, Restart, Exit; if(PlayerScore >= MaxScore) DrawText(Font, t1, f, sf::Vector2f(100, Height/2), sf::Color::Green, sf::String("PLAYER WINS!"), Window); if(EnemyScore >= MaxScore) DrawText(Font, t2, f, sf::Vector2f(100, Height/2), sf::Color::Red, sf::String("ENEMY WINS!"), Window); DrawText(Font, Restart, f, sf::Vector2f(50, Height-100), sf::Color::White, sf::String("Play Again?"), Window); DrawText(Font, Exit, f, sf::Vector2f(700, Height-100), sf::Color::White, sf::String("Quit!"), Window); //start of mouse bounds checking if(MousePosition.x >= Restart.getPosition().x - 10 && MousePosition.x <= Restart.getPosition().x + Restart.getGlobalBounds().width + 10 && //x MousePosition.y >= Restart.getPosition().y - 10 && MousePosition.y <= Restart.getPosition().y + Restart.getGlobalBounds().height + 20) //y { Restart.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { Reset(PlayerShape, EnemyShape, Ball, Pos, ePos, bPos, PlayerScore, EnemyScore); state = MainMenu; }//end of if mouse button is pressed }//end of mouse bounds checking if(MousePosition.x >= Exit.getPosition().x - 10 && MousePosition.x <= Exit.getPosition().x + Exit.getGlobalBounds().width + 10 && //x MousePosition.y >= Exit.getPosition().y - 10 && MousePosition.y <= Exit.getPosition().y + Exit.getGlobalBounds().height + 20) //y { Exit.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { state = Quit; }//end of if mouse button is pressed }//end of mouse bounds checking Window.clear(); Window.draw(t1); Window.draw(t2); Window.draw(Restart); Window.draw(Exit); Window.display(); } //end of while state == EndScreen while (state == Quit) { sf::Text EndText; sf::Text Yes; sf::Text No; DrawText(Font, EndText, f, sf::Vector2f(Width/2 - 100, Height/2 - 50), sf::Color::White, sf::String("Are you sure you want to quit?!"), Window); DrawText(Font, Yes, f, sf::Vector2f(Width/2 - 100, Height/2), sf::Color::White, sf::String("Yes"), Window); DrawText(Font, No, f, sf::Vector2f(Width/2, Height/2), sf::Color::White, sf::String("No"), Window); sf::Event Event; while(Window.pollEvent(Event)) { switch(Event.type) { case sf::Event::Closed: Window.close(); break; case sf::Event::KeyPressed: if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) Window.close(); break; }//end of switch Event.type }//end of window.pollEvent //Update sf::Vector2i MousePosition = sf::Mouse::getPosition(Window); //Start of mouse bounds checking if(MousePosition.x >= Yes.getPosition().x - 10 && MousePosition.x <= Yes.getPosition().x + Yes.getGlobalBounds().width + 10 && //x MousePosition.y >= Yes.getPosition().y - 10 && MousePosition.y <= Yes.getPosition().y + Yes.getGlobalBounds().height + 20) //y { Yes.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { Window.close(); }//end of if mouse button is pressed } if(MousePosition.x >= No.getPosition().x - 10 && MousePosition.x <= No.getPosition().x + No.getGlobalBounds().width + 10 && //x MousePosition.y >= No.getPosition().y - 10 && MousePosition.y <= No.getPosition().y + No.getGlobalBounds().height + 20) //y { No.setColor(sf::Color::Red); if(sf::Mouse::isButtonPressed(sf::Mouse::Left)) { state = Paused; }//end of if mouse button is pressed }//end of mouse bounds checking Window.clear(); Window.draw(EndText); Window.draw(Yes); Window.draw(No); Window.display(); } //end of state == Quit }//end of while Window.isOpen() return 0; }//End of main //Methods/Functions void PlayerMovement(sf::Shape &PlayerShape) { if(sf::Keyboard::isKeyPressed(sf::Keyboard::W) || sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) { PlayerShape.move(0, -5); } else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S) || sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) { PlayerShape.move(0, 5); } } bool Collided(const sf::Shape & s1, const sf::Shape & s2) { sf::FloatRect r1 = s1.getGlobalBounds(); sf::FloatRect r2 = s2.getGlobalBounds(); return r1.intersects(r2); } void ResetBall(sf::CircleShape & s1, float & a, float & b, sf::Vector2f & Pos) { s1.setPosition(Pos); a = 1, b = 1; } void ChangeBallDir(sf::CircleShape & s1, const float & speed, float & dirX, float & dirY) { dirX = -dirX; dirY = -dirY; //s1.move(dirX * speed, dirY * speed); } void StringChange(sf::Text & t1, int & a) { switch(a) { case 0: t1.setString("0"); break; case 1: t1.setString("1"); break; case 2: t1.setString("2"); break; case 3: t1.setString("3"); break; case 4: t1.setString("4"); break; case 5: t1.setString("5"); break; case 6: t1.setString("6"); break; case 7: t1.setString("7"); break; case 8: t1.setString("8"); break; case 9: t1.setString("9"); break; case 10: t1.setString("10"); break; case 11: t1.setString("11"); break; case 12: t1.setString("12"); break; case 13: t1.setString("13"); break; case 14: t1.setString("14"); break; case 15: t1.setString("15"); break; case 16: t1.setString("16"); break; case 17: t1.setString("17"); break; case 18: t1.setString("18"); break; case 19: t1.setString("19"); break; case 20: t1.setString("20"); break; }//end of switch }//end of void SwitchString void StringChangeDif(sf::Text & t1, int & a) { switch(a) { case 0: t1.setString("Cake"); break; case 1: t1.setString("Easy"); break; case 2: t1.setString("Medium"); break; case 3: t1.setString("Hard"); break; case 4: t1.setString("Impossible"); break; } } void EnemyAi(sf::RectangleShape & r1, sf::CircleShape c1, float & a, const float & speed, int & difficulty) { if(difficulty == 0) { a = 0.2f; } else if(difficulty == 1) { a = 0.4f; } else if(difficulty == 2) { a = 0.5f; } else if(difficulty == 3) { a = 0.6f; } else if(difficulty == 3) { a = 1.0f; } if(c1.getPosition().y < r1.getPosition().y) { r1.move(0, -a * speed); } else if(c1.getPosition().y > r1.getPosition().y) { r1.move(0, a * speed); } //so if the ball goes lower than the enemy can the enemy wont be all buggy and weird about moving in and out of the bounds its allowed else if(c1.getPosition().y > Height - 96) { r1.move(0,-1); } } void DrawText(sf::Font &Font, sf::Text &text, int &Size, sf::Vector2f &Pos, const sf::Color &Color, sf::String &str, sf::RenderWindow &rw) { text.setFont(Font); text.setCharacterSize(Size); text.setPosition(Pos.x, Pos.y); text.setColor(Color); text.setString(str); rw.draw(text); } void Reset(sf::Shape & s1, sf::Shape & s2, sf::Shape & s3, sf::Vector2f & v1, sf::Vector2f & v2, sf::Vector2f & v3, int & x, int & y) { s1.setPosition(v1); s2.setPosition(v2); s3.setPosition(v3); x = 0; y = 0; } void Save() { }