implement jump() + remove jump_trying + prevent air jumping

This commit is contained in:
Quaternions 2023-09-19 21:29:39 -07:00
parent 6ed71073f6
commit 9025bea5ef
2 changed files with 58 additions and 23 deletions

View File

@ -5,7 +5,6 @@ pub enum PhysicsInstruction {
CollisionStart(RelativeCollision), CollisionStart(RelativeCollision),
CollisionEnd(RelativeCollision), CollisionEnd(RelativeCollision),
StrafeTick, StrafeTick,
Jump,
ReachWalkTargetVelocity, ReachWalkTargetVelocity,
// Water, // Water,
// Spawn( // Spawn(
@ -271,7 +270,6 @@ pub struct PhysicsState {
pub walk_accel: f32, pub walk_accel: f32,
pub gravity: glam::Vec3, pub gravity: glam::Vec3,
pub grounded: bool, pub grounded: bool,
pub jump_trying: bool,
} }
#[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)] #[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)]
@ -483,6 +481,16 @@ impl PhysicsState {
self.time=time; self.time=time;
} }
fn set_control(&mut self,control:u32,state:bool){
self.controls=if state{self.controls|control}else{self.controls&!control};
}
fn jump(&mut self){
self.grounded=false;//do I need this?
let mut v=self.body.velocity+glam::Vec3::new(0.0,0.715588/2.0*100.0,0.0);
self.contact_constrain_velocity(&mut v);
self.body.velocity=v;
}
fn contact_constrain_velocity(&self,velocity:&mut glam::Vec3){ fn contact_constrain_velocity(&self,velocity:&mut glam::Vec3){
for contact in self.contacts.iter() { for contact in self.contacts.iter() {
let n=contact.normal(&self.models); let n=contact.normal(&self.models);
@ -897,8 +905,7 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
|PhysicsInstruction::ReachWalkTargetVelocity |PhysicsInstruction::ReachWalkTargetVelocity
|PhysicsInstruction::CollisionStart(_) |PhysicsInstruction::CollisionStart(_)
|PhysicsInstruction::CollisionEnd(_) |PhysicsInstruction::CollisionEnd(_)
|PhysicsInstruction::StrafeTick |PhysicsInstruction::StrafeTick => self.advance_time(ins.time),
|PhysicsInstruction::Jump => self.advance_time(ins.time),
} }
match ins.instruction { match ins.instruction {
PhysicsInstruction::CollisionStart(c) => { PhysicsInstruction::CollisionStart(c) => {
@ -915,6 +922,9 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
let mut v=self.body.velocity; let mut v=self.body.velocity;
self.contact_constrain_velocity(&mut v); self.contact_constrain_velocity(&mut v);
self.body.velocity=v; self.body.velocity=v;
if self.grounded&&self.controls&CONTROL_JUMP!=0{
self.jump();
}
self.refresh_walk_target(); self.refresh_walk_target();
}, },
PhysicsInstruction::CollisionEnd(c) => { PhysicsInstruction::CollisionEnd(c) => {
@ -941,13 +951,6 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
self.body.velocity=v; self.body.velocity=v;
} }
} }
PhysicsInstruction::Jump => {
self.grounded=false;//do I need this?
let mut v=self.body.velocity+glam::Vec3::new(0.0,0.715588/2.0*100.0,0.0);
self.contact_constrain_velocity(&mut v);
self.body.velocity=v;
self.refresh_walk_target();
},
PhysicsInstruction::ReachWalkTargetVelocity => { PhysicsInstruction::ReachWalkTargetVelocity => {
//precisely set velocity //precisely set velocity
let mut a=glam::Vec3::ZERO; let mut a=glam::Vec3::ZERO;
@ -959,24 +962,57 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
self.walk.state=WalkEnum::Reached; self.walk.state=WalkEnum::Reached;
}, },
PhysicsInstruction::Input(input_instruction) => { PhysicsInstruction::Input(input_instruction) => {
let mut refresh_walk_target=false;
match input_instruction{ match input_instruction{
InputInstruction::MoveMouse(m) => self.mouse_interpolation.move_mouse(self.time,m), InputInstruction::MoveMouse(m) => {
InputInstruction::MoveForward(s) => self.controls=if s{self.controls|CONTROL_MOVEFORWARD}else{self.controls&!CONTROL_MOVEFORWARD}, self.camera.angles=self.camera.simulate_move_angles(self.mouse_interpolation.mouse1-self.mouse_interpolation.mouse0);
InputInstruction::MoveLeft(s) => self.controls=if s{self.controls|CONTROL_MOVELEFT}else{self.controls&!CONTROL_MOVELEFT}, self.mouse_interpolation.move_mouse(self.time,m);
InputInstruction::MoveBack(s) => self.controls=if s{self.controls|CONTROL_MOVEBACK}else{self.controls&!CONTROL_MOVEBACK}, refresh_walk_target=true;
InputInstruction::MoveRight(s) => self.controls=if s{self.controls|CONTROL_MOVERIGHT}else{self.controls&!CONTROL_MOVERIGHT}, },
InputInstruction::MoveUp(s) => self.controls=if s{self.controls|CONTROL_MOVEUP}else{self.controls&!CONTROL_MOVEUP}, InputInstruction::MoveForward(s) => {
InputInstruction::MoveDown(s) => self.controls=if s{self.controls|CONTROL_MOVEDOWN}else{self.controls&!CONTROL_MOVEDOWN}, self.set_control(CONTROL_MOVEFORWARD,s);
InputInstruction::Jump(s) => self.controls=if s{self.controls|CONTROL_JUMP}else{self.controls&!CONTROL_JUMP}, refresh_walk_target=true;
InputInstruction::Zoom(s) => self.controls=if s{self.controls|CONTROL_ZOOM}else{self.controls&!CONTROL_ZOOM}, },
InputInstruction::MoveLeft(s) => {
self.set_control(CONTROL_MOVELEFT,s);
refresh_walk_target=true;
},
InputInstruction::MoveBack(s) => {
self.set_control(CONTROL_MOVEBACK,s);
refresh_walk_target=true;
},
InputInstruction::MoveRight(s) => {
self.set_control(CONTROL_MOVERIGHT,s);
refresh_walk_target=true;
},
InputInstruction::MoveUp(s) => {
self.set_control(CONTROL_MOVEUP,s);
refresh_walk_target=true;
},
InputInstruction::MoveDown(s) => {
self.set_control(CONTROL_MOVEDOWN,s);
refresh_walk_target=true;
},
InputInstruction::Jump(s) => {
self.set_control(CONTROL_JUMP,s);
refresh_walk_target=true;
if self.grounded{
self.jump();
}
},
InputInstruction::Zoom(s) => {
self.set_control(CONTROL_ZOOM,s);
},
InputInstruction::Reset => println!("reset"), InputInstruction::Reset => println!("reset"),
} }
//calculate control dir //calculate control dir
let camera_mat=self.camera.simulate_move_rotation_y(self.mouse_interpolation.interpolated_position(self.time).x-self.mouse_interpolation.mouse0.x); let camera_mat=self.camera.simulate_move_rotation_y(self.mouse_interpolation.interpolated_position(self.time).x-self.mouse_interpolation.mouse0.x);
let control_dir=camera_mat*get_control_dir(self.controls); let control_dir=camera_mat*get_control_dir(self.controls);
//calculate walk target velocity //calculate walk target velocity
if refresh_walk_target{
self.walk.target_velocity=self.walkspeed*control_dir; self.walk.target_velocity=self.walkspeed*control_dir;
self.refresh_walk_target(); self.refresh_walk_target();
}
}, },
} }
} }

View File

@ -512,7 +512,6 @@ impl strafe_client::framework::Example for GraphicsData {
walk_accel: 90.0, walk_accel: 90.0,
mv: 2.7, mv: 2.7,
grounded: false, grounded: false,
jump_trying: false,
walkspeed: 18.0, walkspeed: 18.0,
contacts: std::collections::HashSet::new(), contacts: std::collections::HashSet::new(),
models: Vec::new(), models: Vec::new(),