Advertisement
Guest User

Flappy Bird

a guest
Mar 16th, 2017
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.01 KB | None | 0 0
  1. #include <SFML/Graphics.hpp>
  2.  
  3. #include <vector>
  4. #include <string>
  5. #include <random>
  6. #include <fstream>
  7. #include <algorithm>
  8.  
  9. #include <cstdlib>
  10. #include <ctime>
  11. #include <cstring>
  12.  
  13. class Bird{
  14.     public:
  15.         Bird(){
  16.             bird_x = 100;
  17.             bird_y = 0;
  18.  
  19.             bird.push_back(sf::CircleShape(30.f));
  20.             bird[0].setFillColor(sf::Color::Red);
  21.             bird[0].setPosition(bird_x, bird_y);
  22.  
  23.             bird.push_back(sf::CircleShape(10, 3));
  24.             bird[1].setFillColor(sf::Color::Yellow);
  25.             bird[1].setRotation(90);
  26.             bird[1].setPosition(bird_x + 71, bird_y + 20);
  27.  
  28.             bird.push_back(sf::CircleShape(3.f));
  29.             bird[2].setFillColor(sf::Color::Blue);
  30.             bird[2].setPosition(bird_x + 20, bird_y + 10);
  31.         }
  32.         void getPosition(float *x, float *y){
  33.             *x = bird_x + 15;
  34.             *y = bird_y + 15;
  35.         }
  36.         void moveVertically(float mov){
  37.             bird_y += mov;
  38.             for(unsigned int i = 0; i < bird.size(); i++){
  39.                 bird[i].move(0, mov);
  40.             }
  41.         }
  42.         std::vector<sf::CircleShape> getBirdVector(){
  43.             return bird;
  44.         }
  45.     private:
  46.         std::vector<sf::CircleShape> bird;
  47.         float bird_x;
  48.         float bird_y;
  49. };
  50.  
  51. class Pipe{
  52.     public:
  53.         Pipe(unsigned int space, unsigned int window_width, unsigned int window_height){
  54.             printf("Spawning new pipe with gap from %u to %u\n", space - 100, space + 100);
  55.             upper_pipe = new sf::RectangleShape(sf::Vector2f(100, space - 100));
  56.             lower_pipe = new sf::RectangleShape(sf::Vector2f(100, window_height - space - 100));
  57.            
  58.             upper_pipe->setFillColor(sf::Color::Green);
  59.             lower_pipe->setFillColor(sf::Color::Green);
  60.  
  61.             current_x = window_width + 100;
  62.            controlled_space = space;
  63.  
  64.             upper_pipe->setPosition(current_x, 0);
  65.             lower_pipe->setPosition(current_x, space + 100);
  66.         }
  67.         bool checkIfCollision(float colliding_x, float colliding_y){
  68.             if(colliding_x > current_x + 50 || colliding_x < current_x - 50) return false;
  69.             if(colliding_y < controlled_space + 100 && colliding_y > controlled_space - 100) return false;
  70.             return true;
  71.         }
  72.         bool update(){
  73.             if(current_x < -100) return true;
  74.             current_x -= 1;
  75.             upper_pipe->move(-1, 0);
  76.             lower_pipe->move(-1, 0);
  77.             return false;
  78.         }
  79.         void drawSelf(sf::RenderWindow *to_draw_to){
  80.             to_draw_to->draw(*upper_pipe);
  81.             to_draw_to->draw(*lower_pipe);
  82.             return;
  83.         }
  84.         void properDestruct(){
  85.             delete upper_pipe;
  86.             delete lower_pipe;
  87.         }
  88.         ~Pipe(){}
  89.     private:
  90.         sf::RectangleShape *upper_pipe;
  91.         sf::RectangleShape *lower_pipe;
  92.         signed int current_x;
  93.         unsigned int  controlled_space;
  94. };
  95.  
  96. void save(unsigned int score){
  97.     char *name = (char *)calloc(1, 1);
  98.     char buf = 0;
  99.     printf("Enter your name: ");
  100.     while(1){
  101.         scanf("%c", &buf);
  102.         if(buf == '\n')break;
  103.         name = (char *)realloc(name, strlen(name) + 2);
  104.         name[strlen(name)] = buf;
  105.     }
  106.     std::ofstream savefile;
  107.     savefile.open(".flappy_bird_save", std::ios::out | std::ios::app);
  108.     savefile << name;
  109.     savefile << ':';
  110.     savefile.write((char *)(void *)(&score), sizeof(unsigned int));
  111.     savefile << '\n';
  112.     savefile.close();
  113. }
  114.  
  115. void get_hs(){
  116.     printf("====LEADERBOARD====\n");
  117.     struct player{
  118.         unsigned int score;
  119.         char *name;
  120.     };
  121.     std::vector<player> players;
  122.  
  123.     std::ifstream savefile;
  124.     char buf = 0;
  125.     savefile.open(".flappy_bird_save");
  126.     while(savefile.good()){
  127.         buf = 0;
  128.         players.resize(players.size() + 1);
  129.         players[players.size() - 1].name = (char *)calloc(1, 1);
  130.         while(1){
  131.             buf = savefile.get();
  132.             if(buf == ':' || !savefile.good()) break;
  133.             players[players.size() - 1].name = (char *)realloc(players[players.size() - 1].name, strlen(players[players.size() - 1].name) + 2);
  134.             players[players.size() - 1].name[strlen(players[players.size() - 1].name)] = buf;
  135.         }
  136.         savefile.read((char *)(void *)&(players[players.size() - 1].score), sizeof(unsigned int));
  137.         savefile.get(); //drop the newline
  138.     }
  139.     bool is_sorted = false;
  140.     if(players.size() < 3) return; //don't bother
  141.     while(1){
  142.         for(unsigned int i = 0; i < players.size(); i++){
  143.             unsigned int pivot_pos = players.size() / 2;
  144.             if(players[pivot_pos].score == 0) pivot_pos -= 1;
  145.             if(i == pivot_pos) pivot_pos -= 1;
  146.             if(players[i].score < players[pivot_pos].score){
  147.                 players.push_back(players[i]);
  148.                 players.erase(players.begin() + i);
  149.             }
  150.         }
  151.         is_sorted = true;
  152.         for(unsigned int i = 0; i < players.size() - 2; i++){
  153.             if(players[i].score < players[i + 1].score){
  154.                 is_sorted = false;
  155.                 break;
  156.             }
  157.         }
  158.         if(is_sorted) break;
  159.     }
  160.  
  161.     for(unsigned int i = 0; i < players.size(); i++){
  162.         if(players[i].score == 0) break;
  163.         printf("%s:\t%8u\n", players[i].name, players[i].score);
  164.     }
  165. }
  166.  
  167.  
  168. int main(int argc, char *argv[]){
  169.     if(argc < 2) return 1;
  170.  
  171.     std::default_random_engine rand_generator;
  172.     rand_generator.seed(time(0));
  173.  
  174.     get_hs();
  175.     printf("Insert quarter to play\n");
  176.     getchar();
  177.  
  178.     unsigned int window_width = (argc < 3) ? 1000 : atoi(argv[2]); //we have to do it this way because SFML team is too lazy to let you
  179.     unsigned int window_height = (argc < 4) ? 800 : atoi(argv[3]); //actually get the size of the window.
  180.  
  181.     sf::RenderWindow window(sf::VideoMode(window_width, window_height), argv[1]); //damn kids...
  182.     printf("Created the window\n");
  183.  
  184.     std::uniform_int_distribution<int> pipe_pos_spawn(100, window_height - 100);
  185.  
  186.     Bird protagonist;
  187.     std::vector<sf::CircleShape> protagonist_parts;
  188.     std::vector<Pipe> pipes;
  189.  
  190.     float protagonist_x;
  191.     float protagonist_y;
  192.  
  193.     unsigned int score = 0;
  194.     char *score_text = (char *)calloc(1, 11);
  195.     sprintf(score_text, "%u", score);
  196.  
  197.     float current_gravity_pull = 0.5;
  198.    
  199.     sf::Clock time_tracker;
  200.     sf::Time check_time;
  201.  
  202.     sf::RectangleShape *current_upper_pipe;
  203.     sf::RectangleShape *current_lower_pipe;
  204.  
  205.     sf::Font font;
  206.     if(!font.loadFromFile("Hack-Regular.ttf")) return 1;
  207.     sf::Text score_view;
  208.     score_view.setCharacterSize(32);
  209.     score_view.setFont(font);
  210.     score_view.setFillColor(sf::Color::White);
  211.     score_view.setStyle(1);
  212.     score_view.setString("Score: " + std::string(score_text));
  213.     printf("Scoreview is currently %s\n", score_view.getString().toAnsiString().c_str());
  214.  
  215.     pipe_pos_spawn(rand_generator); //throwaway first value
  216.  
  217.     protagonist.moveVertically(window_height / 2);
  218.  
  219.     while(window.isOpen()){
  220.         sf::Event event;
  221.         while(window.pollEvent(event)){
  222.             if(event.type == sf::Event::Closed) window.close();
  223.         }
  224.  
  225.         protagonist.getPosition(&protagonist_x, &protagonist_y);
  226.  
  227.         current_gravity_pull = (current_gravity_pull * 2 < 16) ? current_gravity_pull : 16;
  228.  
  229.         if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && protagonist_y > 0){
  230.             current_gravity_pull = 0.5;
  231.             protagonist.moveVertically(-2);
  232.         }else{
  233.             protagonist.moveVertically(current_gravity_pull);
  234.         }
  235.        
  236.         protagonist_parts = protagonist.getBirdVector();
  237.  
  238.         check_time = time_tracker.getElapsedTime();
  239.         if(check_time.asMilliseconds() % 1000 == 0){
  240.             pipes.push_back(Pipe(pipe_pos_spawn(rand_generator), window_width, window_height));
  241.         }
  242.  
  243.         window.clear();
  244.         for(unsigned int i = 0; i < protagonist_parts.size(); i++){ //draw the bird
  245.            window.draw(protagonist_parts[i]);
  246.         }
  247.         for(unsigned int i = 0; i < pipes.size(); i++){
  248.             pipes[i].drawSelf(&window);
  249.             if(pipes[i].update()){
  250.                 printf("Update returned true\n");
  251.                 pipes[i].properDestruct();
  252.                 pipes[i].~Pipe();
  253.                 pipes.erase(pipes.begin() + i);
  254.                 score += 1;
  255.                 sprintf(score_text, "Score: %u", score);
  256.                 score_view.setString(std::string(score_text));
  257.                 printf("Scoreview is currently %s\n", score_view.getString().toAnsiString().c_str());
  258.                 continue;
  259.             }else if(pipes[i].checkIfCollision(protagonist_x, protagonist_y) || protagonist_y >= window_height){
  260.                 printf("You died\nScore: %u\n", score);
  261.                 window.close();
  262.                 save(score);
  263.                 return 0;
  264.             }
  265.         }
  266.         window.draw(score_view);
  267.         window.display();
  268.     }
  269.     return 0;
  270. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement