fixed finally webrtc
This commit is contained in:
@@ -21,11 +21,22 @@ var is_airborne: bool = true
|
||||
var velocity_set_by_spawner: bool = false # Track if velocity was set externally
|
||||
|
||||
# Bounce physics
|
||||
var bounce_restitution: float = 0.6 # How much bounce energy is retained (0-1)
|
||||
var bounce_restitution: float = 0.6 # How much bounce energy is retained (0-1) - matches old code
|
||||
var min_bounce_velocity: float = 40.0 # Minimum velocity needed to bounce
|
||||
var friction: float = 25.0 # Friction when on ground (increased to dampen faster)
|
||||
var friction: float = 8.0 # Friction when on ground (lower = more gradual slowdown, matches old code)
|
||||
var bounce_timer: float = 0.0 # Prevent rapid bounce sounds
|
||||
|
||||
# Multiplayer sync and prediction
|
||||
var sync_timer: float = 0.0 # Timer for periodic position/velocity sync
|
||||
var sync_interval: float = 0.05 # Sync every 0.05 seconds (20 times per second) for smoother sync
|
||||
var last_sync_time: float = 0.0 # Track last server sync time for reconciliation
|
||||
var server_position: Vector2 = Vector2.ZERO # Last server-authoritative position
|
||||
var server_velocity: Vector2 = Vector2.ZERO # Last server-authoritative velocity
|
||||
var server_position_z: float = 0.0 # Last server-authoritative Z position
|
||||
var server_velocity_z: float = 0.0 # Last server-authoritative Z velocity
|
||||
var prediction_error_threshold: float = 10.0 # Distance threshold before correcting (pixels)
|
||||
var correction_smoothing: float = 0.3 # Lerp factor for smooth correction (0-1, lower = smoother)
|
||||
|
||||
# Loot properties
|
||||
var coin_value: int = 1
|
||||
var heal_amount: float = 20.0
|
||||
@@ -77,11 +88,13 @@ func _ready():
|
||||
|
||||
# Adjust bounce properties based on loot type
|
||||
if loot_type == LootType.COIN:
|
||||
bounce_restitution = 0.4 # Reduced from 0.6 to dampen more
|
||||
bounce_restitution = 0.6 # Matches old code - more bouncy
|
||||
min_bounce_velocity = 40.0
|
||||
friction = 8.0 # Lower friction for coins - more gradual slowdown
|
||||
else:
|
||||
bounce_restitution = 0.2 # Reduced from 0.3 to dampen more
|
||||
bounce_restitution = 0.3 # Lower bounce for food items
|
||||
min_bounce_velocity = 60.0
|
||||
friction = 12.0 # Slightly higher friction for food items
|
||||
|
||||
func _setup_sprite():
|
||||
if not sprite:
|
||||
@@ -171,100 +184,174 @@ func _physics_process(delta):
|
||||
if collected:
|
||||
return
|
||||
|
||||
# Update bounce timer
|
||||
if bounce_timer > 0.0:
|
||||
bounce_timer -= delta
|
||||
if bounce_timer < 0:
|
||||
bounce_timer = 0.0
|
||||
var is_client = multiplayer.has_multiplayer_peer() and not is_multiplayer_authority()
|
||||
var is_server = not multiplayer.has_multiplayer_peer() or is_multiplayer_authority()
|
||||
|
||||
# Update Z-axis physics
|
||||
if is_airborne:
|
||||
# Apply gravity to Z-axis
|
||||
acceleration_z = -300.0 # Gravity
|
||||
velocity_z += acceleration_z * delta
|
||||
# Server (authority): Run physics normally
|
||||
if is_server:
|
||||
# Update bounce timer
|
||||
if bounce_timer > 0.0:
|
||||
bounce_timer -= delta
|
||||
if bounce_timer < 0:
|
||||
bounce_timer = 0.0
|
||||
|
||||
# CRITICAL: Apply damping to velocity_z to lerp it towards 0 (prevents infinite bouncing)
|
||||
# Dampen more when velocity is small (closer to ground) but allow normal bounces first
|
||||
var damping_factor = 8.0 # How quickly velocity_z approaches 0 (allow more visible bounces)
|
||||
if abs(velocity_z) < 25.0: # More aggressive damping for very small velocities only
|
||||
damping_factor = 20.0
|
||||
velocity_z = lerpf(velocity_z, 0.0, 1.0 - exp(-damping_factor * delta))
|
||||
|
||||
position_z += velocity_z * delta
|
||||
|
||||
# Apply air resistance to slow down horizontal movement while airborne
|
||||
velocity = velocity.lerp(Vector2.ZERO, 1.0 - exp(-8.0 * delta))
|
||||
|
||||
# Ground collision and bounce (skip if collected to prevent bounce sounds)
|
||||
if position_z <= 0.0:
|
||||
position_z = 0.0
|
||||
# Update Z-axis physics
|
||||
if is_airborne:
|
||||
# Apply gravity to Z-axis (matches old code)
|
||||
acceleration_z = -300.0 # Gravity
|
||||
velocity_z += acceleration_z * delta
|
||||
position_z += velocity_z * delta
|
||||
|
||||
# Apply friction when on ground (dampen X/Y momentum faster)
|
||||
velocity = velocity.lerp(Vector2.ZERO, 1.0 - exp(-friction * delta))
|
||||
|
||||
# Check if we should bounce (only if not collected and velocity is significant)
|
||||
# Allow bouncing but ensure it eventually stops
|
||||
if not collected and abs(velocity_z) > min_bounce_velocity:
|
||||
# Bounce on floor
|
||||
# Only play bounce sound if bounce is significant enough and timer has elapsed
|
||||
# CRITICAL: Only play sound if velocity is large enough and coin is actually falling (downward)
|
||||
if loot_type == LootType.COIN and bounce_timer == 0.0 and abs(velocity_z) > 50.0 and velocity_z < 0.0:
|
||||
# Play bounce sound for coins (only for significant downward velocities)
|
||||
if sfx_coin_bounce:
|
||||
# Adjust volume based on bounce velocity (softer for smaller bounces)
|
||||
var volume_multiplier = clamp(abs(velocity_z) / 100.0, 0.3, 1.0)
|
||||
sfx_coin_bounce.volume_db = -3.0 + (-12.0 * (1.0 - volume_multiplier))
|
||||
sfx_coin_bounce.play()
|
||||
bounce_timer = 0.12 # Prevent rapid bounce sounds but allow reasonable bounce rate
|
||||
# Ground collision and bounce (matches old code - simpler, no aggressive damping)
|
||||
if position_z <= 0.0:
|
||||
position_z = 0.0
|
||||
|
||||
velocity_z = - velocity_z * bounce_restitution
|
||||
# Apply friction ONLY when on ground (matches old code behavior)
|
||||
velocity = velocity.lerp(Vector2.ZERO, 1.0 - exp(-friction * delta))
|
||||
|
||||
# CRITICAL: Force stop bouncing if velocity is too small after bounce (prevent micro-bounces)
|
||||
# Use a lower threshold to allow a few more bounces before stopping
|
||||
if abs(velocity_z) < min_bounce_velocity * 0.5:
|
||||
# Check if we should bounce (simpler logic matching old code)
|
||||
if not collected and abs(velocity_z) > min_bounce_velocity:
|
||||
# Play bounce sound for coins (matches old code volume formula)
|
||||
if loot_type == LootType.COIN and bounce_timer == 0.0 and velocity_z < 0.0:
|
||||
if sfx_coin_bounce:
|
||||
# Old code formula: -1 + (-10 - (velocityZ * 0.1))
|
||||
# Adjusted for negative velocity_z
|
||||
sfx_coin_bounce.volume_db = -1.0 + (-10.0 - (abs(velocity_z) * 0.1))
|
||||
sfx_coin_bounce.play()
|
||||
bounce_timer = 0.08 # Matches old code timing
|
||||
|
||||
# Simple bounce (matches old code)
|
||||
velocity_z = -velocity_z * bounce_restitution
|
||||
is_airborne = true # Still bouncing
|
||||
else:
|
||||
# Velocity too small or collected - stop bouncing
|
||||
velocity_z = 0.0
|
||||
is_airborne = false
|
||||
else:
|
||||
is_airborne = true # Still bouncing
|
||||
else:
|
||||
# Velocity too small or collected - stop bouncing
|
||||
velocity_z = 0.0
|
||||
is_airborne = false
|
||||
else:
|
||||
is_airborne = false
|
||||
# Ensure velocity_z is zero when on ground
|
||||
velocity_z = 0.0
|
||||
# Apply friction even when not airborne (on ground)
|
||||
velocity = velocity.lerp(Vector2.ZERO, 1.0 - exp(-friction * delta))
|
||||
else:
|
||||
is_airborne = false
|
||||
# Ensure velocity_z is zero when on ground
|
||||
velocity_z = 0.0
|
||||
# Apply friction when on ground (matches old code)
|
||||
velocity = velocity.lerp(Vector2.ZERO, 1.0 - exp(-friction * delta))
|
||||
|
||||
# Move and check for collisions
|
||||
move_and_slide()
|
||||
|
||||
# Check for wall collisions (skip if collected to prevent bounce sounds)
|
||||
# Matches old code behavior - simpler wall bounce without aggressive velocity reduction
|
||||
if not collected:
|
||||
for i in get_slide_collision_count():
|
||||
var collision = get_slide_collision(i)
|
||||
if collision:
|
||||
var collider = collision.get_collider()
|
||||
# Only bounce off walls, not players (players are detected via PickupArea)
|
||||
if collider and not collider.is_in_group("player"):
|
||||
# Check if velocity is too small before bouncing (prevent infinite micro-bounces)
|
||||
var velocity_magnitude = velocity.length()
|
||||
if velocity_magnitude < 15.0: # If velocity is very small, stop bouncing
|
||||
velocity = Vector2.ZERO
|
||||
continue # Skip bounce and sound
|
||||
|
||||
# Bounce off walls (matches old code - no aggressive velocity reduction)
|
||||
var normal = collision.get_normal()
|
||||
velocity = velocity.bounce(normal) # Old code didn't reduce velocity here
|
||||
|
||||
# Play bounce sound for coins hitting walls (matches old code)
|
||||
if loot_type == LootType.COIN and bounce_timer == 0.0:
|
||||
if sfx_coin_bounce:
|
||||
sfx_coin_bounce.volume_db = -5.0
|
||||
sfx_coin_bounce.play()
|
||||
bounce_timer = 0.08 # Matches old code timing
|
||||
|
||||
# Update visual position based on Z
|
||||
_update_visuals()
|
||||
|
||||
# Animate coin rotation (always animate, even when not airborne)
|
||||
if loot_type == LootType.COIN:
|
||||
_animate_coin(delta)
|
||||
|
||||
# Server: Periodically sync position/velocity to clients (sync more frequently when airborne)
|
||||
sync_timer += delta
|
||||
# Sync more frequently when airborne (bouncing), less when settled
|
||||
var current_interval = sync_interval if is_airborne else sync_interval * 2.0
|
||||
if sync_timer >= current_interval:
|
||||
sync_timer = 0.0
|
||||
var game_world = get_tree().get_first_node_in_group("game_world")
|
||||
if game_world and game_world.has_method("_sync_loot_physics"):
|
||||
var loot_id = get_meta("loot_id") if has_meta("loot_id") else -1
|
||||
if loot_id >= 0:
|
||||
game_world._rpc_to_ready_peers("_sync_loot_physics", [loot_id, global_position, velocity, position_z, velocity_z])
|
||||
|
||||
# Move and check for collisions
|
||||
move_and_slide()
|
||||
|
||||
# Check for wall collisions (skip if collected to prevent bounce sounds)
|
||||
if not collected:
|
||||
for i in get_slide_collision_count():
|
||||
var collision = get_slide_collision(i)
|
||||
if collision:
|
||||
var collider = collision.get_collider()
|
||||
# Only bounce off walls, not players (players are detected via PickupArea)
|
||||
if collider and not collider.is_in_group("player"):
|
||||
# Bounce off walls
|
||||
var normal = collision.get_normal()
|
||||
velocity = velocity.bounce(normal) * 0.5 # Reduce velocity more after bounce (was 0.8)
|
||||
|
||||
# Play bounce sound for coins hitting walls
|
||||
if loot_type == LootType.COIN and bounce_timer == 0.0:
|
||||
# Client (prediction): Run physics locally for smooth movement, then reconcile with server
|
||||
elif is_client:
|
||||
# Run physics locally (client-side prediction) - same logic as server
|
||||
# Update bounce timer
|
||||
if bounce_timer > 0.0:
|
||||
bounce_timer -= delta
|
||||
if bounce_timer < 0:
|
||||
bounce_timer = 0.0
|
||||
|
||||
# Update Z-axis physics
|
||||
if is_airborne:
|
||||
# Apply gravity to Z-axis (matches server)
|
||||
acceleration_z = -300.0
|
||||
velocity_z += acceleration_z * delta
|
||||
position_z += velocity_z * delta
|
||||
|
||||
# Ground collision and bounce (matches server logic)
|
||||
if position_z <= 0.0:
|
||||
position_z = 0.0
|
||||
velocity = velocity.lerp(Vector2.ZERO, 1.0 - exp(-friction * delta))
|
||||
|
||||
if not collected and abs(velocity_z) > min_bounce_velocity:
|
||||
# Play bounce sound for coins
|
||||
if loot_type == LootType.COIN and bounce_timer == 0.0 and velocity_z < 0.0:
|
||||
if sfx_coin_bounce:
|
||||
sfx_coin_bounce.volume_db = -5.0
|
||||
sfx_coin_bounce.volume_db = -1.0 + (-10.0 - (abs(velocity_z) * 0.1))
|
||||
sfx_coin_bounce.play()
|
||||
bounce_timer = 0.08
|
||||
|
||||
# Update visual position based on Z
|
||||
_update_visuals()
|
||||
|
||||
# Animate coin rotation (always animate, even when not airborne)
|
||||
if loot_type == LootType.COIN:
|
||||
_animate_coin(delta)
|
||||
velocity_z = -velocity_z * bounce_restitution
|
||||
is_airborne = true
|
||||
else:
|
||||
velocity_z = 0.0
|
||||
is_airborne = false
|
||||
else:
|
||||
is_airborne = false
|
||||
velocity_z = 0.0
|
||||
velocity = velocity.lerp(Vector2.ZERO, 1.0 - exp(-friction * delta))
|
||||
|
||||
# Move and check for collisions
|
||||
move_and_slide()
|
||||
|
||||
# Check for wall collisions
|
||||
if not collected:
|
||||
for i in get_slide_collision_count():
|
||||
var collision = get_slide_collision(i)
|
||||
if collision:
|
||||
var collider = collision.get_collider()
|
||||
if collider and not collider.is_in_group("player"):
|
||||
var velocity_magnitude = velocity.length()
|
||||
if velocity_magnitude < 15.0:
|
||||
velocity = Vector2.ZERO
|
||||
continue
|
||||
var normal = collision.get_normal()
|
||||
velocity = velocity.bounce(normal)
|
||||
if loot_type == LootType.COIN and bounce_timer == 0.0:
|
||||
if sfx_coin_bounce:
|
||||
sfx_coin_bounce.volume_db = -5.0
|
||||
sfx_coin_bounce.play()
|
||||
bounce_timer = 0.08
|
||||
|
||||
# Update visuals
|
||||
_update_visuals()
|
||||
|
||||
# Animate coin rotation
|
||||
if loot_type == LootType.COIN:
|
||||
_animate_coin(delta)
|
||||
|
||||
# Reconcile with server state if available (called from game_world._sync_loot_physics)
|
||||
# Server state is stored in server_position, server_velocity, etc. variables
|
||||
# Reconciliation happens in game_world._reconcile_loot_state()
|
||||
|
||||
func _update_z_physics(delta):
|
||||
position_z += velocity_z * delta
|
||||
|
||||
Reference in New Issue
Block a user