1 #include "playercontroller.h"
2 #include <msp/game/root.h>
3 #include <msp/game/stage.h>
9 PlayerController::PlayerController(Game::Stage &s):
11 player_setup(stage.get_resources().get<ShipSetup>("player.ship.setup")),
12 bullet_setup(stage.get_resources().get<BulletSetup>("quaver.bullet.setup"))
14 declare_dependency<Game::Transform>(READ_OLD);
15 declare_dependency<RigidBody>(UPDATE);
18 void PlayerController::set_controls(Controls *c)
22 player_ship = Game::Owned<Ship>(stage.get_root(), player_setup);
25 void PlayerController::tick(Time::TimeDelta dt)
30 float dt_secs = dt/Time::sec;
32 const Ship::Setup &setup = player_ship->get_setup();
33 float thrust = setup.speed*setup.speed;
34 float torque = setup.turn_rate*setup.turn_rate;
36 Game::Handle<Game::Transform> transform = player_ship->get_transform();
37 LinAl::Vector<float, 2> fwd_dir = normalize(transform->get_world_matrix().column(0).slice<2>(0));
38 Game::Handle<RigidBody> body = player_ship->get_body();
40 body->add_force(fwd_dir*(controls->forward.get_value()*thrust));
41 const LinAl::Vector<float, 2> &velocity = body->get_velocity();
42 float speed = velocity.norm();
44 body->add_force(velocity*-min(speed+setup.speed/speed, 1.0f/dt_secs));
46 body->add_torque(controls->turn_left.get_value()*torque);
47 Geometry::Angle<float> angular_vel = body->get_angular_velocity();
48 Geometry::Angle<float> angular_speed = abs(angular_vel);
49 if(abs(angular_speed.radians())>1e-5)
50 body->add_torque(angular_vel.radians()*-min(angular_speed.radians()+setup.turn_rate/angular_speed.radians(), 1.0f/dt_secs));
52 if(controls->fire.was_pressed())
53 defer([this]{ fire(); });
55 controls->reset_edges();
58 void PlayerController::deferred_tick()
60 System::deferred_tick();
61 erase_if(bullets, [](Game::Handle<Bullet> b){ return !b->get_hitpoints()->is_alive(); });
64 void PlayerController::fire()
66 Game::Handle<Game::Transform> player_tf = player_ship->get_transform();
67 Game::Handle<RigidBody> player_body = player_ship->get_body();
69 Game::TransformValues tv;
70 tv.position = (player_tf->get_world_matrix()*LinAl::Vector<float, 4>(2.0f, 0.0f, 0.0f, 1.0f)).slice<3>(0);
71 tv.rotation = player_tf->get_rotation()*Geometry::Quaternion<float>::rotation(Geometry::Angle<float>::from_degrees(10), LinAl::Vector<float, 3>(0.0f, 0.0f, 1.0f));
72 bullets.emplace_back(stage.get_root(), bullet_setup, tv);
73 Game::Handle<Bullet> bullet = bullets.back();
74 Game::Handle<RigidBody> bullet_body = bullet->get_body();
75 bullet_body->set_velocity(player_body->get_velocity()+(player_tf->get_world_matrix()*LinAl::Vector<float, 4>(20.0f, 0.0f, 0.0f, 0.0f)).slice<2>(0));