From 152a12f384e9dfc928d8968a155a4844d58655a6 Mon Sep 17 00:00:00 2001
From: Shivam Gupta <sgupta72@illinois.edu>
Date: Mon, 11 Dec 2017 11:45:41 -0600
Subject: [PATCH] Working

---
 Makefile   |   4 +-
 editor.cpp |  28 ++++++++-----
 enemy.cpp  |   8 ++--
 game.cpp   | 115 ++++++++++++++++++++++++++++++++++++++++++-----------
 game.h     |   3 ++
 main.cpp   |  62 ++++++++++++++++++++++++++++-
 menu.cpp   |  79 ++++++++++++++++++++++++++++++++++++
 menu.h     |  24 +++++++++++
 player.cpp |  13 +++---
 player.h   |   3 +-
 rect.cpp   |  26 +++++++++++-
 rect.h     |  10 +++++
 12 files changed, 324 insertions(+), 51 deletions(-)
 create mode 100644 menu.cpp
 create mode 100644 menu.h

diff --git a/Makefile b/Makefile
index 93addb3..d20e439 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
 all :
-	g++ main.cpp game.cpp window.cpp rect.cpp player.cpp platform.cpp entity.cpp enemy.cpp editor.cpp -lSDL2 -lSDL2_image
+	g++ main.cpp game.cpp window.cpp rect.cpp player.cpp platform.cpp entity.cpp enemy.cpp editor.cpp menu.cpp -lSDL2 -lSDL2_image -lSDL2_ttf -std=c++11
 test :
-	g++ test.cpp game.cpp window.cpp rect.cpp player.cpp platform.cpp entity.cpp enemy.cpp editor.h -lSDL2 -lSDL2_image -o test
+	g++ test.cpp game.cpp window.cpp rect.cpp player.cpp platform.cpp entity.cpp enemy.cpp editor.h -lSDL2 -lSDL2_image -lSDL2_ttf -o test
diff --git a/editor.cpp b/editor.cpp
index 0ace99f..3d3852f 100644
--- a/editor.cpp
+++ b/editor.cpp
@@ -10,16 +10,6 @@ using namespace std;
 
 Editor::Editor()
 {
-    if(SDL_Init(SDL_INIT_VIDEO) < 0)
-    {
-        cout << "Could not initialize SDL: " << SDL_GetError() << endl;
-        return;
-    }
-    cout << IMG_INIT_PNG << endl;
-    if(!IMG_Init(IMG_INIT_PNG))
-    {
-        cout << "Could not initialize SDL_image: " << IMG_GetError() << endl;
-    }
     quit = false;
     GameLoop();
 }
@@ -31,7 +21,7 @@ Editor::~Editor()
 
 void Editor::GameLoop()
 {
-    const int num_types = 2;
+    const int num_types = 4;
     const int TILE_SIZE = 64;
     int width = 800;
     int height = 600;
@@ -163,6 +153,22 @@ void Editor::GameLoop()
                             ((mouse_rect.y + camera.y) / TILE_SIZE) * TILE_SIZE);
                 entities.push_back(make_pair(rect, 1));
             }
+            //end door
+            else if(cur_type == 2)
+            {
+                Rect *rect = new Rect("door.png", window);
+                rect->Move(((mouse_rect.x + camera.x) / TILE_SIZE) * TILE_SIZE,
+                            ((mouse_rect.y + camera.y) / TILE_SIZE) * TILE_SIZE);
+                entities.push_back(make_pair(rect, 2));
+            }
+            //bitcoin
+            else if(cur_type == 3)
+            {
+                Rect *rect = new Rect("bitcoin.png", window);
+                rect->Move(((mouse_rect.x + camera.x) / TILE_SIZE) * TILE_SIZE,
+                            ((mouse_rect.y + camera.y) / TILE_SIZE) * TILE_SIZE);
+                entities.push_back(make_pair(rect, 3));
+            }
         }
         //draw the entities
         for(int i = 0; i < entities.size(); i++)
diff --git a/enemy.cpp b/enemy.cpp
index 7d14ec3..1bbe508 100644
--- a/enemy.cpp
+++ b/enemy.cpp
@@ -20,7 +20,7 @@ Enemy::Enemy(Window &window, int x, int y)
     }
     rect->SetAnimationFrames(enemy_animations);
     //move to initial position
-    rect->Move(400, 300);
+    rect->Move(x, y);
     //do the same with flipped rect
     flipped_rect = new Rect("enemy_flipped.png", window, 1, 11);
     vector<pair<int, int> > flipped_enemy_animations;
@@ -32,7 +32,7 @@ Enemy::Enemy(Window &window, int x, int y)
         }
     }
     flipped_rect->SetAnimationFrames(enemy_animations);
-    flipped_rect->Move(400, 300);
+    flipped_rect->Move(x, y);
     //initially, y velocity is 0
     vy = 0;
     //initially pointing to right
@@ -61,10 +61,10 @@ void Enemy::Update(vector<Entity*> entities)
         flipped_rect->Move(rect->get_x() - 10, rect->get_y() + vy);
     }
     //too far to right
-    if(rect->get_x() >= this->x + 200)
+    if(rect->get_x() >= this->x + 100)
         right = false;
     //too far to left
-    else if(rect->get_x() <= this->x - 200)
+    else if(rect->get_x() <= this->x - 100)
         right = true;
     for(int i = 0; i < entities.size(); i++)
     {
diff --git a/game.cpp b/game.cpp
index 86fba4d..fe5bf82 100644
--- a/game.cpp
+++ b/game.cpp
@@ -13,17 +13,10 @@ using namespace std;
 
 Game::Game(string filename)
 {
-    if(SDL_Init(SDL_INIT_VIDEO) < 0)
-    {
-        cout << "Could not initialize SDL: " << SDL_GetError() << endl;
-        return;
-    }
-    cout << IMG_INIT_PNG << endl;
-    if(!IMG_Init(IMG_INIT_PNG))
-    {
-        cout << "Could not initialize SDL_image: " << IMG_GetError() << endl;
-    }
     quit = false;
+    died = false;
+    won = false;
+    collected = 0;
     GameLoop(filename);
 }
 
@@ -43,6 +36,9 @@ void Game::GameLoop(string filename)
     int entity_x, entity_y, type;
     vector<Enemy *> enemies;
     vector<Entity*> entities;
+    vector<Rect *> bitcoins;
+    Rect *exit = NULL;
+    //load the file
     while(!in.eof())
     {
         in >> entity_x >> entity_y >> type;
@@ -54,10 +50,18 @@ void Game::GameLoop(string filename)
         {
             enemies.push_back(new Enemy(window, entity_x, entity_y));
         }
+        else if(type == 2)
+        {
+            exit = new Rect("door.png", window);
+            exit->Move(entity_x, entity_y);
+        }
+        else if(type == 3)
+        {
+            Rect *bitcoin = new Rect("bitcoin.png", window);
+            bitcoin->Move(entity_x, entity_y);
+            bitcoins.push_back(bitcoin);
+        }
     }
-    //enemies.push_back(new Enemy(window));
-    //for(int i = 0; i < 10; i++)
-    //    entities.push_back(new Platform(window, i * 64, 500));
     //while the quit button hasn't been pressed
     while(!quit)
     {
@@ -68,8 +72,6 @@ void Game::GameLoop(string filename)
                 quit = true;
             player.HandleEvents(e);
         }
-        //clear window
-        window.ClearWindow();
         //update positions of enemies and player
         for(int i = 0; i < enemies.size(); i++)
             enemies[i]->Update(entities);
@@ -77,19 +79,84 @@ void Game::GameLoop(string filename)
         //handle logic
         for(int i = 0; i < enemies.size(); i++)
         {
-            if(player.HandleEnemy(enemies[i]))
+            int enemy_res = player.HandleEnemy(enemies[i]);
+            if(enemy_res == 1)
             {
                 delete enemies[i];
-                enemies.clear();
-                enemies.push_back(new Enemy(window, entity_x, entity_y));
+                enemies.erase(enemies.begin() + i);
+                i--;
+            }
+            else if(enemy_res == 2)
+            {
+                died = true;
             }
         }
-        //draw enemies, players and other entities
-        player.Draw(camera, window);
-        for(int i = 0; i < enemies.size(); i++)
-            enemies[i]->Draw(camera, window);
-        for(int i = 0; i < entities.size(); i++)
-            entities[i]->Draw(camera, window);
+        //check if we have reached the exit
+        SDL_Rect player_rect = player.get_rect()->get_rect();
+        if(player_rect.y > 1000)
+            died = true;
+        SDL_Rect exit_rect = exit->get_rect();
+        if(SDL_HasIntersection(&player_rect, &exit_rect))
+        {
+            won = true;
+        }
+        for(int i = 0; i < bitcoins.size(); i++)
+        {
+            SDL_Rect cur_bitcoin_rect = bitcoins[i]->get_rect();
+            if(SDL_HasIntersection(&player_rect, &cur_bitcoin_rect))
+            {
+                collected = true;
+                bitcoins.erase(bitcoins.begin() + i);
+                i--;
+            }
+        }
+        //clear window
+        window.ClearWindow();
+        if(!died && !won)
+        {
+            //draw enemies, players and other entities
+            player.Draw(camera, window);
+            for(int i = 0; i < enemies.size(); i++)
+                enemies[i]->Draw(camera, window);
+            for(int i = 0; i < entities.size(); i++)
+                entities[i]->Draw(camera, window);
+            exit->Draw(camera, window);
+            for(int i = 0; i < bitcoins.size(); i++)
+                bitcoins[i]->Draw(camera, window);
+            string num_coins = "Bitoins collected: " + to_string(collected);
+            SDL_Color black = {0, 0, 0};
+            Rect *coins = new Rect("times.ttf", num_coins, black);
+            SDL_Rect dummy_camera = {0, 0, 0, 0};
+            coins->Draw(dummy_camera, window, 0, 0);
+        }
+        else if(died)
+        {
+            died = false;
+            SDL_Color black = {0, 0, 0};
+            Rect *you_died = new Rect("times.ttf", "You Died!", black);
+            you_died->Move(400 - you_died->get_w()/2, 300 - you_died->get_h()/2);
+            camera.x = 0;
+            camera.y = 0;
+            you_died->Draw(camera, window, 0, 0);
+            //update the window
+            window.Update();
+            SDL_Delay(1000);
+            return;
+        }
+        else if(won)
+        {
+            won = false;
+            SDL_Color black = {0, 0, 0};
+            Rect *you_died = new Rect("times.ttf", "You Won!", black);
+            you_died->Move(400 - you_died->get_w()/2, 300 - you_died->get_h()/2);
+            camera.x = 0;
+            camera.y = 0;
+            you_died->Draw(camera, window, 0, 0);
+            //update the window
+            window.Update();
+            SDL_Delay(1000);
+            return;
+        }
         //update the window
         window.Update();
         //wait for 100 ms
diff --git a/game.h b/game.h
index a0cd887..dfb73fb 100644
--- a/game.h
+++ b/game.h
@@ -18,6 +18,9 @@ public:
 private:
     //has the user quit?
     bool quit;
+    bool died;
+    bool won;
+    int collected;
     //current event
     SDL_Event e;
     SDL_Rect camera;
diff --git a/main.cpp b/main.cpp
index 8b77db1..c668dc9 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1,11 +1,69 @@
 #include <SDL2/SDL.h>
+#include <SDL2/SDL_image.h>
+#include <SDL2/SDL_ttf.h>
 #include <iostream>
 #include "editor.h"
 #include "game.h"
+#include "menu.h"
 using namespace std;
 
 int main()
 {
-    Editor game;
-    //Game game("level.txt");
+    /*if(SDL_Init(SDL_INIT_VIDEO) < 0)
+    {
+        cout << "Could not initialize SDL: " << SDL_GetError() << endl;
+        return 0;
+    }
+    cout << IMG_INIT_PNG << endl;
+    if(!IMG_Init(IMG_INIT_PNG))
+    {
+        cout << "Could not initialize SDL_image: " << IMG_GetError() << endl;
+        return 0;
+    }
+    if(TTF_Init() == -1)
+    {
+        cout << "Could not initialize SDL_TTF: " << TTF_GetError() << endl;
+        return 0;
+    }
+    Editor game;*/
+    //init level names
+    vector<string> level_names;
+    level_names.push_back("Level 1");
+    level_names.push_back("Level 2");
+    level_names.push_back("Level 3");
+    //init level files
+    vector<string> level_files;
+    level_files.push_back("level1.txt");
+    level_files.push_back("level2.txt");
+    level_files.push_back("level3.txt");
+    int level = 1;
+    while(level != -1)
+    {
+        if(SDL_Init(SDL_INIT_VIDEO) < 0)
+        {
+            cout << "Could not initialize SDL: " << SDL_GetError() << endl;
+            return 0;
+        }
+        cout << IMG_INIT_PNG << endl;
+        if(!IMG_Init(IMG_INIT_PNG))
+        {
+            cout << "Could not initialize SDL_image: " << IMG_GetError() << endl;
+            return 0;
+        }
+        if(TTF_Init() == -1)
+        {
+            cout << "Could not initialize SDL_TTF: " << TTF_GetError() << endl;
+            return 0;
+        }
+        Menu *menu = new Menu(level_names);
+        SDL_Delay(100);
+        level = menu->Loop();
+        delete menu;
+        if(level != -1)
+        {
+            SDL_Delay(100);
+            Game *game = new Game("level.txt");
+            delete game;
+        }
+    }
 }
diff --git a/menu.cpp b/menu.cpp
new file mode 100644
index 0000000..2a83300
--- /dev/null
+++ b/menu.cpp
@@ -0,0 +1,79 @@
+#include "menu.h"
+#include <vector>
+#include <string>
+#include <iostream>
+
+using namespace std;
+
+Menu::Menu(vector<string> level_names)
+{
+    quit = false;
+    this->level_names = level_names;
+    cur_level = 0;
+}
+
+Menu::~Menu()
+{
+}
+
+int Menu::Loop()
+{
+    vector<Rect *> menu_items;
+    Window window(800, 600);
+    SDL_Rect camera = {0, 0, 800, 600};
+    SDL_Color black = {0, 0, 0};
+    //populate menu items
+    for(int i = 0; i < level_names.size(); i++)
+    {
+        menu_items.push_back(new Rect("times.ttf", level_names[i], black));
+        menu_items[i]->Move(400 - menu_items[i]->get_w()/2, i * 30 + 10);
+    }
+    while(!quit)
+    {
+        delete menu_items[cur_level];
+        //color the currently selected item
+        SDL_Color text_color = {238, 130, 238};
+        menu_items[cur_level] = new Rect("times.ttf", level_names[cur_level], text_color);
+        menu_items[cur_level]->Move(400 - menu_items[cur_level]->get_w()/2, cur_level * 30 + 10);
+        //handle input
+        while(SDL_PollEvent(&e) != 0)
+        {
+            if(e.type == SDL_QUIT)
+                quit = true;
+            if(e.type == SDL_KEYDOWN && e.key.repeat == 0)
+            {
+                switch (e.key.keysym.sym)
+                {
+                //move around the menu
+                case SDLK_DOWN:
+                    delete menu_items[cur_level];
+                    menu_items[cur_level] = new Rect("times.ttf", level_names[cur_level], black);
+                    menu_items[cur_level]->Move(400 - menu_items[cur_level]->get_w()/2, cur_level * 30 + 10);
+                    cur_level = (cur_level + 1) % level_names.size();
+                    break;
+                case SDLK_UP:
+                    delete menu_items[cur_level];
+                    menu_items[cur_level] = new Rect("times.ttf", level_names[cur_level], black);
+                    menu_items[cur_level]->Move(400 - menu_items[cur_level]->get_w()/2, cur_level * 30 + 10);
+                    cur_level--;
+                    while(cur_level < 0)
+                        cur_level += level_names.size();
+                    break;
+                //select a menu item
+                case SDLK_RETURN:
+                    return cur_level;
+                    break;
+                }
+            }
+        }
+        window.ClearWindow();
+        //draw the menu items
+        for(int i = 0; i < menu_items.size(); i++)
+        {
+            menu_items[i]->Draw(camera, window, 0, 0);
+        }
+        window.Update();
+        SDL_Delay(100);
+    }
+    return -1;
+}
diff --git a/menu.h b/menu.h
new file mode 100644
index 0000000..3422bce
--- /dev/null
+++ b/menu.h
@@ -0,0 +1,24 @@
+#include <vector>
+#include <string>
+#include "rect.h"
+
+using namespace std;
+
+#ifndef MENU_H
+#define MENU_H
+
+class Menu
+{
+public:
+    Menu(vector<string> level_names);
+    ~Menu();
+    //main loop
+    int Loop();
+private:
+    bool quit;
+    vector<string> level_names;
+    int cur_level;
+    SDL_Event e;
+};
+
+#endif
diff --git a/player.cpp b/player.cpp
index 39864f6..2d6b4b8 100644
--- a/player.cpp
+++ b/player.cpp
@@ -29,6 +29,8 @@ Player::Player(Window &window)
         }
     }
     flipped_rect->SetAnimationFrames(mario_flipped_animations);
+    SDL_Color text_color = { 0, 0, 0 };
+    text = new Rect("times.ttf", "something Yes", text_color);
     //not jumping
     jump = false;
     //facing right
@@ -41,6 +43,7 @@ Player::Player(Window &window)
 Player::~Player()
 {
     delete rect;
+    delete flipped_rect;
 }
 
 void Player::HandleEvents(const SDL_Event &e)
@@ -84,7 +87,7 @@ void Player::HandleEvents(const SDL_Event &e)
 void Player::Update(vector<Entity *> entities)
 {
     //gravity
-    vy += 10;
+    vy += 15;
     //perform jump
     if(jump)
     {
@@ -104,16 +107,16 @@ void Player::Update(vector<Entity *> entities)
     }
 }
 
-bool Player::HandleEnemy(Enemy *enemy)
+int Player::HandleEnemy(Enemy *enemy)
 {
     //killed enemy!
     if(vy > 0 && rect->CheckCollision(*(enemy->get_rect())))
-        return true;
+        return 1;
     //died!
     if(vy <= 0 && rect->CheckCollision(*enemy->get_rect()))
-        cout << "DEAD!!" << endl;
+        return 2;
     //nothing happened
-    return false;
+    return 0;
 }
 void Player::Draw(SDL_Rect &camera, Window &window)
 {
diff --git a/player.h b/player.h
index de8aed7..40ac6ad 100644
--- a/player.h
+++ b/player.h
@@ -16,13 +16,14 @@ public:
     //handle events
     void HandleEvents(const SDL_Event &event);
     void Update(vector<Entity *> entities);
-    bool HandleEnemy(Enemy *enemy);
+    int HandleEnemy(Enemy *enemy);
     void Draw(SDL_Rect &camera, Window &window);
     Rect *get_rect();
 private:
     //rect when facing right, flipped rect when facing left
     Rect *rect;
     Rect *flipped_rect;
+    Rect *text;
     bool flipped;
     //x and y velocity
     int vx, vy;
diff --git a/rect.cpp b/rect.cpp
index a4b9039..41ee272 100644
--- a/rect.cpp
+++ b/rect.cpp
@@ -3,6 +3,7 @@
 #include <string>
 #include <SDL2/SDL.h>
 #include <SDL2/SDL_image.h>
+#include <SDL2/SDL_ttf.h>
 #include <iostream>
 
 using namespace std;
@@ -49,6 +50,28 @@ Rect::Rect(string filename, Window &window, int rows, int columns)
     this->columns = columns;
 }
 
+Rect::Rect(string font_filename, string text, SDL_Color text_color)
+{
+    TTF_Font *font = TTF_OpenFont(font_filename.c_str(), 28);
+    if(font == NULL)
+    {
+        cout << "Failed to load font! " << TTF_GetError() << endl;
+        return;
+    }
+    image = TTF_RenderText_Solid(font, text.c_str(), text_color);
+    if(image == NULL)
+    {
+        cout << "Failed to create surface! " << SDL_GetError() << endl;
+        return;
+    }
+    sdl_rect.x = 0;
+    sdl_rect.y = 0;
+    sdl_rect.w = image->w;
+    sdl_rect.h = image->h;
+    rows = 1;
+    columns = 1;
+}
+
 Rect::~Rect()
 {
     SDL_FreeSurface(image);
@@ -77,8 +100,7 @@ void Rect::Draw(const SDL_Rect &camera, Window &window, int row, int column)
     srcrect.w = image->w/columns;
     srcrect.h = image->h/rows;
     //set up dstrect to draw on
-    SDL_Rect dstrect = sdl_rect;
-    dstrect.x = sdl_rect.x - camera.x;
+    SDL_Rect dstrect = sdl_rect; dstrect.x = sdl_rect.x - camera.x;
     dstrect.y = sdl_rect.y - camera.y;
     //draw
     SDL_BlitSurface(image, &srcrect, window.get_screen_surface(), &dstrect);
diff --git a/rect.h b/rect.h
index ba9b35b..fdc0ec3 100644
--- a/rect.h
+++ b/rect.h
@@ -5,6 +5,8 @@
 #include <SDL2/SDL.h>
 #include <vector>
 #include "window.h"
+#include <SDL2/SDL_ttf.h>
+
 using namespace std;
 
 /**
@@ -28,6 +30,14 @@ public:
      * column: columns in spritesheet
      */
     Rect(string filename, Window &window, int rows, int columns);
+
+    /**
+     * load text
+     * font_filename: filaname of font file
+     * text: string to render
+     * text_color: color to render in
+     */
+    Rect(string font_filename, string text, SDL_Color text_color);
     ~Rect();
     /**
      * move rect to x, y coordinate
-- 
GitLab