Enemy functionality and hit detection working but not really tested and probably buggy and will probably stay that way LOL

main
Braydon Kains 6 years ago
parent f35c70c86e
commit f266425a2f

@ -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() {

@ -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);

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

@ -29,3 +29,16 @@ enum Behavior {
Player,
Enemy
};
struct Hitbox {
int x;
int y;
int height;
int width;
};
struct NewEnemy {
int x;
Behavior e_type;
int when;
};

@ -12,6 +12,7 @@ void Game::init() {
score = 0;
state = Start;
sprites.insert(pair<string, ALLEGRO_BITMAP*>("Ship", al_load_bitmap("placeholder.bmp")));
sprites.insert(pair<string, ALLEGRO_BITMAP*>("Enemy", al_load_bitmap("enemy.bmp")));
al_reserve_samples(4);

@ -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;

@ -6,6 +6,7 @@
#include <vector>
#include <string>
#include <sstream>
#include <fstream>
#include <map>
#include <ctime>
@ -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);
}

@ -21,6 +21,7 @@ public:
ObjectManager objects;
unsigned int max_bullets;
std::vector<NewEnemy> enemy_q;
GameScreen(std::map<std::string, ALLEGRO_BITMAP*> _sprites, std::map<std::string, ALLEGRO_SAMPLE*> _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();
};

@ -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<Ship*>::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<int> dead;
for (vector<Ship*>::iterator it = enemies.begin(); it != enemies.end(); it++) {
for (vector<Bullet*>::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<int>::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<int> dead;
for (vector<Ship*>::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<int>::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<Ship*>::iterator it = enemies.begin(); it != enemies.end(); it++) {
delete *it;
}
enemies.clear();
for (vector<Bullet*>::iterator it = player_bullets.begin(); it != player_bullets.end(); it++) {
delete *it;
}
player_bullets.clear();
for (vector<Bullet*>::iterator it = enemy_bullets.begin(); it != enemy_bullets.end(); it++) {
delete *it;
}
enemy_bullets.clear();
}
void ObjectManager::move_enemies() {
for (vector<Ship*>::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;
}
}

@ -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);
};

@ -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;
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,17 +77,29 @@ void Ship::move(Direction dir) {
}
if (x_pos <= l_bound) {
if (behavior == Player) {
x_pos = l_bound;
}
else oob = true;
}
else if (x_pos >= r_bound) {
if (behavior == Player) {
x_pos = r_bound;
}
else oob = true;
}
if (y_pos <= 0.0) {
if (behavior == Player) {
y_pos = 0.0;
}
else oob = true;
}
else if (y_pos >= h_bound) {
if (behavior == Player) {
y_pos = h_bound;
}
else oob = true;
}
}
Bullet Ship::fire() {

@ -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();
};

Binary file not shown.
Loading…
Cancel
Save