diff options
Diffstat (limited to 'game_overwatch.cpp')
| -rw-r--r-- | game_overwatch.cpp | 419 |
1 files changed, 419 insertions, 0 deletions
diff --git a/game_overwatch.cpp b/game_overwatch.cpp new file mode 100644 index 0000000..32e9ad1 --- /dev/null +++ b/game_overwatch.cpp @@ -0,0 +1,419 @@ +#include "stdafx.h" + + +Game_overwatch::Game_overwatch(){ + //Initialize our population + head = NULL; + population = 0; +} + + +void Game_overwatch::move_out(Actor *npc){ + + //Moving out means killing a citizen from the citizen linked list. + + citizen *curr, *prev; + prev = NULL; + + for(curr=head;curr!=NULL;prev=curr,curr=curr->next){ + if (curr->val == npc) { + if (prev == NULL) { + head = curr->next; + std::cout << "I have deleted an NPC from the top!\n"; + } else { + prev->next = curr->next; + std::cout << "I have deleted an NPC from the middle!\n"; + } + + delete curr; + + } + } + population--; +} + +void Game_overwatch::move_in(Actor * npc){ + //Moving in means adding a citizen to the linkd list. + + citizen *curr; + curr = new citizen; + curr->val = npc; + curr->next = head; + head=curr; + population++; +} + +int Game_overwatch::get_population(){ + return population; +} + +void Game_overwatch::draw(SDL_Surface *viewport, Map *mainmap){ + + //Generic draw function, iterates over the list and draws + //each one of them. + + //NOTE: Further along it may be wise to allow Lua scripts to + // override the draw function and just call curr->draw(); + + citizen *curr; + curr = head; + while (curr != NULL){ + Gfx::drawsurface(curr->val->get_clip_x(),curr->val->get_clip_y(), + curr->val->get_w(),curr->val->get_h(), + curr->val->get_sprite(), + curr->val->get_x()-mainmap->get_sx(),curr->val->get_y()-mainmap->get_sy(), + viewport); + curr = curr->next; + } +} + +void Game_overwatch::act(SDL_Surface *viewport, Map *mainmap, bool keys[323]){ + + //Iterates over the list and runs the "act" function from the lua script. + + citizen *curr; + curr = head; + while (curr != NULL){ + curr->val->move(); + handleinput(curr->val, keys); + + //do the lua thing. + curr->val->SelectScriptFunction ("act"); + curr->val->Go (); + + curr = curr->next; + } +} + +void Game_overwatch::handleinput(Actor *actor, bool keys[323]){ + + //Right now these actions just map keys to variables the scripts can use + //In the future it will be wise to abstract the keys to what they do + //Also, take into account gamepads. + //Preferably, let lua handle this somehow. + + if(keys[SDLK_LEFT]){ + if(leftkey == 0){ + leftkey = SDL_GetTicks(); + } + }else{ + leftkey = 0; + } + + if(keys[SDLK_RIGHT]){ + + if(rightkey == 0){ + rightkey = SDL_GetTicks(); + } + }else{ + rightkey = 0; + } + + if(keys[SDLK_z]){ + if(zkey == 0){ + zkey = SDL_GetTicks(); + } + }else{ + zkey = 0; + } + + if(keys[SDLK_x]){ + if(xkey == 0){ + xkey = SDL_GetTicks(); + } + }else{ + xkey = 0; + } + + if(keys[SDLK_c]){ + if(ckey == 0){ + ckey = SDL_GetTicks(); + } + }else{ + ckey = 0; + } + + actor->set_leftkey(leftkey); + actor->set_rightkey(rightkey); + actor->set_zkey(zkey); + actor->set_xkey(xkey); + actor->set_ckey(ckey); +} + +void Game_overwatch::animate(){ + //Iterate and run the animate method. + + citizen *curr; + curr = head; + while (curr != NULL){ + curr->val->animate(); + curr = curr->next; + } +} + +void Game_overwatch::check_collisions(Map *mainmap){ + citizen *curr, *others; + + bool collided = false; + curr = head; + others = head->next; + Actor *ac1, *ac2; + + //now check everyone. Never with itself. + //It does line collisions, not corner collisions. + + while (curr != NULL){ + ac1 = curr->val; + while (others != NULL) { + ac2 = others->val; + collided = false; + if (curr->val != others->val) { + if(Game_overwatch::line_colliding(ac1->get_x(), ac1->get_w(), + ac1->get_y(), ac1->get_h(), + ac2->get_x(), ac2->get_w(), + ac2->get_y(), ac2->get_h(), + UP)){ + + ac2->set_collision(true, DOWN); + ac2->set_speed(ac1->get_ownspeed()); + ac2->set_vertical_speed(ac2->get_vertical_speed()+ac1->get_vertical_speed()); + + ac1->set_collision(true, UP); + collided = true; + } + if(Game_overwatch::line_colliding(ac1->get_x(), ac1->get_w(), + ac1->get_y(), ac1->get_h(), + ac2->get_x(), ac2->get_w(), + ac2->get_y(), ac2->get_h(), + DOWN)){ + + ac2->set_collision(true, UP); + ac1->set_collision(true, DOWN); + collided = true; + } + if(Game_overwatch::line_colliding(ac1->get_x(), ac1->get_w(), + ac1->get_y(), ac1->get_h(), + ac2->get_x(), ac2->get_w(), + ac2->get_y(), ac2->get_h(), + LEFT)){ + + ac2->set_collision(true, RIGHT); + ac1->set_collision(true, LEFT); + collided = true; + } + if(Game_overwatch::line_colliding(ac1->get_x(), ac1->get_w(), + ac1->get_y(), ac1->get_h(), + ac2->get_x(), ac2->get_w(), + ac2->get_y(), ac2->get_h(), + RIGHT)){ + + ac2->set_collision(true, LEFT); + ac1->set_collision(true, RIGHT); + collided = true; + } + } + + others = others->next; + if(collided){ + collision_callback(ac1, ac2); + } + + } + + curr = curr->next; + if (curr != NULL){ + others = curr->next; + } + } +} + +void Game_overwatch::collision_callback(Actor *ac1, Actor *ac2){ + + std::cout << "The collision has called "; + + if (ac1->get_enemy() == WEAPON && !ac2->get_dying()) { + if (ac2->get_enemy() == EVIL) { + ac1->set_dying(true); + ac2->set_dying(true); + + + std::cout << "And the shot has destroyed the enemy."; + } + } + + if (ac1->get_enemy() == SUPEREVIL) { + ac2->set_dying(true); + std::cout << "And the shot has destroyed the enemy."; + } + + if (ac1->get_controllable()) { + if (ac2->get_enemy() == EVIL) { + ac1->set_dying(true); + + + std::cout << "And the enemy has destroyed the main actor."; + } + } + + if (ac1->get_enemy() == EVIL) { + if (ac2->get_controllable()) { + ac2->set_dying(true); + + + std::cout << "And the enemy has destroyed the main actor."; + } + } + + + std::cout << "\n"; +} + + +bool Game_overwatch::line_colliding(int x1, int w1, int y1, int h1, int x2, int w2, int y2, int h2, int direction){ + switch (direction) { + case UP: + if (y1 <= y2+h2 && y1 >= y2+(h2/2) && + ((x1 > x2 && x1 < x2+w2) || + (x1+w1 > x2 && x1+w2 < x2+w2))) { + std::cout << "Foo' is collidin' top\n"; + return true; + } + break; + case DOWN: + if (y1+h1 >= y2 && y1+h1 <= y2+(h2/2) && + ((x1 > x2 && x1 < x2+w2) || + (x1+w1 > x2 && x1+w2 < x2+w2))) { + std::cout << "Foo' is collidin' bottom\n"; + return true; + } + break; + case LEFT: + if (x1 <= x2+w2 && x1 >= x2+(w2/2) && + ((y1 > y2 && y1 < y2+h2) || + (y1+h1 > y2 && y1+h1 < y2+h2))) { + std::cout << "Foo' is collidin' left\n"; + return true; + } + break; + case RIGHT: + if (x1+w1 >= x2 && x1+w1 <= x2+(w2/2) && + ((y1 > y2 && y1 < y2+h2) || + (y1+h1 > y2 && y1+h1 < y2+h2))) { + std::cout << "Foo' is collidin' right\n"; + return true; + } + break; + } + + return false; +} + +void Game_overwatch::handlephysics(Map *mainmap, int ticks1, int ticks2){ + citizen *curr; + curr = head; + while (curr != NULL){ + + //some are not affected by physics. + if(curr->val->get_physics()){ + //can it fall? + if(curr->val->can_move(DOWN, curr->val->get_x(), curr->val->get_y())){ + + //change sprite to its jump. + switch(curr->val->get_oldclip()){ + case 1: + curr->val->set_clip_y(curr->val->get_h()*0); + break; + case 2: + curr->val->set_clip_y(curr->val->get_h()*3); + break; + } + + //start the fall process + if(curr->val->get_falltime() == 0){ + curr->val->set_falltime(.5); + }else{ + curr->val->set_falltime(curr->val->get_falltime()+(ticks2-ticks1)/1000); + } + + }else{ + + //stop falling. + curr->val->set_clip_y(curr->val->get_h()*curr->val->get_oldclip()); + curr->val->set_falltime(0); + if(curr->val->get_vertical_speed() > 0){ + curr->val->set_vertical_speed(0); + } + } + + //check for top collision + if( !curr->val->can_move(UP, curr->val->get_x(), curr->val->get_y()) && curr->val->get_vertical_speed() < 0){ + curr->val->set_vertical_speed(0); + } + + //Avoid falling through the ground + while(!curr->val->can_move(DOWN, curr->val->get_x(), curr->val->get_y()+curr->val->get_vertical_speed()) && curr->val->get_vertical_speed() > 0){ + curr->val->set_vertical_speed( curr->val->get_vertical_speed() - 1 ); + } + + //V=Vo+at + curr->val->set_vertical_speed( curr->val->get_vertical_speed() + (GRAVITY*curr->val->get_falltime())); + + //translate. + curr->val->set_y( curr->val->get_y() + curr->val->get_vertical_speed()); + } + + //NEXT + curr = curr->next; + } +} + +void Game_overwatch::reset_collisions(){ + citizen *curr; + curr = head; + while (curr != NULL){ + curr->val->set_collision(false, LEFT); + curr->val->set_collision(false, RIGHT); + curr->val->set_collision(false, DOWN); + curr->val->set_collision(false, UP); + curr = curr->next; + } +} + +void Game_overwatch::dieloop(){ + + //The kill loop: + // Every frame, we find out who needs to be killed + // We kill them all. + + citizen *curr; + curr = head; + while (curr != NULL){ + bool killthis = false; + if ( curr->val->get_dying() ){ + killthis = true; + } + + if (killthis){ + Actor *victim = curr->val; + curr = curr->next; + this->kill(victim); + }else{ + curr = curr->next; + } + } +} + +void Game_overwatch::kill(Actor *actor){ + + //This should probably delegate to the lua die function + //So it can animate/change states. + + if ( actor->get_controllable() ){ + actor->set_x(50); + actor->set_y(100); + actor->set_dying(false); + }else{ + delete actor; + actor = NULL; + } +}
\ No newline at end of file |