Skip to content

Commit

Permalink
Rework how objects get killed
Browse files Browse the repository at this point in the history
  • Loading branch information
commandblockguy committed Jan 18, 2021
1 parent 841638d commit 550869b
Show file tree
Hide file tree
Showing 11 changed files with 67 additions and 40 deletions.
12 changes: 6 additions & 6 deletions src/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
bool start_mission(const serialized_tank_t *ser_tanks) {
dbg_printf("starting mission\n");

while(!PhysicsBody::objects.empty()) {
// Delete objects without killing
delete PhysicsBody::objects[0];
for(auto & obj : PhysicsBody::objects) {
obj->active = false;
}
PhysicsBody::remove_inactive();

game.num_tanks = 0;

Expand Down Expand Up @@ -67,9 +67,11 @@ uint8_t play_mission(const serialized_tank_t *ser_tanks) {
for(auto & object : PhysicsBody::objects) {
object->tick();
}
PhysicsBody::remove_inactive();
PhysicsBody::sort();
profiler_end(physics);

if(!game.player_alive) {
if(!game.player) {
profiler_end(total);
game.lives--;
if(!game.lives) {
Expand All @@ -84,8 +86,6 @@ uint8_t play_mission(const serialized_tank_t *ser_tanks) {
return NEXT_LEVEL;
}

PhysicsBody::sort();

render();

game.tick++;
Expand Down
1 change: 0 additions & 1 deletion src/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ typedef struct {
uint8_t lives; //Number of remaining tanks. This includes the tank that is currently in use, so a value of 1 means that the game will end the next time the tank is hit.
uint8_t total_kills; //Number of enemy tanks destroyed.
uint8_t kills[NUM_TANK_TYPES];
bool player_alive;
uint8_t num_tanks;
bool alive_tanks[MAX_NUM_TANKS];
Tank *player;
Expand Down
22 changes: 14 additions & 8 deletions src/objects/mine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ Mine::Mine(Tank *tank) {
position_x = tank->position_x + (TANK_SIZE - MINE_SIZE) / 2;
position_y = tank->position_y + (TANK_SIZE - MINE_SIZE) / 2;

velocity_x = 0;
velocity_y = 0;

parent = tank;

new (std::nothrow) MineDetector(this);
Expand All @@ -45,7 +42,7 @@ void Mine::process() {
detonate();
}
if(countdown == 0) {
kill();
active = false;
}

//todo: range detection
Expand Down Expand Up @@ -91,6 +88,11 @@ void Mine::render(uint8_t layer) {
}

void Mine::detonate() {
if(countdown < EXPLOSION_ANIM) {
// Don't explode multiple times
return;
}

countdown = EXPLOSION_ANIM - 1;

// todo: The original game uses a radius, not a square
Expand All @@ -107,15 +109,19 @@ void Mine::detonate() {
}

// Kill any nearby physics objects
for(auto *it = objects.begin(); it < objects.end();) {
if(*it != this && center_distance_less_than(*it, MINE_EXPLOSION_RADIUS)) {
(**it).kill();
} else it++;
for(auto & obj : objects) {
if(obj != this && center_distance_less_than(obj, MINE_EXPLOSION_RADIUS)) {
obj->handle_explosion();
}
}

generate_bg_tilemap();
}

void Mine::handle_explosion() {
detonate();
}

void Mine::handle_collision(PhysicsBody *other) {
other->collide(this);
}
Expand Down
2 changes: 2 additions & 0 deletions src/objects/mine.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ class Mine: public PhysicsBody {

void detonate();

void handle_explosion();

void handle_collision(PhysicsBody *other);
void collide(Tank *tank);
void collide(Shell *shell);
Expand Down
7 changes: 2 additions & 5 deletions src/objects/mine_detector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,11 @@ MineDetector::MineDetector(Mine *mine) {
position_x = mine->center_x() - MINE_EXPLOSION_RADIUS;
position_y = mine->center_y() - MINE_EXPLOSION_RADIUS;

velocity_x = 0;
velocity_y = 0;

parent = mine;
}

void MineDetector::process() {
if(!parent) kill();
if(!parent) active = false;

if(!primed) {
Tank *placer = (Tank*)parent->parent;
Expand All @@ -43,7 +40,7 @@ void MineDetector::collide(__attribute__((unused)) Tank *tank) {
if(parent) {
((Mine*)parent)->countdown = MINE_TRIGGERED;
}
kill();
active = false;
}
}

Expand Down
33 changes: 21 additions & 12 deletions src/objects/physicsbody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ uint PhysicsBody::center_y() const {
}

PhysicsBody::PhysicsBody() {
active = true;
parent = nullptr;
velocity_x = 0;
velocity_y = 0;

// todo: compiler bug triggers if this line is the only thing in here
objects.push_back(this);

Expand All @@ -24,19 +29,7 @@ PhysicsBody::PhysicsBody() {
}

PhysicsBody::~PhysicsBody() {
// Remove from object list
for(auto *it = objects.begin(); it < objects.end();) {
// Inform any children that we no longer exist
if((**it).parent == this) (**it).parent = nullptr;
// Remove from objects list
if(*it == this) {
objects.erase(it);
} else it++;
}
}

void PhysicsBody::kill() {
delete this;
}

void PhysicsBody::sort() {
Expand All @@ -52,6 +45,18 @@ void PhysicsBody::sort() {
}
}

void PhysicsBody::remove_inactive() {
for(auto & obj : objects) {
if(!obj->parent->active) obj->parent = nullptr;
}
for(auto *it = objects.begin(); it < objects.end();) {
if(!(*it)->active) {
delete *it;
it = objects.erase(it);
} else it++;
}
}

bool PhysicsBody::detect_collision(PhysicsBody *other) const {
return position_x < other->position_x + (int)other->width &&
position_x + (int)width > other->position_x &&
Expand Down Expand Up @@ -172,3 +177,7 @@ void PhysicsBody::tick() {
void PhysicsBody::handle_tile_collision(__attribute__((unused)) direction_t dir) {

}

void PhysicsBody::handle_explosion() {
// Do nothing, by default
}
4 changes: 3 additions & 1 deletion src/objects/physicsbody.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class PhysicsBody {
uint width;
uint height;
PhysicsBody *parent;
bool active;

bool tile_collisions;
// Whether or not to collide with holes
Expand All @@ -44,12 +45,13 @@ class PhysicsBody {
void tick();

static void sort();
static void remove_inactive();

virtual void kill();
virtual void process() = 0;
virtual void render(uint8_t layer);

virtual void handle_tile_collision(direction_t dir);
virtual void handle_explosion();

// Polymorphic ping-pong (aka "visitor pattern," apparently)
virtual void handle_collision(PhysicsBody *other) = 0;
Expand Down
10 changes: 8 additions & 2 deletions src/objects/shell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ Shell::Shell(Tank *tank) {

Shell::~Shell() {
if(parent) {
// todo: see if there's a way to do this without an ugly cast
((Tank*)parent)->num_shells--;
}
}
Expand Down Expand Up @@ -70,6 +69,10 @@ void Shell::update_direction() {
direction = angle_to_shell_direction(angle);
}

void Shell::handle_explosion() {
kill();
}

void Shell::handle_collision(PhysicsBody *other) {
other->collide(this);
}
Expand Down Expand Up @@ -99,7 +102,6 @@ void Shell::handle_tile_collision(direction_t dir) {
return;
}

//shell_t is still alive
if(dir & UP || dir & DOWN) {
velocity_y *= -1;
update_direction();
Expand All @@ -115,3 +117,7 @@ void Shell::handle_tile_collision(direction_t dir) {
void Shell::collide(__attribute__((unused)) MineDetector *detector) {
// don't do anything
}

void Shell::kill() {
active = false;
}
4 changes: 4 additions & 0 deletions src/objects/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ class Shell: public PhysicsBody {
return ((uint8_t) -((angle >> (INT_BITS - 8)) - 64)) >> 4;
}

void kill();

void handle_explosion();

void handle_collision(PhysicsBody *other);
void collide(Tank *tank);
void collide(Shell *shell);
Expand Down
10 changes: 5 additions & 5 deletions src/objects/tank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,13 @@ Tank::Tank(const serialized_tank_t *ser_tank, uint8_t id) {
start_y = ser_tank->start_y + 1;
position_x = TILE_TO_X_COORD(start_x);
position_y = TILE_TO_Y_COORD(start_y);
velocity_x = 0;
velocity_y = 0;
barrel_rot = 0;
tread_rot = 0;
shot_cooldown = 0;
mine_cooldown = 0;

if(id == 0) {
game.player = this;
game.player_alive = true;
}

game.num_tanks++;
Expand All @@ -60,7 +57,6 @@ Tank::Tank(const serialized_tank_t *ser_tank, uint8_t id) {
Tank::~Tank() {
game.num_tanks--;
if(this == game.player) {
game.player_alive = false;
game.player = nullptr;
}
}
Expand All @@ -72,7 +68,7 @@ void Tank::kill() {
game.alive_tanks[id] = false;
}

delete this;
active = false;
}

void Tank::process() {
Expand Down Expand Up @@ -173,6 +169,10 @@ void Tank::handle_collision(PhysicsBody *other) {
other->collide(this);
}

void Tank::handle_explosion() {
kill();
}

void Tank::collide(Tank *tank) {
//Figure out if the four corners are colliding
bool top_right = tank->is_point_inside(position_x + width, position_y);
Expand Down
2 changes: 2 additions & 0 deletions src/objects/tank.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class Tank: public PhysicsBody {
static const uint8_t max_mines[];
static const uint8_t velocities[];

void handle_explosion();

void handle_collision(PhysicsBody *other);
void collide(Tank *tank);
void collide(Shell *shell);
Expand Down

0 comments on commit 550869b

Please sign in to comment.