void Soldier::update(float delta) { sur.update(delta); FloatVector2d velocity; velocity.x = steering; velocity.y = acceleration; FloatVector2d new_pos = pos + (velocity * 100.0f * delta); BuildingMap* building_map = GameWorld::current()->get_buildingmap(); if (building_map->get_building(new_pos) == 0) { pos = new_pos; } else { // Soldier is stuck in a building, allow him to walk so he // can unstuck himself if (building_map->get_building(pos) != 0) pos = new_pos; else if (building_map->get_building(FloatVector2d(pos.x, new_pos.y)) == 0) pos = FloatVector2d(pos.x, new_pos.y); else if (building_map->get_building(FloatVector2d(new_pos.x, pos.y)) == 0) pos = FloatVector2d(new_pos.x, pos.y); } }
void Turret::draw (View& view) { float absolute_orientation = tank->get_orientation () + orientation; #ifdef UGLY_SHADOWS_ENABLED view.draw(shadow, tank->get_pos () + FloatVector2d (10,10), absolute_orientation); view.draw(shadow, tank->get_pos () + FloatVector2d (15,15), absolute_orientation); view.draw(shadow, tank->get_pos () + FloatVector2d (20,20), absolute_orientation); view.draw(shadow, tank->get_pos () + FloatVector2d (25,25), absolute_orientation); #endif sur.set_angle((absolute_orientation + Math::pi) / Math::pi * 180.0f); view.get_sc().color().draw(sur, tank->get_pos().x, tank->get_pos().y); if (fireing && reloading == 0 && tank->ammo > 0.0) { fire_sur.set_angle(Math::rad2deg(absolute_orientation + Math::pi)); view.get_sc().color().draw(fire_sur, tank->get_pos().x, tank->get_pos().y); fireing = false; reloading = reloading_speed; } }
WallDoor::WallDoor(const AList& lst) : Building(lst), sprite(), map_width(), map_height(), status(), pos() { if (lst.get_string("orientation") == "vertical") { sprite = resources->get_sprite("feuerkraft/vdoor"); pos = FloatVector2d(x_pos * 40 + 20, y_pos * 40 + 60); map_width = 1; map_height = 3; } else { sprite = resources->get_sprite("feuerkraft/hdoor"); pos = FloatVector2d(x_pos * 40 + 60, y_pos * 40 + 20); map_width = 3; map_height = 1; } }
void Explosion::update (float delta) { lifetime -= delta; new_particle_time += delta; if (new_particle_time > 0.200) { for (int i = 0; i < 4; ++i) { switch (en_size) { case LARGE: GameWorld::current()->add (new ExplosionParticle(FloatVector2d (pos.x + (rand()%40 - 20), pos.y + (rand()%40 - 20)), FloatVector2d (rand ()%20 - 10, rand ()%20 - 10), Random::frand(size) + 1.0)); GameWorld::current()->add (new ExplosionParticle(FloatVector2d (pos.x + (rand()%40 - 20), pos.y + (rand()%40 - 20)), FloatVector2d (rand ()%20 - 10, rand ()%20 - 10), Random::frand(size) + 1.0)); break; case MEDIUM: GameWorld::current()->add (new ExplosionParticle(FloatVector2d (pos.x + (rand()%10 - 5), pos.y + (rand()%10 - 5)), FloatVector2d (rand ()%20 - 10, rand ()%20 - 10), Random::frand(size) + .5)); break; default: GameWorld::current()->add (new ExplosionParticle(FloatVector2d (pos.x + (rand()%10 - 5), pos.y + (rand()%10 - 5)), FloatVector2d (rand ()%20 - 10, rand ()%20 - 10), Random::frand(size) + .01)); break; } lifetime = 0; } new_particle_time = 0; } }
void GameSession::init() { loops = 0; deltas = 0.0; start_time = CL_System::get_time (); frames = 0; collision_mgr = new CollisionManager(); buildingtypemanager = new BuildingTypeManager(); // Load helper functions // FIXME: These functions need a better place scm_c_primitive_load(path_manager.complete("feuerkraft.scm").c_str()); scm_c_primitive_load(path_manager.complete("input.scm").c_str()); // Deserialize the game world { std::cout << "<<<<<<<<<<<<< Parsing map <<<<<<<<<<<<<" << std::endl; SCM fdes = scm_open_file (scm_makfrom0str(filename.c_str()), scm_makfrom0str("r")); SCM lst = scm_read (fdes); scm_close (fdes); // unstable Testing stuff //OutputWorldBuilder builder; //SexprWorldReader(lst, &builder).run(); // Now we create the real world world = new GameWorld(lst); std::cout << ">>>>>>>>>>>>> Parsing map >>>>>>>>>>>>>" << std::endl; } // End: Test of parsing code // The all mighty soldier that the player controlls Soldier* soldier = new Soldier(AList()); soldier->set_position(FloatVector2d (500, 1100)); { Soldier* soldier = new Soldier(AList()); soldier->set_position(FloatVector2d (1400, 1500)); SoldierAI* ai = new SoldierAI(soldier); world->add(soldier); AIManager::instance()->add(ai); } { Soldier* soldier = new Soldier(AList()); soldier->set_position(FloatVector2d (1300, 1600)); SoldierAI* ai = new SoldierAI(soldier); world->add(soldier); AIManager::instance()->add(ai); } world->add(new RobotTank(660, 1245, 0, 100.0f)); world->add(new Helicopter(AList() .set_float("x-pos", 600) .set_float("y-pos", 1245) .set_int("type", 0))); world->add(new Helicopter(AList() .set_float("x-pos", 600) .set_float("y-pos", 1445) .set_int("type", 1))); world->add(new Helicopter(AList() .set_float("x-pos", 660) .set_float("y-pos", 1645) .set_int("type", 2))); world->add(new Tank(FloatVector2d (650, 1245), 5, "feuerkraft/tank", "feuerkraft/turret", "feuerkraft/fire2")); world->add(new Tank(FloatVector2d (750, 1245), 5, "feuerkraft/tank", "feuerkraft/turret", "feuerkraft/fire2")); world->add(new Tank(FloatVector2d (850, 1245), 5, "feuerkraft/tank", "feuerkraft/turret", "feuerkraft/fire2")); { Tank* tank = new Tank(FloatVector2d (450, 1245), 5, "feuerkraft/tank", "feuerkraft/turret", "feuerkraft/fire2"); world->add(tank); AIManager::instance()->add(new VehicleRoboAI(tank)); } { Tank* tank = new Tank(FloatVector2d (0, 1245), 5, "feuerkraft/tank2", "feuerkraft/turret", "feuerkraft/fire2"); world->add(tank); AIManager::instance()->add(new VehicleRoboAI(tank)); } { Tank* tank = new Tank(FloatVector2d (-100, 1245), 5, "feuerkraft/tank", "feuerkraft/turret2", "feuerkraft/fire2"); world->add(tank); AIManager::instance()->add(new VehicleRoboAI(tank)); } { Tank* tank = new Tank(FloatVector2d (560, 1245), 5, "feuerkraft/tank2", "feuerkraft/turret2", "feuerkraft/fire2"); world->add(tank); VehiclePathAI* ai = new VehiclePathAI(tank); ai->drive_to(FloatVector2d(200, 200)); ai->drive_to(FloatVector2d(500, 200)); ai->drive_to(FloatVector2d(500, 500)); ai->drive_to(FloatVector2d(1500, 500)); ai->drive_to(FloatVector2d(1500, 300)); AIManager::instance()->add(ai); } world->add(new Background (resources->get_sprite("feuerkraft/sand"), -10.0f)); world->add(soldier); player = new Player(soldier); view = new View(0, 0, CL_Display::get_width(), CL_Display::get_height(), new PlayerViewUpdater(player)); DisplayManager::init(); }
void GameSession::update() { int delta_wait = static_cast<int>(1000/args->fps); float delta = delta_wait/1000.0f;; deltas += delta; ++loops; if (CL_Keyboard::get_keycode(CL_KEY_D)) Guile::enter_repl(); unsigned int last_time = CL_System::get_time (); // Update stuff if (!do_pause) { collision_mgr->clear(); AIManager::instance()->update(delta); world->update(delta); collision_mgr->run(); view->update(delta); } GameWorld::current()->draw(*view); GameWorld::current()->draw_energie(*view); view->get_sc().render(); view->get_sc().light().fill_screen(CL_Color(50, 50, 100)); if (draw_colmap) collision_mgr->draw(*view); if (!do_pause) DisplayManager::current()->update(delta); DisplayManager::current()->draw(*(CL_Display::get_current_window()->get_gc())); if (CL_Mouse::get_keycode(CL_MOUSE_MIDDLE)) world->add(new ExplosionParticle(view->screen_to_world(FloatVector2d(CL_Mouse::get_x (), CL_Mouse::get_y ())), FloatVector2d(), 3.0f)); // Comment out for variable frame rate int sleep_time = (last_time + delta_wait) - CL_System::get_time(); if (sleep_time > 0) CL_System::sleep (sleep_time); // Flip front and backbuffer. This makes the changes visible: CL_Display::flip (); if (!args->video_record_directory.empty()) { std::stringstream filename; filename << args->video_record_directory; filename.width(8); filename.fill('0'); filename << frames; filename << ".ppm"; Screenshot::write_screenshot_pnm(filename.str()); } ++frames; // Update keyboard input and handle system events: // Exits the loop if ClanLib requests shutdown - for instance if // someone closes the window. CL_System::keep_alive(); clanlib_call_post_keep_alive_func(); InputManager::update(delta); InputEventLst lst = InputManager::get_controller().get_events(); for(InputEventLst::iterator i = lst.begin(); i != lst.end(); ++i) { if (i->type == BUTTON_EVENT) { if (i->button.name == MENU_BUTTON && i->button.is_down()) { if (control_state == MENU_CONTROL) { menu_hide(); control_state = UNIT_CONTROL; } else { menu_show(0); control_state = MENU_CONTROL; } } else if (i->button.name == USE_BUTTON && i->button.is_down()) { // FIXME: Unclean hack gh_call0(gh_lookup("join-nearest-vehicle")); } } } switch (control_state) { case MENU_CONTROL: if (DisplayManager::current()->get_menu()) DisplayManager::current()->get_menu()->process_events(InputManager::get_controller().get_events()); else { std::cout << "Error: Menu not available, fallback to unit" << std::endl; control_state = UNIT_CONTROL; } break; case UNIT_CONTROL: player->get_current_unit()->update_controlls(InputManager::get_controller()); break; default: std::cout << "Unknown ControlState, switching back to UNIT_CONTROL" << std::endl; control_state = UNIT_CONTROL; break; } InputManager::clear(); }
FloatVector2d View::world_to_screen (const FloatVector2d& pos) { return FloatVector2d (pos.x + get_x_offset (), pos.y + get_y_offset ()); }
FloatVector2d View::screen_to_world (const FloatVector2d& pos) { return FloatVector2d (pos.x - get_x_offset (), pos.y - get_y_offset ()); }
bool Level::loadObj(Path file){ if(!os().fileExists(file)){ console().write("obj file '"+file.getAbsolute()+"' not found"); #ifdef DEVELOPER #endif return false; } std::ifstream in; in.open(file.getAbsolute().c_str(),std::ios::in); std::string line; String s; ObjectAddress obj; obj.type=NULLOBJECT; Array<FloatVector3d> ivertices; Array<FloatVector3d> inor; Array<FloatVector2d> iuv; int vertexcnt=0; int lnnum=0; while(getline(in, line)){ lnnum++; s=line; if(s.substrIndex(0,2)=="g " || s.substrIndex(0,2)=="o "){ if(obj.type!=NULLOBJECT){ obj.object->setVertexCount(vertexcnt); obj.object->getVertexRaw(0).end=START_TRI; obj.object->getVertexRaw(vertexcnt-1).end=END_TRI; } vertexcnt=0; String name=s.substrIndex(2,s.size()); obj=level->add(name,"polymesh"); if(obj.type==NULLOBJECT){ console().write("error, coulden't open obj because object '"+name+"' already exists"); return false; } obj.object->material=0; obj.object->visible=true; defaultMaterial(); }else if(s.substrIndex(0,2)=="v "){ if(obj.type==NULLOBJECT){createObjDefaultObj(&obj);} float x,y,z; sscanf(s.c_str(),"v %f %f %f",&x,&y,&z); ivertices.pushBack(FloatVector3d(x,y,z)); }else if(s.substrIndex(0,3)=="vn "){ if(obj.type==NULLOBJECT){createObjDefaultObj(&obj);} float x,y,z; sscanf(s.c_str(),"vn %f %f %f",&x,&y,&z); inor.pushBack(FloatVector3d(x,y,z)); }else if(s.substrIndex(0,3)=="vt "){ if(obj.type==NULLOBJECT){createObjDefaultObj(&obj);} float x,y,z; sscanf(s.c_str(),"vt %f %f %f",&x,&y,&z); iuv.pushBack(FloatVector2d(x,y)); }else if(s.substrIndex(0,2)=="f "){ if(obj.type==NULLOBJECT){createObjDefaultObj(&obj);} String sub=s.substrIndex(2,s.size()); Array<String> fc=sub.explode(" "); if(fc.size()==3 || fc.size()==4){ int iter=1; if(fc.size()==4){iter=2;} for(int j=0; j<iter; j++){ for(int i=0; i<3; i++){ int realIndex=i; if(j==1){ if(i==1){ realIndex=2; }else if(i==2){ realIndex=3; } } Array<String> f1=fc[realIndex].explode("/"); if(f1.size()==1){ Vertex v; if(f1[0]!=""){ int ind=-1; sscanf(f1[0].c_str(),"%d",&ind); v.pos=ivertices[ind-1]; } vertexcnt++; obj.object->addVertex(v); obj.object->getVertexRaw(vertexcnt-1).end=0; }else if(f1.size()==3){ Vertex v; if(f1[0]!=""){ int ind=-1; sscanf(f1[0].c_str(),"%d",&ind); v.pos=ivertices[ind-1]; } if(f1[1]!=""){ int ind=-1; sscanf(f1[1].c_str(),"%d",&ind); v.uvLightmap=iuv[ind-1]; v.uv0=iuv[ind-1]; v.uv1=iuv[ind-1]; v.uv2=iuv[ind-1]; v.uv3=iuv[ind-1]; v.uv4=iuv[ind-1]; v.uv5=iuv[ind-1]; v.uv6=iuv[ind-1]; } if(f1[2]!=""){ int ind=-1; sscanf(f1[2].c_str(),"%d",&ind); v.normal=inor[ind-1]; } vertexcnt++; obj.object->addVertex(v); obj.object->getVertexRaw(vertexcnt-1).end=0; }else{ console().write("face dropped, incorrect index size, should only include vertex,uv, and normal indices"); } } } }else{ console().write("Error: non-triangle polygon, has "+String(fc.size())+" sides"); return false; } }else if(s.substrIndex(0,7)=="mtllib "){ }else if(s.substrIndex(0,7)=="usemtl "){ }else if(s.substrIndex(0,2)=="s "){ }else if(s.substrIndex(0,1)=="#"){ }else{ console().write("unknown .obj file content line "+String(lnnum)); return false; } } if(obj.type!=NULLOBJECT){ obj.object->setVertexCount(vertexcnt); obj.object->getVertexRaw(0).end=START_TRI; obj.object->getVertexRaw(vertexcnt-1).end=END_TRI; } in.close(); return true; }
void CollisionManager::run() { // Check for GameObj<->GameObj collisions for(Shapes::iterator i = shapes.begin(); i != shapes.end(); ++i) { for(Shapes::iterator j = i + 1; j != shapes.end(); ++j) { if (i->type == SHAPE_CIRCLE) { if (j->type == SHAPE_CIRCLE) { check_circle_circle_collision(i->circle, j->circle); } else if (j->type == SHAPE_RECT) { check_circle_rect_collision(i->circle, j->rect); } } else if (i->type == SHAPE_RECT) { if (j->type == SHAPE_CIRCLE) { check_circle_rect_collision(j->circle, i->rect); } else if (j->type == SHAPE_RECT) { check_rect_rect_collision(i->rect, j->rect); } } else { assert(false); } } } // Check for GameObj building collision for(Shapes::iterator i = shapes.begin(); i != shapes.end(); ++i) { switch (i->type) { case SHAPE_CIRCLE: { BuildingMap* building_map = GameWorld::current()->get_buildingmap(); Building* building = building_map->get_building(FloatVector2d(i->circle.x, i->circle.y)); if (!building) building = building_map->get_building(FloatVector2d(i->circle.x - i->circle.radius, i->circle.y)); if (!building) building = building_map->get_building(FloatVector2d(i->circle.x + i->circle.radius, i->circle.y)); if (!building) building = building_map->get_building(FloatVector2d(i->circle.x, i->circle.y - i->circle.radius)); if (!building) building = building_map->get_building(FloatVector2d(i->circle.x, i->circle.y + i->circle.radius)); if (building) { GameObj* obj = GameObjManager::current()->get_object_by_id(i->circle.object_id); assert(obj); obj->on_collision_with_building(building); } } break; case SHAPE_RECT: // fixme: not handled break; default: std::cout << "Unhandled type: " << i->type << std::endl; } } }