summaryrefslogtreecommitdiff
path: root/src/content
diff options
context:
space:
mode:
Diffstat (limited to 'src/content')
-rw-r--r--src/content/entities/entity_wizard.rs158
-rw-r--r--src/content/entities/mod.rs1
2 files changed, 159 insertions, 0 deletions
diff --git a/src/content/entities/entity_wizard.rs b/src/content/entities/entity_wizard.rs
new file mode 100644
index 0000000..eea2a48
--- /dev/null
+++ b/src/content/entities/entity_wizard.rs
@@ -0,0 +1,158 @@
+use glam::Vec2;
+use rapier2d::{
+ control::{CharacterAutostep, CharacterLength, KinematicCharacterController},
+ pipeline::QueryFilter,
+};
+
+use crate::{
+ config::GRAVITY,
+ input::Input,
+ sim::{
+ entity::{EntityBehaviour, EntityDef, EntityUpdateCtx},
+ sim_manager::SimCtx,
+ },
+};
+
+struct WizardEntityBehaviour {
+ movement_input_x: f32,
+ jump: f32,
+
+ grounded: bool,
+ acc_vel: Vec2,
+ kinematic_controller: KinematicCharacterController,
+}
+
+const JUMP_VELOCITY: f32 = 100.0;
+const ACCEL: f32 = 1000.0;
+const AIR_ACCEL: f32 = 350.0;
+const MAX_SPEED: f32 = 75.0;
+
+impl EntityBehaviour for WizardEntityBehaviour {
+ fn update(&mut self, _: &mut EntityUpdateCtx, ctx: &mut SimCtx, _: f32) {
+ if ctx.input_manager.held(Input::Left) {
+ self.movement_input_x = -1.0;
+ } else if ctx.input_manager.held(Input::Right) {
+ self.movement_input_x = 1.0;
+ } else {
+ self.movement_input_x = 0.0;
+ }
+
+ if ctx.input_manager.pressed(Input::Up) {
+ self.jump = 0.06;
+ }
+ }
+
+ fn physics_update(
+ &mut self,
+ update_ctx: &mut EntityUpdateCtx,
+ ctx: &mut SimCtx,
+ delta_time: f32,
+ ) {
+ if self.grounded {
+ // TODO delta_time
+ if self.movement_input_x.abs() < 0.2 {
+ self.acc_vel.x = self.acc_vel.x * 0.7;
+ }
+ // if we're moving up, keep moving up
+ self.acc_vel.y = self.acc_vel.y.min(0.0);
+ if self.jump > 0.0 {
+ self.acc_vel.y -= JUMP_VELOCITY;
+ self.jump = 0.0;
+ }
+ } else {
+ self.acc_vel.x = self.acc_vel.x * 0.95;
+ self.acc_vel.y += GRAVITY * delta_time;
+
+ if self.jump > 0.0 {
+ self.jump -= delta_time;
+ }
+ }
+
+ if self.acc_vel.x.abs() < 1.0 {
+ self.acc_vel.x = 0.0;
+ }
+
+ let flip_adj = if self.acc_vel.x.signum() != self.movement_input_x.signum() {
+ 3.0
+ } else {
+ 1.0
+ };
+ self.acc_vel.x += self.movement_input_x
+ * if self.grounded { ACCEL } else { AIR_ACCEL }
+ * delta_time
+ * flip_adj;
+ self.acc_vel.x = self.acc_vel.x.clamp(-MAX_SPEED, MAX_SPEED);
+
+ let query_pipeline = ctx
+ .rb_manager
+ .physics_manager
+ .world
+ .query_pipeline_with_filter(
+ QueryFilter::default().exclude_rigid_body(update_ctx.entity_data.rb_h.unwrap()),
+ );
+
+ let rb = ctx
+ .rb_manager
+ .physics_manager
+ .world
+ .bodies
+ .get(update_ctx.entity_data.rb_h.unwrap())
+ .unwrap();
+
+ let collider = ctx
+ .rb_manager
+ .physics_manager
+ .world
+ .colliders
+ .get(update_ctx.entity_data.collider_h.unwrap())
+ .unwrap();
+
+ // move_shape works in translations, not velocities: feed it the distance we
+ // want to cover this step, and convert the allowed distance back to a velocity.
+ let movement = self.kinematic_controller.move_shape(
+ delta_time,
+ &query_pipeline,
+ collider.shape(),
+ rb.position(),
+ self.acc_vel * delta_time,
+ |_| {},
+ );
+
+ let rb = ctx
+ .rb_manager
+ .physics_manager
+ .world
+ .bodies
+ .get_mut(update_ctx.entity_data.rb_h.unwrap())
+ .unwrap();
+
+ rb.set_linvel(movement.translation / delta_time, true);
+
+ self.grounded = movement.grounded;
+ }
+}
+
+pub fn entity_wizard_def(position: Vec2) -> EntityDef {
+ let mut kinematic_controller = KinematicCharacterController::default();
+ kinematic_controller.up = -Vec2::Y;
+ kinematic_controller.autostep = Some(CharacterAutostep {
+ max_height: CharacterLength::Absolute(4.0),
+ min_width: CharacterLength::Absolute(8.0),
+ include_dynamic_bodies: false,
+ });
+ kinematic_controller.offset = CharacterLength::Absolute(0.1);
+ kinematic_controller.normal_nudge_factor = 1.0e-3;
+ kinematic_controller.max_slope_climb_angle = 45f32.to_radians();
+
+ EntityDef::kinematic_from_sprite(
+ position,
+ "assets/sprites/wizard",
+ Some(Box::new(WizardEntityBehaviour {
+ movement_input_x: 0.0,
+ jump: 0.0,
+ grounded: false,
+ acc_vel: Vec2::ZERO,
+ kinematic_controller,
+ })),
+ )
+}
diff --git a/src/content/entities/mod.rs b/src/content/entities/mod.rs
index 0ec45ce..11c1706 100644
--- a/src/content/entities/mod.rs
+++ b/src/content/entities/mod.rs
@@ -2,3 +2,4 @@ pub mod entity_bullet_emitter;
pub mod entity_cube;
pub mod entity_grenade;
pub mod entity_tnt;
+pub mod entity_wizard;