Open stargazing-dino opened 1 year ago
Certainly! Variable jump height is a common mechanic in platformers and provides players with more control over their character's movements. The idea is straightforward: the longer the jump button is held, the higher the character jumps, up to a maximum height. Releasing the button prematurely results in a shorter jump. This allows for precise, skill-based platforming.
Here's a basic approach to implementing variable jump height:
Jump Start:
Jump Hold:
Jump Release:
Here's a possible implementation based on the code you provided:
const MAX_JUMP_HOLD_TIME: f32 = 0.5; // Max time the jump can be held in seconds
const JUMP_START_FORCE: f32 = 20.0; // Initial jump force
const JUMP_HOLD_FORCE: f32 = 8.0; // Additional force applied while the jump button is held
pub fn variable_jump(
time: Res<Time>,
keyboard_input: Res<Input<KeyCode>>,
mut players: Query<(&mut ExternalImpulse, &ShapeHits, &GravityBound, &mut JumpState), With<Player>>,
sensors_query: Query<&Sensor>,
) {
for (mut external_impulse, shape_hits, gravity_bound, mut jump_state) in &mut players {
let gravity_force = gravity_bound.gravity_force;
// If the player is floating in space, don't apply jump
if gravity_force == Vec3::ZERO {
continue;
}
let gravity_up = -gravity_force.normalize();
if keyboard_input.just_pressed(KeyCode::Space) {
let touching_ground = shape_hits
.iter()
.any(|hit| sensors_query.get(hit.entity).is_err());
if touching_ground {
external_impulse.apply_impulse(gravity_up * JUMP_START_FORCE);
jump_state.is_jumping = true;
jump_state.hold_timer = 0.0;
}
}
// If the jump button is held and the player is still in the jump process
if keyboard_input.pressed(KeyCode::Space) && jump_state.is_jumping {
if jump_state.hold_timer < MAX_JUMP_HOLD_TIME {
external_impulse.apply_impulse(gravity_up * JUMP_HOLD_FORCE * time.delta_seconds());
jump_state.hold_timer += time.delta_seconds();
}
}
// If the jump button is released
if keyboard_input.just_released(KeyCode::Space) && jump_state.is_jumping {
jump_state.is_jumping = false;
}
}
}
// ... elsewhere in the code ...
pub struct JumpState {
is_jumping: bool,
hold_timer: f32,
}
Here's a summary:
JumpState
is a component added to the player that tracks if they are currently in a jump and how long the jump button has been held.JUMP_START_FORCE
).JUMP_HOLD_FORCE
) is applied for up to a max duration (MAX_JUMP_HOLD_TIME
).This implementation is just a starting point, and you may need to adjust values and mechanics based on how it feels in your game. Remember, game mechanics often need iterative testing and refining!
Description:
To enhance player control and gameplay dynamics, implement a variable jump height feature. The jump's height should be dependent on the duration the jump button (
KeyCode::Space
) is held. A short button press should result in a lower jump, while holding the button should allow the character to reach the maximum jump height.Acceptance Criteria:
Initial Jump Thrust: On the initial press of the jump button, the player should receive an impulse sufficient to initiate a jump.
Height Control: The player should be able to control the jump's height by holding or releasing the jump button. Holding the button will add a continuous, but diminishing force, up to a capped max height. Releasing the button will halt the additional force, allowing gravity to take over immediately.
Feedback: Consider adding a subtle animation or effect when reaching the maximum jump height to provide player feedback.
Sound: Different jump sound effects for short hops versus full jumps can enhance the player's feedback.
Air Control: Ensure that the in-air controls still feel responsive when the player is controlling jump height.
Edge Cases: Ensure the mechanic doesn't allow for 'double jumps' unless intended. If the player taps the jump button multiple times in rapid succession, it shouldn't give them extra height.
Performance: The feature should not introduce any significant performance overhead.
Implementation Details:
On the detection of a jump button press, apply an initial impulse to the player.
Continue to apply a diminishing upward force to the player for as long as the jump button is held, but only up to a maximum duration or height.
Monitor for the release of the jump button, at which point the upward force should stop being applied.
Consider using a Coroutine or Timer (depending on your game engine/framework) to manage the diminishing force over time.
Playtest extensively to find the right balance for the initial impulse, the diminishing force, and the maximum height.