fixed finally webrtc

This commit is contained in:
2026-01-19 23:51:57 +01:00
parent 454c065cf3
commit 1c247f3d82
44 changed files with 5264 additions and 486 deletions

View File

@@ -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