diff --git a/Assignment3Project/Assignment3Project/bullet.cpp b/Assignment3Project/Assignment3Project/bullet.cpp index e38d885..05cc535 100644 --- a/Assignment3Project/Assignment3Project/bullet.cpp +++ b/Assignment3Project/Assignment3Project/bullet.cpp @@ -21,6 +21,11 @@ Bullet::Bullet(Behavior _behavior) { void Bullet::reset_pos(float x, float y) { x_pos = x; y_pos = y; + + hitbox.x = x_pos; + hitbox.y = y_pos; + hitbox.width = width; + hitbox.height = height; } void Bullet::draw() { diff --git a/Assignment3Project/Assignment3Project/bullet.h b/Assignment3Project/Assignment3Project/bullet.h index 3ecfdd0..48c0d3c 100644 --- a/Assignment3Project/Assignment3Project/bullet.h +++ b/Assignment3Project/Assignment3Project/bullet.h @@ -7,6 +7,7 @@ class Bullet : public GameElement { public: Bullet(Behavior _behavior); + //implementing virtual void reset_pos(float x, float y); void draw(); void move(Direction dir); diff --git a/Assignment3Project/Assignment3Project/enemies.txt b/Assignment3Project/Assignment3Project/enemies.txt index 565a32c..151b182 100644 --- a/Assignment3Project/Assignment3Project/enemies.txt +++ b/Assignment3Project/Assignment3Project/enemies.txt @@ -1 +1 @@ -n,10,240 \ No newline at end of file +e,10,240 \ No newline at end of file diff --git a/Assignment3Project/Assignment3Project/enemy.bmp b/Assignment3Project/Assignment3Project/enemy.bmp new file mode 100644 index 0000000..444523d Binary files /dev/null and b/Assignment3Project/Assignment3Project/enemy.bmp differ diff --git a/Assignment3Project/Assignment3Project/enums.h b/Assignment3Project/Assignment3Project/enums.h index 37e3494..c0b0cc2 100644 --- a/Assignment3Project/Assignment3Project/enums.h +++ b/Assignment3Project/Assignment3Project/enums.h @@ -28,4 +28,17 @@ enum Direction { enum Behavior { Player, Enemy +}; + +struct Hitbox { + int x; + int y; + int height; + int width; +}; + +struct NewEnemy { + int x; + Behavior e_type; + int when; }; \ No newline at end of file diff --git a/Assignment3Project/Assignment3Project/game.cpp b/Assignment3Project/Assignment3Project/game.cpp index 79771d1..9807274 100644 --- a/Assignment3Project/Assignment3Project/game.cpp +++ b/Assignment3Project/Assignment3Project/game.cpp @@ -12,6 +12,7 @@ void Game::init() { score = 0; state = Start; sprites.insert(pair("Ship", al_load_bitmap("placeholder.bmp"))); + sprites.insert(pair("Enemy", al_load_bitmap("enemy.bmp"))); al_reserve_samples(4); diff --git a/Assignment3Project/Assignment3Project/game_element.h b/Assignment3Project/Assignment3Project/game_element.h index 05e0ffb..715dc03 100644 --- a/Assignment3Project/Assignment3Project/game_element.h +++ b/Assignment3Project/Assignment3Project/game_element.h @@ -15,6 +15,7 @@ public: float width; bool oob; Behavior behavior; + Hitbox hitbox; virtual void reset_pos(float x, float y) = 0; virtual void move(Direction dir) = 0; diff --git a/Assignment3Project/Assignment3Project/game_screen.cpp b/Assignment3Project/Assignment3Project/game_screen.cpp index 26def4b..3529929 100644 --- a/Assignment3Project/Assignment3Project/game_screen.cpp +++ b/Assignment3Project/Assignment3Project/game_screen.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -18,6 +19,8 @@ using std::vector; using std::string; using std::ostringstream; +using std::istringstream; +using std::ifstream; using std::map; using std::pair; @@ -42,13 +45,38 @@ void GameScreen::reset() { //If a sample needs to be played while it is still being played, it will be stopped first. //Admittedly this was a hack solution to the fact that my sound effect samples are too long. //In future projects I will use a better program for sound effect creation that does not have a large minimum length for audio export. -void play(ALLEGRO_SAMPLE_INSTANCE* x) { +void GameScreen::play(ALLEGRO_SAMPLE_INSTANCE* x) { if (al_get_sample_instance_playing(x)) { al_stop_sample_instance(x); } al_play_sample_instance(x); } +void GameScreen::build_enemy_queue() { + string line; + ifstream enemies_file("enemies.txt"); + + if (enemies_file.is_open()) { + while (getline(enemies_file, line)) { + NewEnemy next; + istringstream curr_line(line); + string element; + //Get enemy type (when there's other types of enemies I'll fix this) + getline(curr_line, element, ','); + next.e_type = Enemy; + //Get appearance time + getline(curr_line, element, ','); + next.when = stoi(element); + //Get position + getline(curr_line, element, ','); + next.x = stoi(element); + enemy_q.push_back(next); + } + } + + enemies_file.close(); +} + void GameScreen::run(ALLEGRO_FONT* font) { ALLEGRO_EVENT_QUEUE* event_queue = NULL; event_queue = al_create_event_queue(); @@ -58,6 +86,11 @@ void GameScreen::run(ALLEGRO_FONT* font) { timer = al_create_timer(1.0 / FPS); al_register_event_source(event_queue, al_get_timer_event_source(timer)); + build_enemy_queue(); + bool more_enemies = true; + NewEnemy next_enemy = enemy_q.back(); + enemy_q.pop_back(); + //MapLoad((char*)"level.fmp", 1); map_y = TILE_SIZE * LEVEL_LEN; @@ -132,7 +165,22 @@ void GameScreen::run(ALLEGRO_FONT* font) { next_state = Exit; } + if (more_enemies && map_y >= next_enemy.when) { + Ship* new_e = new Ship(next_enemy.e_type); + new_e->set_sprite(sprites["Enemy"]); + new_e->reset_pos(next_enemy.x, 0 - new_e->height + 1); + objects.enemies.push_back(new_e); + if (enemy_q.size() > 0) { + next_enemy = enemy_q.back(); + enemy_q.pop_back(); + } + else { + more_enemies = false; + } + } + //Global refresh + objects.move_enemies(); al_clear_to_color(al_map_rgb(0, 0, 0)); redraw(font); al_flip_display(); @@ -216,6 +264,7 @@ void GameScreen::run(ALLEGRO_FONT* font) { //Garbage collection //MapFreeMem(); + objects.destroy_objects(); al_destroy_event_queue(event_queue); al_destroy_timer(timer); } diff --git a/Assignment3Project/Assignment3Project/game_screen.h b/Assignment3Project/Assignment3Project/game_screen.h index 80c4e3f..fdbbe7b 100644 --- a/Assignment3Project/Assignment3Project/game_screen.h +++ b/Assignment3Project/Assignment3Project/game_screen.h @@ -21,6 +21,7 @@ public: ObjectManager objects; unsigned int max_bullets; + std::vector enemy_q; GameScreen(std::map _sprites, std::map _samples); @@ -29,4 +30,7 @@ public: void redraw(ALLEGRO_FONT* font); void back(); void cont(); +private: + void play(ALLEGRO_SAMPLE_INSTANCE* x); + void build_enemy_queue(); }; \ No newline at end of file diff --git a/Assignment3Project/Assignment3Project/object_manager.cpp b/Assignment3Project/Assignment3Project/object_manager.cpp index de6989f..462b8cf 100644 --- a/Assignment3Project/Assignment3Project/object_manager.cpp +++ b/Assignment3Project/Assignment3Project/object_manager.cpp @@ -2,6 +2,7 @@ using std::vector; + ObjectManager::ObjectManager() { } @@ -11,17 +12,57 @@ void ObjectManager::initiate(Ship * _player) { } bool ObjectManager::chk_player_col() { - return false; + for (vector::iterator it = enemies.begin(); it != enemies.end(); it++) { + if (col_eval(player->hitbox, (*it)->hitbox)) { + return true; + } + } } int ObjectManager::chk_bullet_col() { - return 0; + int points = 0; + int i = 0; + vector dead; + for (vector::iterator it = enemies.begin(); it != enemies.end(); it++) { + for (vector::iterator it_b = player_bullets.begin(); it_b != player_bullets.end(); it++) { + if (col_eval((*it_b)->hitbox, (*it)->hitbox)) { + switch ((*it)->behavior) { + default: + points += 10; + } + delete *it; + dead.push_back(i); + } + } + i++; + } + //Removed backwards to avoid indexing errors + for (vector::iterator it = dead.end(); it != dead.begin(); it--) { + enemies.erase(enemies.begin() + *it); + } + return points; } void ObjectManager::draw_objects() { player->draw(); + int i = 0; + vector dead; + for (vector::iterator it = enemies.begin(); it != enemies.end(); it++) { + if (!(*it)->oob) { + (*it)->draw(); + } + else { + dead.push_back(i); + } + i++; + } + //Removed backwards to avoid indexing errors + for (vector::iterator it = dead.end(); it != dead.begin(); it--) { + enemies.erase(enemies.begin() + *it); + } + bool unload = false; for (unsigned int i = 0; i < player_bullets.size(); i++) { if (player_bullets.at(i)->oob) { @@ -37,3 +78,33 @@ void ObjectManager::draw_objects() } } +void ObjectManager::destroy_objects() { + delete player; + + for (vector::iterator it = enemies.begin(); it != enemies.end(); it++) { + delete *it; + } + enemies.clear(); + + for (vector::iterator it = player_bullets.begin(); it != player_bullets.end(); it++) { + delete *it; + } + player_bullets.clear(); + + for (vector::iterator it = enemy_bullets.begin(); it != enemy_bullets.end(); it++) { + delete *it; + } + enemy_bullets.clear(); +} + +void ObjectManager::move_enemies() { + for (vector::iterator it = enemies.begin(); it != enemies.end(); it++) { + (*it)->move(D); + } +} + +bool ObjectManager::col_eval(Hitbox h1, Hitbox h2) { + if ((h1.x > h2.x && h1.x < (h2.x + h2.width)) && (h1.y > h2.y && h1.y < (h2.y + h2.height))) { + return true; + } +} \ No newline at end of file diff --git a/Assignment3Project/Assignment3Project/object_manager.h b/Assignment3Project/Assignment3Project/object_manager.h index 72ad32b..9018f14 100644 --- a/Assignment3Project/Assignment3Project/object_manager.h +++ b/Assignment3Project/Assignment3Project/object_manager.h @@ -18,4 +18,9 @@ public: bool chk_player_col(); int chk_bullet_col(); void draw_objects(); + void destroy_objects(); + void move_enemies(); + +private: + bool col_eval(Hitbox h1, Hitbox h2); }; \ No newline at end of file diff --git a/Assignment3Project/Assignment3Project/ship.cpp b/Assignment3Project/Assignment3Project/ship.cpp index 60aeb96..1810c3e 100644 --- a/Assignment3Project/Assignment3Project/ship.cpp +++ b/Assignment3Project/Assignment3Project/ship.cpp @@ -6,24 +6,33 @@ Ship::Ship(Behavior _behavior) { speed = 1.2; height = 40; width = 40; + + l_bound = SCREEN_L_B; + r_bound = SCREEN_R_B; + h_bound = SCREEN_H; break; default: - speed = 1.0; + speed = 0.5; height = 40; width = 40; - break; - } - l_bound = SCREEN_L_B; - r_bound = SCREEN_R_B; - r_bound -= width; - h_bound = SCREEN_H; - h_bound -= height; + l_bound = SCREEN_L_B; + r_bound = SCREEN_R_B; + r_bound -= width; + h_bound = SCREEN_H; + h_bound -= height; + break; + } } void Ship::reset_pos(float x, float y) { x_pos = x; y_pos = y; + + hitbox.x = x_pos; + hitbox.y = y_pos; + hitbox.width = width; + hitbox.height = height; } void Ship::set_sprite(ALLEGRO_BITMAP* _sprite) { @@ -31,7 +40,7 @@ void Ship::set_sprite(ALLEGRO_BITMAP* _sprite) { } void Ship::draw() { - al_draw_bitmap(sprite, x_pos, y_pos, NULL); + al_draw_bitmap(sprite, x_pos, y_pos, (behavior == Player) ? NULL : ALLEGRO_FLIP_VERTICAL); } void Ship::move(Direction dir) { @@ -68,16 +77,28 @@ void Ship::move(Direction dir) { } if (x_pos <= l_bound) { - x_pos = l_bound; + if (behavior == Player) { + x_pos = l_bound; + } + else oob = true; } else if (x_pos >= r_bound) { - x_pos = r_bound; + if (behavior == Player) { + x_pos = r_bound; + } + else oob = true; } if (y_pos <= 0.0) { - y_pos = 0.0; + if (behavior == Player) { + y_pos = 0.0; + } + else oob = true; } else if (y_pos >= h_bound) { - y_pos = h_bound; + if (behavior == Player) { + y_pos = h_bound; + } + else oob = true; } } diff --git a/Assignment3Project/Assignment3Project/ship.h b/Assignment3Project/Assignment3Project/ship.h index 4ac5510..0cdcaf9 100644 --- a/Assignment3Project/Assignment3Project/ship.h +++ b/Assignment3Project/Assignment3Project/ship.h @@ -12,9 +12,12 @@ public: Ship(Behavior _behavior); + //implementing virtual methods void reset_pos(float x, float y); - void set_sprite(ALLEGRO_BITMAP* _sprite); void draw(); void move(Direction dir); + + //unique to object + void set_sprite(ALLEGRO_BITMAP* _sprite); Bullet fire(); }; \ No newline at end of file diff --git a/cheesetheme.wav b/cheesetheme.wav deleted file mode 100644 index 32a1e3b..0000000 Binary files a/cheesetheme.wav and /dev/null differ