hold right+left, it charges ahead

This commit is contained in:
2026-05-25 20:38:38 +03:00
parent 950d93ed0e
commit b30fb6e0a6
3 changed files with 47 additions and 12 deletions
+5 -1
View File
@@ -12,6 +12,9 @@ var _tilt_x: float = 0.0
var _tilt_z: float = 0.0
var _aerial_pitch: float = 0.0
var charge_pitch_target: float = 0.0
var _charge_pitch_curr: float = 0.0
# Tail — Verlet chain simulation
const TAIL_BONES: Array = [
&"tail_1", &"tail_2", &"tail_3", &"tail_4",
@@ -111,7 +114,8 @@ func _wobble_body(delta: float) -> void:
target_pitch = clampf(-atan2(vel.y, flat_spd) * DP.f("aerial_pitch_scale"), -1.4, 1.4)
_aerial_pitch = lerpf(_aerial_pitch, target_pitch, delta * DP.f("aerial_pitch_speed"))
_bull.rotation.x = _tilt_x + _aerial_pitch
_charge_pitch_curr = lerpf(_charge_pitch_curr, charge_pitch_target, delta * DP.f("charge_head_speed"))
_bull.rotation.x = _tilt_x + _aerial_pitch + _charge_pitch_curr
_bull.rotation.z = _tilt_z
+5
View File
@@ -53,6 +53,11 @@ func _register_all() -> void:
_reg_f("Tail", "tail_body_radius", 0.35, 0.05, 2.0, 0.05)
_reg_f("Tail", "tail_wag_freq", 4.0, 0.5, 15.0)
_reg_f("Tail", "tail_wag_idle", 0.3, 0.0, 2.0, 0.05)
# ── Charge (both mouse buttons) ──────────────────────────────────────────
_reg_f("Charge", "bull_charge_accel", 20.0, 1.0, 200.0)
_reg_f("Charge", "bull_charge_max_speed", 22.0, 5.0, 100.0)
_reg_f("Charge", "charge_head_pitch", 0.3, 0.0, 1.2, 0.01)
_reg_f("Charge", "charge_head_speed", 5.0, 0.5, 20.0)
# ── Body ──────────────────────────────────────────────────────────────────
_reg_f("Body", "body_tilt_fwd", 0.015, 0.0, 0.1, 0.001)
_reg_f("Body", "body_tilt_side", 0.01, 0.0, 0.1, 0.001)
+37 -11
View File
@@ -14,9 +14,11 @@ const HOOF_OFFSETS: Array = [
var _hoof_emitters: Array[CPUParticles3D] = []
var _legs: Node
var _kick_timer: float = 0.0
var _was_on_floor: bool = false
var _kick_timer: float = 0.0
var _was_on_floor: bool = false
var _pre_slide_vel_y: float = 0.0
var _charge_dir: Vector3 = Vector3.ZERO
var _both_held: bool = false
enum DustState { NONE, WALK, CHARGE }
var _dust_state: DustState = DustState.NONE
@@ -177,18 +179,42 @@ func _physics_process(delta: float) -> void:
var charging := Input.is_action_pressed(&"charge")
var on_floor := is_on_floor()
# ── Left / right click thrust ─────────────────────────────────────────────
# Left click → thrust NE (forward-right diagonal)
# Right click → thrust NW (forward-left diagonal)
if Input.is_action_just_pressed(&"thrust_left") or Input.is_action_just_pressed(&"thrust_right"):
# ── Mouse button actions ──────────────────────────────────────────────────
# Both held → charge: lock direction, ramp speed, lower head
# Left only → thrust NE (forward-right diagonal)
# Right only → thrust NW (forward-left diagonal)
var left_held := Input.is_action_pressed(&"thrust_left")
var right_held := Input.is_action_pressed(&"thrust_right")
var both_held := left_held and right_held
if both_held and not _both_held:
var raw := cube_guy.global_transform.basis.z
var bull_fwd := Vector3(raw.x, 0.0, raw.z).normalized()
var bull_right := bull_fwd.cross(Vector3.UP)
if Input.is_action_just_pressed(&"thrust_left"):
_charge_dir = Vector3(raw.x, 0.0, raw.z).normalized()
if both_held:
velocity.x += _charge_dir.x * DP.f("bull_charge_accel") * delta
velocity.z += _charge_dir.z * DP.f("bull_charge_accel") * delta
var flat_c := Vector2(velocity.x, velocity.z)
var spd_c := flat_c.length()
if spd_c > DP.f("bull_charge_max_speed"):
velocity.x *= DP.f("bull_charge_max_speed") / spd_c
velocity.z *= DP.f("bull_charge_max_speed") / spd_c
_legs.set(&"charge_pitch_target", DP.f("charge_head_pitch"))
else:
_legs.set(&"charge_pitch_target", 0.0)
if Input.is_action_just_pressed(&"thrust_left") and not right_held:
var raw := cube_guy.global_transform.basis.z
var bull_fwd := Vector3(raw.x, 0.0, raw.z).normalized()
var bull_right := bull_fwd.cross(Vector3.UP)
_apply_thrust((bull_fwd + bull_right).normalized())
else:
elif Input.is_action_just_pressed(&"thrust_right") and not left_held:
var raw := cube_guy.global_transform.basis.z
var bull_fwd := Vector3(raw.x, 0.0, raw.z).normalized()
var bull_right := bull_fwd.cross(Vector3.UP)
_apply_thrust((bull_fwd - bull_right).normalized())
_both_held = both_held
# Reset kick timer on landing so the first kick after a bounce is immediate
if on_floor and not _was_on_floor and direction:
_kick_timer = 0.0
@@ -196,7 +222,7 @@ func _physics_process(delta: float) -> void:
# ── Periodic kick ─────────────────────────────────────────────────────────
_kick_timer = maxf(0.0, _kick_timer - delta)
if direction and _kick_timer <= 0.0:
if direction and _kick_timer <= 0.0 and not both_held:
_apply_kick(direction, charging)
_kick_timer = DP.f("kick_interval")