1206๋ฒˆ์— 23.4ms? ๋”์ฐํ•˜๋„ค

----
์ˆ˜์ • ํ›„


2932๋ฒˆ ํ˜ธ์ถœ์— 8.6 ms

---

func _physics_process(delta):
var s_delta = TimeManager.scale_delta(delta)
var prev_pos := global_position

if velocity.length() > 0:
var collision: KinematicCollision2D = move_and_collide(velocity * s_delta)
if collision:
var collider = collision.get_collider()
if collider is Wall:
velocity = velocity.bounce(collision.get_normal()) * bounce

if is_being_pulled:
if _check_collect_path(prev_pos, global_position):
_collect()
return
else:
velocity = velocity.move_toward(Vector2.ZERO, friction * s_delta)
if velocity == Vector2.ZERO and spawn_scale >= 1.0:
set_physics_process(false)


์ด๊ฒŒ ๊ธฐ์กด์ฝ”๋“œ์ธ๋ฐ is_being_pulled ์ƒํƒœ์—๋Š” ๋ฌผ๋ฆฌ ์ถฉ๋Œ์ด ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋‹ˆ๊นŒ ๋กœ์ง์„ _process๋กœ ์ด์ „ํ•˜๊ณ  move_and_collide ๋Œ€์‹ 
global_position += velocity * delta ์‚ฌ์šฉ์œผ๋กœ ์ˆ˜์ •ํ•˜๊ธฐ๋กœ ํ•˜๊ณ  _process ๋กœ ๋„˜์–ด๊ฐ


func _process(delta):
# ์•„์ดํ…œ ์ค๋Š”๊ฑฐ์—๋Š” ์ผ๋ฐ˜ ์‹œ๊ฐ„ ์‚ฌ์šฉ
# var s_delta = TimeManager.scale_delta(delta)
if spawn_scale < 1.0:
spawn_scale = move_toward(spawn_scale, 1.0, SPAWN_SCALE_SPEED * delta)
scale = Vector2.ONE * spawn_scale
else:
if not is_being_pulled:
set_process(false)

if is_being_pulled:
if not _has_valid_target_magnet():
is_being_pulled = false
return

var target_pos = target_magnet.global_position
var distance = global_position.distance_to(target_pos)

if distance < COLLECT_RANGE or velocity.length() > FORCED_COLLECT_SPEED:
_collect()
return

if velocity.length() > 10.0:
var target_rotation = velocity.angle() + PI/2
rotation = lerp_angle(rotation, target_rotation, 2 * delta)

var direction = (target_pos - global_position).normalized()
pull_speed += PULL_STRENTGTH * delta
# ๊ธฐ๋ณธ ์†๋„๋Š” ๊ณ„์† ์ฆ๊ฐ€
var base_speed = pow(pull_speed, 2) * 0.01
# ๊ฐ€๊นŒ์šธ ๋•Œ๋งŒ ์ถ”๊ฐ€ ๋ถ€์ŠคํŠธ (150px ์ดํ•˜์ผ ๋•Œ)
var distance_boost = 1.0
if distance < 50.0:
distance_boost += (50.0 - distance) / 50.0
var target_velocity = direction * base_speed * distance_boost
var speed_factor = min(velocity.length() / 1000.0, 1.0)
var distance_factor = 1.0 - min(distance / 200.0, 1.0)
var dynamic_turn_speed = TURN_SPEED + (speed_factor * 0.3) + (distance_factor * 0.2)
velocity = velocity.lerp(target_velocity, dynamic_turn_speed)



์ผ๋‹จ ๋ชจ๋“  ๊ฑฐ๋ฆฌ ๊ด€๋ จ ์—ฐ์‚ฐ์„ squared ๊ธฐ๋ฐ˜์œผ๋กœ ๋ณ€๊ฒฝ ์ด๋Ÿฌ๋ฉด ์ œ๊ณฑ๊ทผ ๊ณ„์‚ฐ์ด ๋น ์ ธ์„œ ์„ฑ๋Šฅ์ ์œผ๋กœ ์ข‹์•„๋ณด์ž„

var distance_sq := global_position.distance_squared_to(target_pos)

if distance_sq < COLLECT_RANGE_SQ or velocity.length_squared() > FORCED_COLLECT_SPEED_SQ:
_collect()
return


๊ทธ๋‹ค์Œ _process ์ˆ˜์ •ํ•˜๊ธฐ ์ „์— _check_collect_path๋ฅผ ํ™•์ธํ•ด๋ณด์ž
ํ•ด๋‹น ํ•จ์ˆ˜๋Š” drop์˜ ์†๋„๊ฐ€ ๋นจ๋ผ ํš๋“ํ•˜์ง€ ๋ชปํ•˜๊ณ  ์˜ค๋ฒ„์Š› ํ–ˆ์„๊ฒฝ์šฐ๋ฅผ ๋ง‰์•„์ฃผ๋Š” ํ•จ์ˆ˜์ด๋‹ค

func _check_collect_path(start_pos: Vector2, end_pos: Vector2) -> bool:
if is_collected or not _has_valid_target_magnet():
return false

var target_pos := target_magnet.global_position
var collect_range_sq := COLLECT_RANGE * COLLECT_RANGE

if start_pos.distance_squared_to(target_pos) <= collect_range_sq:
return true
if end_pos.distance_squared_to(target_pos) <= collect_range_sq:
return true

var segment := end_pos - start_pos
var segment_len_sq := segment.length_squared()
if segment_len_sq <= 0.0001:
return false

var t := clampf((target_pos - start_pos).dot(segment) / segment_len_sq, 0.0, 1.0)
var closest_point := start_pos + segment * t
return closest_point.distance_squared_to(target_pos) <= collect_range_sq


๋งค๋ฒˆ target_magnet ์„ ๋“ค๊ณ ์˜ค๋Š”๋ฐ _process๋กœ ์ด๋™ํ–ˆ์œผ๋‹ˆ ์ด๋ฏธ ๋“ค๊ณ ์žˆ๋Š” ๊ฐ’์„ ์“ธ ์ˆ˜ ์žˆ์„๊ฒƒ ๊ฐ™๋‹ค
collect_range_sq๋„ ์ƒ์ˆ˜๋กœ ๋นผ๊ณ  ํ•˜๋ฉด


func _is_collect_path_crossed(
start_pos: Vector2,
end_pos: Vector2,
target_pos: Vector2,
start_distance_sq: float,
end_distance_sq: float
) -> bool:
if start_distance_sq <= COLLECT_RANGE_SQ:
return true
if end_distance_sq <= COLLECT_RANGE_SQ:
return true

var segment := end_pos - start_pos
var segment_len_sq := segment.length_squared()
if segment_len_sq <= 0.0001:
return false

var t := clampf((target_pos - start_pos).dot(segment) / segment_len_sq, 0.0, 1.0)
var closest_point := start_pos + segment * t
return closest_point.distance_squared_to(target_pos) <= COLLECT_RANGE_SQ


์ด์ •๋„๋กœ ๊ฐ€๋Šฅํ• ๊ฒƒ ๊ฐ™๋‹ค
์‚ฌ์šฉํ•˜๋Š” ๊ฐ’ ๊ณ„์‚ฐ์€ ์ „๋ถ€ ์™ธ๋ถ€์—์„œ ํ•˜๊ณ  ๋‚ด๋ถ€๋Š” ํ™•์ธ๋งŒ ํ•˜๋Š”์ •๋„

๊ทธ๋ž˜์„œ ์ตœ์ข… ์ฝ”๋“œ

func _physics_process(delta):
if is_being_pulled:
set_physics_process(false)
return # ๋Œ๋ ค๊ฐ€๋Š” ์ค‘์—๋Š” ๋ฌผ๋ฆฌ ์ด๋™ ์ฒ˜๋ฆฌ ์•ˆํ•จ, _process์—์„œ ์ฒ˜๋ฆฌ

var s_delta = TimeManager.scale_delta(delta)
if velocity != Vector2.ZERO:
var collision: KinematicCollision2D = move_and_collide(velocity * s_delta)
if collision:
var collider = collision.get_collider()
if collider is Wall:
velocity = velocity.bounce(collision.get_normal()) * bounce
velocity = velocity.move_toward(Vector2.ZERO, friction * s_delta)
if velocity == Vector2.ZERO and spawn_scale >= 1.0:
set_physics_process(false)

func _process(delta):
# ์•„์ดํ…œ ์ค๋Š”๊ฑฐ์—๋Š” ์ผ๋ฐ˜ ์‹œ๊ฐ„ ์‚ฌ์šฉ
if spawn_scale < 1.0:
spawn_scale = move_toward(spawn_scale, 1.0, SPAWN_SCALE_SPEED * delta)
scale = Vector2.ONE * spawn_scale
else:
if not is_being_pulled:
set_process(false)

if is_being_pulled:
if not _has_valid_target_magnet():
is_being_pulled = false
return

var start_pos := global_position
var target_pos := target_magnet.global_position
var to_target := target_pos - start_pos
var distance_sq := to_target.length_squared()
var velocity_len_sq := velocity.length_squared()

if distance_sq < COLLECT_RANGE_SQ or velocity_len_sq > FORCED_COLLECT_SPEED_SQ:
_collect()
return

if velocity_len_sq > 100.0:
var target_rotation = velocity.angle() + PI / 2
rotation = lerp_angle(rotation, target_rotation, 2 * delta)

var distance := sqrt(distance_sq)
var direction := to_target / distance
pull_speed += PULL_STRENTGTH * delta
# ๊ธฐ๋ณธ ์†๋„๋Š” ๊ณ„์† ์ฆ๊ฐ€
var base_speed = pull_speed * pull_speed * 0.01
# ๊ฐ€๊นŒ์šธ ๋•Œ๋งŒ ์ถ”๊ฐ€ ๋ถ€์ŠคํŠธ (150px ์ดํ•˜์ผ ๋•Œ)
var distance_boost = 1.0
if distance < 50.0:
distance_boost += (50.0 - distance) / 50.0
var target_velocity = direction * base_speed * distance_boost
var speed_factor = min(sqrt(velocity_len_sq) / 1000.0, 1.0)
var distance_factor = 1.0 - min(distance / 200.0, 1.0)
var dynamic_turn_speed = TURN_SPEED + (speed_factor * 0.3) + (distance_factor * 0.2)
velocity = velocity.lerp(target_velocity, dynamic_turn_speed)

global_position += velocity * delta
var end_distance_sq := global_position.distance_squared_to(target_pos)
if _is_collect_path_crossed(start_pos, global_position, target_pos, distance_sq, end_distance_sq):
_collect()
return




16gb m1 mac ์—์„œ ์ด์ •๋„๋กœ ๋Œ์•„๊ฐ€๋ฉด ์ผ๋ฐ˜ pc ์—์„œ๋Š” ์ง€์—ฐ์ด ์ฒด๊ฐ๋˜์ง€ ์•Š์„๊ฑฐ๋ผ ์ƒ๊ฐํ•จ
์˜ค๋Š˜์˜ ์ตœ์ ํ™”๋Š” ์—ฌ๊ธฐ์„œ ๋