Cookie::Bool Cookie::Physics::resolve_collision(Cookie::Node* nodeAPtr, Cookie::Node* nodeBPtr) { Cookie::Bool collision_detected = false; if(nodeAPtr != nodeBPtr) { Cookie::PhysicsBodyType bodyAType = nodeAPtr->physics_body()->body_type(); Cookie::PhysicsBodyType bodyBType = nodeBPtr->physics_body()->body_type(); if(bodyAType == RECTANGLE_BODY) { if(bodyBType == RECTANGLE_BODY) { collision_detected = resolve_collision( *(static_cast<Cookie::RectBody*>(nodeAPtr->physics_body())), *(static_cast<Cookie::RectBody*>(nodeBPtr->physics_body())) ); }else if(bodyAType == CIRCLE_BODY) { collision_detected = resolve_collision( *(static_cast<Cookie::RectBody*>(nodeAPtr->physics_body())), *(static_cast<Cookie::CircleBody*>(nodeBPtr->physics_body())) ); } }else if (bodyAType == CIRCLE_BODY) { if(bodyBType == CIRCLE_BODY) { collision_detected = resolve_collision( *(static_cast<Cookie::CircleBody*>(nodeAPtr->physics_body())), *(static_cast<Cookie::CircleBody*>(nodeBPtr->physics_body())) ); }else if(bodyBType == RECTANGLE_BODY) { collision_detected = resolve_collision( *(static_cast<Cookie::RectBody*>(nodeBPtr->physics_body())), *(static_cast<Cookie::CircleBody*>(nodeAPtr->physics_body())) ); } } return collision_detected; } return false; }
void Cookie::Physics::update(Cookie::Game& game) { //Temporary static Cookie::Float friction = 0.9f; std::vector<Cookie::Node*> nodes; get_all_nodes_with_physics_body(nodes, game.world()); Cookie::Float time = game.time_elapsed() / 1000.0f; for(auto node = nodes.begin(); node != nodes.end(); ++node) { Cookie::Node* nodePtr = *node; Cookie::Vector vel = nodePtr->physics_body()->velocity(); if(nodePtr->physics_body()->dynamic()) { if(!nodePtr->physics_body()->ignores_gravity()) { vel += gravity_; } nodePtr->translate_by(vel.x * time, vel.y * time); // vel *= friction; nodePtr->physics_body()->set_velocity(vel); } } for(auto nodeA = nodes.begin(); nodeA != nodes.end(); ++nodeA) { for(auto nodeB = nodes.begin(); nodeB != nodes.end(); ++nodeB) { if(resolve_collision(*nodeA, *nodeB)) { push_collision((*nodeA)->physics_body(), (*nodeB)->physics_body()); } } } notify_collision_handlers(); }
void update() { if(quit) return; if(game_state != INSTRUCTION) if(keydown == SDLK_ESCAPE) { move_to_main_menu(); return; } if(keydown == SDLK_h) { move_to_instruction_state(); return; } switch(game_state) { case MAIN_MENU: update_main_menu(); break; case PLAY: { if(striker.state == RELEASED) { update_striker(&striker); int i; for(i = 0; CHIPS[i]; i++) if(CHIPS[i]->mov.state != OUT_OF_GAME) integrate(&CHIPS[i]->mov); for(i = 0; CHIPS[i]; i++) if(CHIPS[i]->mov.state != OUT_OF_GAME) resolve_collision(&striker.mov, &CHIPS[i]->mov); int j; for(i = 0; CHIPS[i]; i++) { if(CHIPS[i]->mov.state != OUT_OF_GAME) { for(j = i + 1; CHIPS[j]; j++) { if(CHIPS[j]->mov.state != OUT_OF_GAME) resolve_collision(&CHIPS[i]->mov, &CHIPS[j]->mov); } } } for(i = 0; CHIPS[i]; i++) { if(CHIPS[i]->mov.state != OUT_OF_GAME) { resolve_collision_with_hole(&CHIPS[i]->mov, &board); resolve_collision_with_board(&CHIPS[i]->mov, &board); } } resolve_collision_with_hole(&striker.mov, &board); resolve_collision_with_board(&striker.mov, &board); if(!chips_on_board) { move_to_game_over_state(); return; } int all_stopped = 1; for(i = 0; CHIPS[i]; i++) { if(CHIPS[i]->mov.state == MOVING) { all_stopped = 0; break; } } if(striker.mov.state == MOVING) all_stopped = 0; if(all_stopped) { // calculate score // assign striker to square if(striker.mov.in_hole) { second_chance = 0; } increment_current_player(); move_to_with_player(&striker, current_player); } } else { update_striker(&striker); } } break; case INSTRUCTION: if(keydown || left_mouse_button_down) move_to_state(back_state); break; } }