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