extends CollisionObject2D
signal level_reset_requested
const GRID_SIZE = 16
var moves = 0 setget set_moves
var last_move = null
var last_move_crate = null
var world: Node2D
var count = 0
var started = false
var won := false
signal won
onready var cam = $Camera2D
onready var tween = $Tween
onready var ray = $RayCast2D
onready var dir = $Direction
onready var anitree: AnimationTree = $AnimationTree
onready var anistate = anitree.get("parameters/playback")
func _ready():
anitree.active = true
func initialize():
won = false
set_physics_process(false)
yield(get_tree().create_timer(2), "timeout")
set_physics_process(true)
func _physics_process(_delta):
if Input.is_action_just_pressed("level_reload"):
emit_signal("level_reset_requested")
anistate.travel("Idle")
set_moves(0)
last_move = null
last_move_crate = null
return
if not world:
return
if Utils.stop_input:
return
if get_parent().get_parent().just_started:
return
if world.over:
anistate.travel("Idle")
return
if tween.is_active():
return
var move_intent = Vector2.ZERO
move_intent = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
if Input.is_action_just_pressed("undo_last_move"):
if last_move != null:
self.position -= last_move * GRID_SIZE
if last_move_crate != null:
last_move_crate.position -= last_move * GRID_SIZE
set_moves(moves - 1)
last_move = null
last_move_crate = null
return
if move_intent.x != 0 && move_intent.y != 0:
move_intent = Vector2.ZERO
if move_intent != Vector2.ZERO:
if not started:
get_parent().get_parent().start_stopwatch()
started = true
var offset = move_intent * GRID_SIZE
apply_rotation(offset)
if ray.is_colliding():
var collider = ray.get_collider()
if collider.is_in_group("crates"):
if !collider.push(offset):
anistate.travel("Idle")
return
last_move_crate = collider
else:
anistate.travel("Idle")
return
else:
last_move_crate = null
set_moves(moves + 1)
last_move = move_intent
tween.interpolate_property(
self,
"position",
self.position,
self.position + offset,
0.35,
Tween.TRANS_LINEAR,
Tween.EASE_IN_OUT
)
tween.start()
SoundFx.play("walk", -10, rand_range(.9, 1.1))
anistate.travel("Run")
anitree.set("parameters/Run/blend_position", move_intent)
else:
anistate.travel("Idle")
func set_moves(new_moves: int):
moves = new_moves
$"../../CanvasLayer/HUD/MovesLabel".text = "Moves: " + str(moves)
func apply_rotation(offset: Vector2):
ray.cast_to = offset
var new_rot := offset.angle()
ray.force_raycast_update()
var future_rot := lerp_angle(dir.rotation, new_rot, 1)
if future_rot != dir.rotation:
tween.interpolate_property(
dir, "rotation", dir.rotation, future_rot, 0.3, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT
)
tween.start()
func _over():
if won:
return
emit_signal("won")
won = true
func _on_Player_body_exited(_body):
pass
# if not body.name == "Player" and not body.is_in_group("crates"):
# print("emitting won")
# if won:
# return
# emit_signal("won")
# won = true