/********************************************************************* * Animates a muzzle flash billboard with firing sound and does * damage to borbie. This method is only called when the soldier * is within range and has direct line of sight. He has an 80% * chance of hitting his target. *********************************************************************/ void Soldier::fire(int distance){ lastFireTime = gameInstance->getDevice()->getTimer()->getTime(); IBillboardSceneNode * bill; bill = smgr->addBillboardSceneNode(); bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR ); bill->setMaterialTexture(0, driver->getTexture("assets/textures/muzFlash.png")); bill->setMaterialFlag(video::EMF_LIGHTING, false); bill->setMaterialFlag(video::EMF_ZBUFFER, false); float randomNum = Random::randomFloat(-10.0, 15.0); bill->setSize(core::dimension2d<f32>(30.0+randomNum, 30.0+randomNum)); bill->setID(0);//not pickable by ray caster //get enemy position, adjust muzzle flash height to barrel vector3df start = sceneNode->getPosition(); start.Y+=60; bill->setPosition(start); this->audioSystem->playSound3d(gameInstance->gunShot1, this); const int MUZZLE_FLASH_TIME = 50; ISceneNodeAnimator* anim = gameInstance->getSceneManager()->createDeleteAnimator(MUZZLE_FLASH_TIME); bill->addAnimator(anim); anim->drop(); if (!miss(distance)) gameInstance->player->applyBulletDamage(BULLET_DAMAGE); else gameInstance->player->ricochet(); }
void loop(s4 &game_state) { ICameraSceneNode* camera = irrlicht->smgr->addCameraSceneNode(); matrix4 ortho; ortho.buildProjectionMatrixOrthoLH( irrlicht->driver->getScreenSize().Width/ortho_scale, irrlicht->driver->getScreenSize().Height/ortho_scale,-1.0,1000.0); camera->setProjectionMatrix(ortho); camera->setPosition({0,0,-100}); camera->setTarget({0,0,0}); irrlicht->hud->setActiveCamera(camera); IBillboardSceneNode* qnode = irrlicht->smgr->addBillboardSceneNode(); qnode->setMaterialFlag(EMF_WIREFRAME,true); // -------------------------------------- p("---- Game loop start ----"); d32 dt = 0.0f; const d32 maxDelta = 1.0f/60.0f * 5.0f; const d32 tick_ms = 0.01666f; // TODO: change this back to 30ms? d32 render_dt = 0.0f; const d32 render_ms = RENDER_TIME_STEP; uint32 time_physics_prev = btclock->getTimeMicroseconds(); while(irrlicht->device->run() && game_state == GAME_STATE_PLAY) { const uint32 time_physics_curr = btclock->getTimeMicroseconds(); const d32 frameTime = ((d32)(time_physics_curr - time_physics_prev)) / 1000000.0; // todo: is this truncated correctly? time_physics_prev = time_physics_curr; d32 capped_dt = frameTime; if (capped_dt > maxDelta) { capped_dt = maxDelta; } render_dt += capped_dt; if ( render_dt >= render_ms ) { render_dt = 0.0f; update_player(); update_enemies(); update_missiles(ply->missiles,ply->num_missile); irrlicht->hud->getRootSceneNode()->setPosition(camera->getPosition() + vector3df(0,0,100)); irrlicht->driver->beginScene(true, true, SColor(255,59,120,140)); irrlicht->smgr->drawAll(); irrlicht->driver->clearZBuffer(); irrlicht->hud->drawAll(); irrlicht->driver->endScene(); } dt += capped_dt; while( dt >= tick_ms ) { dt -= tick_ms; receiver->input(); clear_quads(quadtree); step_player(); step_enemies(); step_missiles(ply->missiles, ply->num_missile); QuadTree::Quad* fq = get_quad_from_pos(quadtree,ply->curr_pos); qnode->setSize(dimension2d<f32>(1,1)); qnode->setPosition(fq->pos.irr()); qnode->setSize(dimension2d<f32>(fq->width,fq->width)); if (receiver->debug_key.state) { for (s4 i = 0; i < fleet->num_squad; i++) { if (fleet->squads[i].mode != scatter) fleet->squads[i].mode = scatter; else fleet->squads[i].mode = to_positions; } } if (receiver->restart.state) { game_state = GAME_STATE_RESET; return; } if (receiver->QUIT) { game_state = GAME_STATE_QUIT; return; } empty_transient_soft(memory); } alpha = dt / tick_ms; core::stringw str = L"Coquelicot // score: "; str += score; str += L" // FPS: "; str += (s32)irrlicht->driver->getFPS(); irrlicht->device->setWindowCaption(str.c_str()); } }