1
0
Fork 0
Cleanomancer/Script/Player.gd

159 lines
4.1 KiB
GDScript

tool
extends Area2D
class_name Player
export var speed : float = 1
export var speed_dash : float = 3
export var rest : float = 1
export var reservoir : int = 1
var level
onready var footsteps = $FootSteps
onready var deny = $Deny
var tile_position := Vector2(0,0) setget update_position
var last_move_time := 0.0
var step_count := 0
var stepped := false
var dashing := false
class Movement:
var action: String
var direction: Vector2
var animation: String
func _init(_action, _direction, _animation):
action = _action
direction = _direction
animation = _animation
var movements = [
Movement.new("ui_right", Vector2.RIGHT, "right"),
Movement.new("ui_left", Vector2.LEFT, "left"),
Movement.new("ui_up", Vector2.UP, "back"),
Movement.new("ui_down", Vector2.DOWN, "front")
]
class Sweep:
var action: String
var tile_limit
var waste_limit
var cost: int
var sound: AudioStreamPlayer
func _init(_action, _tlimit, _wlimit, _cost, _sound):
action = _action
tile_limit = _tlimit
waste_limit = _wlimit
cost = _cost
sound = _sound
onready var sweeps = [
Sweep.new("dash", INF, INF, 3, $Hoover),
Sweep.new("whoosh", INF, 1, 2, null)
]
var movement_queue = []
var current_target = null
var current_direction : Movement = movements.back() setget update_animation
onready var sprite = $AnimatedSprite as AnimatedSprite
func _process(delta):
if Engine.editor_hint:
return
if Input.is_action_just_pressed("reset"):
level.reset()
if Input.is_action_just_pressed("undo"):
level.undo()
if (last_move_time + rest) * 1000 < OS.get_ticks_msec():
for movement in movements:
if Input.is_action_pressed(movement.action):
current_direction = movement
if not Input.is_action_pressed("lock_move"):
var target = level.get_tile_v(tile_position + movement.direction)
if target.can_walk(movement.direction) or target.can_push(movement.direction):
movement_queue.push_back(movement)
update_animation()
if not movement_queue.empty():
var current_movement : Movement = movement_queue.front()
if current_target == null:
current_target = tile_position + current_movement.direction
var tile = level.get_tile_v(current_target)
if not tile.can_walk(current_movement.direction) and not tile.can_push(current_movement.direction):
current_target = null
movement_queue.pop_front()
else:
tile.push(current_movement.direction)
footsteps.play()
level.take_snap()
if current_target != null:
tile_position += current_movement.direction * delta * (speed_dash if dashing else speed)
var remaining : Vector2 = current_target - tile_position
if remaining.dot(current_movement.direction) <= 0:
tile_position = current_target
current_target = null
movement_queue.pop_front()
if dashing:
level.check_player_stairs()
stepped = false
dashing = false
if level.get_tile_v(tile_position).is_stairs_entrance():
level.end_of_level()
elif remaining.length() < 0.5 and not stepped:
step_count += 1
stepped = true
update_position()
last_move_time = OS.get_ticks_msec() / 1000.0
for sweep in sweeps:
if Input.is_action_just_pressed(sweep.action):
if reservoir >= sweep.cost:
if not current_target == null:
tile_position = current_target
var current = level.get_tile_v(tile_position)
var end = current.dash(current_direction.direction, sweep.tile_limit, sweep.waste_limit)
if current != end:
movement_queue = [current_direction]
current_target = Vector2 (end.x, end.y)
dashing = true
reservoir = reservoir - sweep.cost
level.update_reservoir()
if sweep.sound != null:
sweep.sound.play()
break
else:
deny.play()
else:
deny.play()
func update_position(var new_pos = false):
if new_pos is Vector2:
tile_position = new_pos
position = level._floor.cell_custom_transform * (tile_position + Vector2.ONE / 2 )
func update_animation(var new_dir = false):
if new_dir is Movement:
current_direction = new_dir
sprite.animation = current_direction.animation
sprite.frame = step_count % 2 + (0 if reservoir > 0 else 2)