add undo feature
This commit is contained in:
parent
7e5cd4d449
commit
3bd07cc437
|
@ -21,19 +21,37 @@ export var stairs_x := 0
|
||||||
export var stairs_y := 0
|
export var stairs_y := 0
|
||||||
|
|
||||||
var completed := false
|
var completed := false
|
||||||
var initial_state
|
var saved_steps := []
|
||||||
|
|
||||||
|
class StepSnap:
|
||||||
|
var waste := {}
|
||||||
|
var reservoir : int
|
||||||
|
var player_position : Vector2
|
||||||
|
var player_direction : Player.Movement
|
||||||
|
|
||||||
|
static func snap(var l : Level) -> StepSnap:
|
||||||
|
var step = StepSnap.new()
|
||||||
|
for w in l._waste.get_used_cells():
|
||||||
|
step.waste[w] = l._waste.get_cellv(w)
|
||||||
|
step.reservoir = l._player.reservoir
|
||||||
|
step.player_position = l._player.tile_position
|
||||||
|
step.player_direction = l._player.current_direction
|
||||||
|
return step
|
||||||
|
|
||||||
|
func restore(var l : Level) -> void:
|
||||||
|
l._waste.clear()
|
||||||
|
for w in self.waste:
|
||||||
|
l._waste.set_cellv(w, self.waste[w])
|
||||||
|
l._player.reservoir = self.reservoir
|
||||||
|
l._player.tile_position = self.player_position
|
||||||
|
l._player.current_direction = self.player_direction
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
_player.level = self
|
_player.level = self
|
||||||
_player.tile_position = Vector2(start_x, start_y)
|
_player.tile_position = Vector2(start_x, start_y)
|
||||||
_stairs.visible = false
|
_stairs.visible = false
|
||||||
_stairs.modulate = Color.white
|
_stairs.modulate = Color.white
|
||||||
initial_state = {
|
|
||||||
waste = {},
|
|
||||||
reservoir = _player.reservoir
|
|
||||||
}
|
|
||||||
for w in _waste.get_used_cells():
|
|
||||||
initial_state.waste[w] = _waste.get_cellv(w)
|
|
||||||
|
|
||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
|
|
||||||
|
@ -145,6 +163,8 @@ class Tile:
|
||||||
func dash(var direction: Vector2, var tile_limit = INF, var waste_limit = INF) -> Tile:
|
func dash(var direction: Vector2, var tile_limit = INF, var waste_limit = INF) -> Tile:
|
||||||
var waste_line = get_waste_line(direction, true, tile_limit)
|
var waste_line = get_waste_line(direction, true, tile_limit)
|
||||||
waste_line.resize(min(waste_limit, waste_line.size()))
|
waste_line.resize(min(waste_limit, waste_line.size()))
|
||||||
|
if not waste_line.empty():
|
||||||
|
level.take_snap()
|
||||||
for tile in waste_line:
|
for tile in waste_line:
|
||||||
tile.set_tile(level._waste, -1)
|
tile.set_tile(level._waste, -1)
|
||||||
level.check_completed()
|
level.check_completed()
|
||||||
|
@ -184,29 +204,26 @@ func waste_sound(var number :int):
|
||||||
func player_initial_position():
|
func player_initial_position():
|
||||||
_player.level = self
|
_player.level = self
|
||||||
_player.tile_position = Vector2(start_x, start_y)
|
_player.tile_position = Vector2(start_x, start_y)
|
||||||
_player.update_position()
|
|
||||||
if not Engine.editor_hint:
|
if not Engine.editor_hint:
|
||||||
_player.current_direction = _player.movements.back()
|
_player.current_direction = _player.movements.back()
|
||||||
_player.update_animation()
|
|
||||||
|
|
||||||
func reset():
|
func take_snap():
|
||||||
if not completed:
|
if not completed:
|
||||||
|
saved_steps.push_back(StepSnap.snap(self))
|
||||||
|
|
||||||
|
func undo():
|
||||||
|
if not completed and not saved_steps.empty():
|
||||||
|
saved_steps.pop_back().restore(self)
|
||||||
|
|
||||||
_waste.clear()
|
func reset():
|
||||||
for w in initial_state.waste:
|
if not completed and not saved_steps.empty():
|
||||||
_waste.set_cellv(w, initial_state.waste[w])
|
saved_steps.front().restore(self)
|
||||||
|
saved_steps.clear()
|
||||||
player_initial_position()
|
|
||||||
|
|
||||||
_player.reservoir = initial_state.reservoir
|
|
||||||
update_reservoir()
|
|
||||||
|
|
||||||
func check_player_stairs():
|
func check_player_stairs():
|
||||||
if get_tile_v(_player.tile_position).is_stairs():
|
if get_tile_v(_player.tile_position).is_stairs():
|
||||||
_player.tile_position = Vector2(stairs_x - 1, stairs_y - 2)
|
_player.tile_position = Vector2(stairs_x - 1, stairs_y - 2)
|
||||||
_player.current_direction = _player.movements.back()
|
_player.current_direction = _player.movements.back()
|
||||||
_player.update_position()
|
|
||||||
_player.update_animation()
|
|
||||||
|
|
||||||
func end_of_level():
|
func end_of_level():
|
||||||
_player.visible = false
|
_player.visible = false
|
||||||
|
|
|
@ -12,7 +12,7 @@ var level
|
||||||
onready var footsteps = $FootSteps
|
onready var footsteps = $FootSteps
|
||||||
onready var deny = $Deny
|
onready var deny = $Deny
|
||||||
|
|
||||||
var tile_position := Vector2(0,0)
|
var tile_position := Vector2(0,0) setget update_position
|
||||||
var last_move_time := 0.0
|
var last_move_time := 0.0
|
||||||
var step_count := 0
|
var step_count := 0
|
||||||
var stepped := false
|
var stepped := false
|
||||||
|
@ -56,7 +56,7 @@ onready var sweeps = [
|
||||||
|
|
||||||
var movement_queue = []
|
var movement_queue = []
|
||||||
var current_target = null
|
var current_target = null
|
||||||
var current_direction : Movement = movements.back()
|
var current_direction : Movement = movements.back() setget update_animation
|
||||||
onready var sprite = $AnimatedSprite as AnimatedSprite
|
onready var sprite = $AnimatedSprite as AnimatedSprite
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
|
@ -64,8 +64,11 @@ func _process(delta):
|
||||||
if Engine.editor_hint:
|
if Engine.editor_hint:
|
||||||
return
|
return
|
||||||
|
|
||||||
if Input.is_action_pressed("reset"):
|
if Input.is_action_just_pressed("reset"):
|
||||||
level.reset()
|
level.reset()
|
||||||
|
|
||||||
|
if Input.is_action_just_pressed("undo"):
|
||||||
|
level.undo()
|
||||||
|
|
||||||
if (last_move_time + rest) * 1000 < OS.get_ticks_msec():
|
if (last_move_time + rest) * 1000 < OS.get_ticks_msec():
|
||||||
for movement in movements:
|
for movement in movements:
|
||||||
|
@ -75,7 +78,6 @@ func _process(delta):
|
||||||
var target = level.get_tile_v(tile_position + movement.direction)
|
var target = level.get_tile_v(tile_position + movement.direction)
|
||||||
if target.can_walk(movement.direction) or target.can_push(movement.direction):
|
if target.can_walk(movement.direction) or target.can_push(movement.direction):
|
||||||
movement_queue.push_back(movement)
|
movement_queue.push_back(movement)
|
||||||
|
|
||||||
|
|
||||||
update_animation()
|
update_animation()
|
||||||
|
|
||||||
|
@ -92,6 +94,7 @@ func _process(delta):
|
||||||
else:
|
else:
|
||||||
tile.push(current_movement.direction)
|
tile.push(current_movement.direction)
|
||||||
footsteps.play()
|
footsteps.play()
|
||||||
|
level.take_snap()
|
||||||
|
|
||||||
if current_target != null:
|
if current_target != null:
|
||||||
tile_position += current_movement.direction * delta * (speed_dash if dashing else speed)
|
tile_position += current_movement.direction * delta * (speed_dash if dashing else speed)
|
||||||
|
@ -143,9 +146,13 @@ func _process(delta):
|
||||||
deny.play()
|
deny.play()
|
||||||
|
|
||||||
|
|
||||||
func update_position():
|
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 )
|
position = level._floor.cell_custom_transform * (tile_position + Vector2.ONE / 2 )
|
||||||
|
|
||||||
func update_animation():
|
func update_animation(var new_dir = false):
|
||||||
|
if new_dir is Movement:
|
||||||
|
current_direction = new_dir
|
||||||
sprite.animation = current_direction.animation
|
sprite.animation = current_direction.animation
|
||||||
sprite.frame = step_count % 2 + (0 if reservoir > 0 else 2)
|
sprite.frame = step_count % 2 + (0 if reservoir > 0 else 2)
|
||||||
|
|
|
@ -105,6 +105,11 @@ reset={
|
||||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
undo={
|
||||||
|
"deadzone": 0.5,
|
||||||
|
"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":90,"unicode":0,"echo":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
[physics]
|
[physics]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue