]> git.tdb.fi Git - libs/game.git/blobdiff - examples/bassteroids/source/playercontroller.cpp
Add a controllable player ship to Bassteroids
[libs/game.git] / examples / bassteroids / source / playercontroller.cpp
diff --git a/examples/bassteroids/source/playercontroller.cpp b/examples/bassteroids/source/playercontroller.cpp
new file mode 100644 (file)
index 0000000..939d838
--- /dev/null
@@ -0,0 +1,47 @@
+#include "playercontroller.h"
+#include <msp/game/root.h>
+#include <msp/game/stage.h>
+#include "controls.h"
+
+using namespace std;
+using namespace Msp;
+
+PlayerController::PlayerController(Game::Stage &s):
+       System(s),
+       player_setup{ .physical={ .body={ .mass=1 }, .collider={ .type=ColliderType::CIRCLE, .radius=0.8f }},
+               .mesh={ .object_name="Bass guitar.object" },
+               .speed=12.0f, .turn_rate=4.71f }
+{ }
+
+void PlayerController::set_controls(Controls *c)
+{
+       controls = c;
+       if(!player_ship)
+               player_ship = Game::Owned<Ship>(stage.get_root(), player_setup);
+}
+
+void PlayerController::tick(Time::TimeDelta dt)
+{
+       if(!controls)
+               return;
+
+       float dt_secs = dt/Time::sec;
+
+       const Ship::Setup &setup = player_ship->get_setup();
+       float thrust = setup.speed*setup.speed;
+       float torque = setup.turn_rate*setup.turn_rate;
+
+       Game::Handle<Game::Transform> transform = player_ship->get_transform();
+       LinAl::Vector<float, 2> fwd_dir = normalize(transform->get_world_matrix().column(0).slice<2>(0));
+       Game::Handle<RigidBody> body = player_ship->get_body();
+
+       body->add_force(fwd_dir*(controls->forward.get_value()*thrust));
+       const LinAl::Vector<float, 2> &velocity = body->get_velocity();
+       float speed = velocity.norm();
+       body->add_force(velocity*-min(speed+setup.speed/speed, 1.0f/dt_secs));
+
+       body->add_torque(controls->turn_left.get_value()*torque);
+       Geometry::Angle<float> angular_vel = body->get_angular_velocity();
+       Geometry::Angle<float> angular_speed = abs(angular_vel);
+       body->add_torque(angular_vel.radians()*-min(angular_speed.radians()+setup.turn_rate/angular_speed.radians(), 1.0f/dt_secs));
+}