SHARE
TWEET

Spaceship Class

kurozael Feb 15th, 2012 204 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.         Written by kurozael (kurozael@gmail.com), do with it
  3.         as you please :)
  4. */
  5.  
  6. #include <Engine/States/PlayState.h>
  7. #include <Engine/Entities/Spaceship.h>
  8. #include <Engine/System/Timer.h>
  9. #include <Engine/System/Entities.h>
  10. #include <Engine/System/Events.h>
  11. #include <Engine/System/Asset.h>
  12. #include <Engine/System/Utility.h>
  13. #include <Engine/Graphics/Render.h>
  14. #include <Engine/Game.h>
  15.  
  16. namespace en
  17. {
  18.         float Spaceship::EnterAtmosphere(Planet* planet)
  19.         {
  20.                 Vector3f& planetPos = planet->GetPos();
  21.                 float distance = planetPos.Distance(m_position);
  22.                 float pullSize = planet->GetSize() + (1.0f + planet->GetGravPull());
  23.  
  24.                 if (distance <= pullSize * 2.0f)
  25.                 {
  26.                         if (m_atmosphere == NULL || (distance < planetPos.Distance(m_atmosphere->GetPos())))
  27.                                 m_atmosphere = planet;
  28.                 }
  29.  
  30.                 return distance;
  31.         }
  32.  
  33.         void Spaceship::SetDashTime(float dashTime)
  34.         {
  35.                 m_dashTime = Timer::CurTime() + dashTime;
  36.         }
  37.  
  38.         void Spaceship::SetMessage(const std::string& message)
  39.         {
  40.                 m_fadeMessageTime = Timer::CurTime() + 3.0f;
  41.                 m_message = message;
  42.         }
  43.  
  44.         void Spaceship::OnCollide(Planet* planet)
  45.         {
  46.                 if (m_fuel < 20.0f)
  47.                         g_Awards->Earn("Close One");
  48.  
  49.                 SetPlanet(planet);
  50.                 SetVelocity(Vector3f(0, 0, 0));
  51.  
  52.                 g_PlayState->AddScore(
  53.                         std::ceil((4.0f - planet->GetSize()) * 100.0f));
  54.  
  55.                 m_landCount++;
  56.  
  57.                 if (m_landCount == 1)
  58.                 {
  59.                         g_PlayState->SetNewPlanet();
  60.                         m_landCount = 0;
  61.                 }
  62.         }
  63.  
  64.         void Spaceship::CheckSkip(Planet* planet)
  65.         {
  66.                 Entity* nextPlanet = (Planet*)g_Entities->GetNext(m_planet, "Planet");
  67.                 float skipBonus = g_Config->GetFloat("SkipPlanetBonus", 300.0f);
  68.  
  69.                 if (nextPlanet != NULL && planet != nextPlanet)
  70.                 {
  71.                         g_PlayState->AddScore(skipBonus, true);
  72.                         g_Awards->Earn("Skip Planet");
  73.                         SetMessage("Skip! +" + Math::ToString(skipBonus));
  74.                 }
  75.         }
  76.  
  77.         void Spaceship::SetPlanet(Planet* planet)
  78.         {
  79.                 if (m_fuel < 1.0f)
  80.                         return;
  81.  
  82.                 Vector3f& position = planet->GetPos();
  83.                 Vector3f direction = position - m_position;
  84.                 float angle = std::atan2(direction.z, -direction.x);
  85.  
  86.                 // Only play the impact sound if we hopped onto it! Durr.
  87.                 if (m_planet != NULL && m_planet != planet)
  88.                 {
  89.                         g_Audio->PlaySound("impact.wav");
  90.                         CheckSkip(planet);
  91.                 }
  92.  
  93.                 m_gravity.Reset();
  94.                 m_gasSound->Stop();
  95.                 m_orbit = angle;
  96.                 m_planet = planet;
  97.                 m_fuel = 100.0f;
  98.         }
  99.  
  100.         Planet* Spaceship::GetPlanet()
  101.         {
  102.                 return m_planet;
  103.         }
  104.  
  105.         void Spaceship::OnEvent(sf::Event& event)
  106.         {
  107.                 if (event.Type == sf::Event::KeyReleased && event.Key.Code == sf::Keyboard::Space
  108.                         && !IsMoving() && !m_exploded)
  109.                         Jump();
  110.         }
  111.  
  112.         void Spaceship::OnUpdate()
  113.         {
  114.                 if (m_planet != NULL && !IsMoving() && !m_exploded)
  115.                 {
  116.                         Vector3f& position = m_planet->GetPos();
  117.                         Vector3f direction = position - m_position;
  118.                         float orbitSpeed = m_planet->GetSpinSpeed() * 0.04;
  119.                         float angle = std::atan2(direction.z, -direction.x);
  120.                         float size = m_planet->GetSize() + 1.0f;
  121.                         angle = (angle * 180.f) / M_PI;
  122.  
  123.                         m_position.x = position.x + std::cos(m_orbit) * size;
  124.                         m_position.z = position.z - std::sin(m_orbit) * size;
  125.                         m_position.y = 0.2f;
  126.                         m_angle.y = angle;
  127.  
  128.                         bool bIsClockwise = m_planet->IsClockwise();
  129.  
  130.                         if (sf::Keyboard::IsKeyPressed(sf::Keyboard::LShift)
  131.                                 || sf::Keyboard::IsKeyPressed(sf::Keyboard::RShift))
  132.                         {
  133.                                 bIsClockwise = !bIsClockwise;
  134.                                 orbitSpeed *= 0.5f;
  135.                         }
  136.                        
  137.                         if (bIsClockwise)
  138.                                 m_orbit -= (Timer::GetDT() * orbitSpeed);
  139.                         else
  140.                                 m_orbit += (Timer::GetDT() * orbitSpeed);
  141.                 }
  142.                 else if (!m_exploded)
  143.                 {
  144.                         // Are we currently within a planet's atmosphere?
  145.                         if (m_atmosphere != NULL)
  146.                         {
  147.                                 Vector3f planetPos = m_atmosphere->GetPos();
  148.                                 Vector3f direction = planetPos - m_position;
  149.                                 float distance = planetPos.Distance(m_position);
  150.                                 float pullSize = m_atmosphere->GetSize() + (1.0f + m_atmosphere->GetGravPull());
  151.  
  152.                                 float angle = std::atan2(direction.z, -direction.x);
  153.                                 angle = angle * (180.f / M_PI);
  154.  
  155.                                 if (distance <= pullSize)
  156.                                         m_gravity = direction * 0.6f;
  157.                                 else
  158.                                         m_gravity = direction * 0.2f;
  159.                        
  160.                                 m_angle.y = Math::DegApproach(
  161.                                         m_angle.y, angle, Timer::GetDT() * 360.0f
  162.                                 );
  163.  
  164.                                 m_atmosphere = NULL;
  165.                         };
  166.  
  167.                         /*
  168.                                 Here we give the ability for the player to do a short 'halt'
  169.                                 in space. This is useful to dodge asteroids, but limits their
  170.                                 speed and still reduces their fuel!
  171.                         */
  172.  
  173.                         if (sf::Keyboard::IsKeyPressed(sf::Keyboard::LShift)
  174.                                 || sf::Keyboard::IsKeyPressed(sf::Keyboard::RShift))
  175.                         {
  176.                                 SetVelocity(m_velocity.NormalCopy() * 4.0f);
  177.                         }
  178.                         else
  179.                         {
  180.                                 SetVelocity(m_velocity.NormalCopy() * GetSpeed());
  181.                         }
  182.  
  183.                         /*
  184.                                 Change the volume based on our fuel,
  185.                                 but not too frequently because SFML doesn't
  186.                                 like it! Silly SFML!
  187.                         */
  188.                         if (Timer::CurTime() >= m_nextVolumeTime)
  189.                         {
  190.                                 m_nextVolumeTime = Timer::CurTime() + 0.5f;
  191.                                 m_gasSound->SetVolume(
  192.                                         Math::Clamp(m_fuel, 0.0f, 100.0f)
  193.                                 );
  194.                         }
  195.  
  196.                         m_position = m_position + (m_gravity * Timer::GetDT());
  197.                         m_gravity *= 0.6f;
  198.  
  199.                         float fuelLossAmount = g_Config->GetFloat("FuelLossAmount") * Timer::GetDT();
  200.                         PropPhysics::OnUpdate();
  201.  
  202.                         if (m_position.z > 30.0f || m_position.z < -30.0f)
  203.                                 Kill();
  204.  
  205.                         if (m_fuel > 0.0f)
  206.                                 m_fuel = std::max<float>(m_fuel - fuelLossAmount, 0);
  207.                         else
  208.                                 Kill();
  209.  
  210.                         FireTrail();
  211.                 }
  212.  
  213.                 if (m_nextRespawn > 0.0f && Timer::CurTime() >= m_nextRespawn)
  214.                         Respawn();
  215.  
  216.                 m_emitter->Update();
  217.         }
  218.  
  219.         float Spaceship::GetSpeed()
  220.         {
  221.                 if (m_dashTime > 0.0f && Timer::CurTime() < m_dashTime)
  222.                         return 12.0f;
  223.                 else
  224.                         return 9.0f;
  225.         }
  226.  
  227.         void Spaceship::Kill()
  228.         {
  229.                 if (!m_exploded)
  230.                         Explode();
  231.         }
  232.  
  233.         void Spaceship::Respawn()
  234.         {
  235.                 g_PlayState->GetCamera()->SetTarget(
  236.                         m_planet->GetPos(), true
  237.                 );
  238.  
  239.                 Vector3f& sunPos = g_PlayState->GetTheSun()->GetPos();
  240.                 sunPos.x = m_planet->GetPos().x - 28.0f;
  241.  
  242.                 g_Audio->PlaySound("impact.wav");
  243.                 m_nextRespawn = 0.0f;
  244.                 m_gasSound->Stop();
  245.                 m_velocity.Reset();
  246.                 m_exploded = false;
  247.                 m_fuel = 100.0f;
  248.                 m_lives--;
  249.  
  250.                 if (m_lives == 0)
  251.                         g_PlayState->Lose();
  252.  
  253.                 g_Game->DoFlash(0.2f, "hazard.wav");
  254.         }
  255.  
  256.         void Spaceship::Explode()
  257.         {
  258.  
  259.                 m_emitter->ExplodeFX(m_position, 18, 60);
  260.                 m_emitter->ShockwaveFX(m_position, 10, 60);
  261.  
  262.                 /*
  263.                         Ground control to major Tom, your circuits dead, there's something wrong
  264.                         Can you hear me, major Tom?
  265.                         Can you hear me, major Tom?
  266.                         Can you hear me, major Tom?
  267.                         Can you...
  268.                         Uh... Houston, we have a problem...
  269.                 */
  270.                 m_nextRespawn = Timer::CurTime() + 1.0f;
  271.                 m_gasSound->Stop();
  272.                 m_exploded = true;
  273.  
  274.                 // Lose points for the failure!
  275.                 float loseLifePenalty = g_Config->GetInt("LoseLifePenalty", 100);
  276.                         SetMessage("Boom! -" + Math::ToString(loseLifePenalty));
  277.                 g_PlayState->TakeScore(loseLifePenalty);
  278.  
  279.                 // BOOOOOOOOOOOOOOOOOOOOOOOOOOOM!
  280.                 m_explosion->Play();
  281.         }
  282.  
  283.         void Spaceship::FireTrail()
  284.         {
  285.                 Vector3f shipDir = m_angle.Direction();
  286.                 float velLength = m_velocity.Length();
  287.                 int particles = velLength * 0.3f;
  288.  
  289.                 // Don't bother if we aren't moving much!
  290.                 if (velLength <= 1.5f) return;
  291.  
  292.                 for (int i = 0; i < particles; i++)
  293.                 {
  294.                         std::string texture = "textures/particles/dust1.png";
  295.                         Vector3f velocity = shipDir * -velLength;
  296.                         float startSize = Math::Random(0.4f, 1.2f);
  297.                         float endSize = Math::Random(0.0f, 0.4f);
  298.                         float randAlpha = Math::Random(0.4f, 1.0f);
  299.                         float randGrey = Math::Random(0.2f, 0.8f);
  300.                         float dieTime = Math::Random(0.8, 1.6f);
  301.                         Color color = Color(randGrey, randGrey, randGrey, randAlpha);
  302.  
  303.                         if (i >= particles * 0.5f)
  304.                         {
  305.                                 texture = "textures/particles/dust2.png";
  306.                                 startSize = Math::Random(0.8f, 1.8f);
  307.                                 endSize = Math::Random(0.3f, 0.6f);
  308.                                 dieTime = Math::Random(0.4f, 1.2f);
  309.                                 color = Color(Math::Random(0.2f, 1.0f), Math::Random(0.0f, 0.2f), 0.0f, randAlpha);
  310.                         }
  311.  
  312.                         pParticle particle = m_emitter->New();
  313.                                 particle->SetPos(m_position - (shipDir * 0.9f));
  314.                                 particle->SetColor(color);
  315.                                 particle->SetDieTime(dieTime);
  316.                                 particle->SetStartSize(startSize);
  317.                                 particle->SetTexture(texture);
  318.                                 particle->SetEndSize(endSize);
  319.                                 particle->SetVelocity(velocity);
  320.                                 particle->SetAirResistance(0.1f);
  321.                         m_emitter->Add(particle);
  322.                 }
  323.         }
  324.  
  325.         bool Spaceship::IsMoving()
  326.         {
  327.                 return m_velocity.SquaredLength() > 0.0f;
  328.         }
  329.  
  330.         int Spaceship::GetLives()
  331.         {
  332.                 return m_lives;
  333.         }
  334.        
  335.         void Spaceship::OnDraw()
  336.         {
  337.                 // See if we're not respawning!
  338.                 if (m_nextRespawn == 0.0f)
  339.                 {
  340.                         Color& color = m_planet->GetColor();
  341.  
  342.                         m_color.r = Math::Approach(m_color.r, color.r + 0.25f, Timer::GetDT() * 0.1f);
  343.                         m_color.g = Math::Approach(m_color.g, color.g + 0.25f, Timer::GetDT() * 0.1f);
  344.                         m_color.b = Math::Approach(m_color.b, color.b + 0.25f, Timer::GetDT() * 0.1f);
  345.  
  346.                         glPushMatrix();
  347.                                 glTranslatef(m_position.x, m_position.y, m_position.z);
  348.                                 glColor4f(m_color.r, m_color.g, m_color.b, 0.4f);
  349.                                 m_billboard.Draw(Vector3f(0.0f, 0.0f, 0.0f), 10.0f);
  350.                                 m_angle.Set();
  351.                                 glColor4f(1, 1, 1, 1);
  352.                                 glRotatef(180, 0, 1, 0);
  353.                                 glScalef(0.07, 0.07, 0.07);
  354.                                 m_model->Draw();
  355.                         glPopMatrix();
  356.                 }
  357.  
  358.                 Pointf screenPos = Render::ToScreen(m_position);
  359.  
  360.                 if (m_fadeMessageTime != 0.0f)
  361.                 {
  362.                         float timeLeft = Math::Clamp(m_fadeMessageTime - Timer::CurTime(), 0.0f, 3.0f);
  363.                         Color color = Color(1.0f, 1.0f, 1.0f, (1.0f / 3.0f) * timeLeft);
  364.  
  365.                         Render::Start2D();
  366.                                 Render::Text::SetFont(g_Config->GetString("GameFont"));
  367.                                 Render::Text::SetHeight(20.0f);
  368.                                 Render::Text::Draw2D(
  369.                                         screenPos.x, screenPos.y + 32.0f + (48.0f - ((48.0f / 3.0f) * timeLeft)), m_message, color, true
  370.                                         );
  371.                         Render::End2D();
  372.  
  373.                         if (timeLeft == 0.0f)
  374.                         {
  375.                                 m_fadeMessageTime = 0.0f;
  376.                                 m_message.clear();
  377.                         }
  378.                 }
  379.  
  380.                 if (m_nextRespawn == 0.0f)
  381.                 {
  382.                         // Don't display the fuel bar if we're orbiting!
  383.                         if (!IsMoving())
  384.                                 return;
  385.  
  386.                         // Position the fuel bar above the spaceship.
  387.                         screenPos.y -= 64.0f;
  388.  
  389.                         Render::Start2D();
  390.                                 Render::Screen::Quad(screenPos.x, screenPos.y, 64, 6, Color(1, 0.2, 0.2, 1));
  391.                                 Render::Screen::Quad(screenPos.x, screenPos.y, (64.0f / 100.0f) * m_fuel, 6, Color(0, 1, 0, 1));
  392.                                
  393.                                 Render::Text::SetFont(g_Config->GetString("GameFont"));
  394.                                 Render::Text::SetHeight(20.0f);
  395.                                 Render::Text::Draw2D(screenPos.x, screenPos.y + 8, "FUEL: " + Math::ToString(std::ceil(m_fuel)));
  396.                         Render::End2D();
  397.                 }
  398.  
  399.                 m_emitter->Draw();
  400.         }
  401.  
  402.         float Spaceship::GetFuel()
  403.         {
  404.                 return m_fuel;
  405.         }
  406.  
  407.         void Spaceship::Remove()
  408.         {
  409.                 g_Entities->Remove(this);
  410.         }
  411.  
  412.         void Spaceship::Jump()
  413.         {
  414.                 if (m_angle.y <= 90 && m_angle.y >= -90)
  415.                 {
  416.                         if (Math::Random(0.0f, 1.0f) < 0.1f)
  417.                                 g_PlayState->MakeAsteroid();
  418.  
  419.                         SetVelocity(m_angle.Direction() * GetSpeed());
  420.                         m_gasSound->Play();
  421.                         m_planet->Impact();
  422.                 }
  423.         }
  424.  
  425.         Spaceship::Spaceship()
  426.         {
  427.                 m_billboard.SetTexture("textures/particle.png");
  428.                 m_billboard.DisableLighting();
  429.                 m_emitter.reset(new Emitter);
  430.                 m_emitter->Clear();
  431.  
  432.                 g_Entities->Add(this);
  433.                 g_Events->Add(this);
  434.                
  435.                 m_explosion = g_Audio->GetSound("explosion.ogg");
  436.                 m_gasSound = g_Audio->GetSound("cannister_loop.wav");
  437.                 m_gasSound->SetLoop(true);
  438.                 g_Audio->LoadSound("impact.wav");
  439.  
  440.                 m_nextVolumeTime = 0.0f;
  441.                 m_nextRespawn = 0.0f;
  442.                 m_exploded = false;
  443.                 m_atmosphere = NULL;
  444.                 m_landCount = 0;
  445.                 m_dashTime = 0.0f;
  446.                 m_planet = NULL;
  447.                 m_lives = g_Config->GetInt("StartLives", 2);
  448.                 m_model = new StaticModel;
  449.                 m_model->Load("meshes/SpaceFrigate/SpaceFrigate.3ds");
  450.                 m_fuel = 100.0f;
  451.         }
  452.  
  453.         Spaceship::~Spaceship()
  454.         {
  455.                 g_Events->Remove(this);
  456.                 delete m_model;
  457.         }
  458. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top