godot-puzzle/piece.gd
2025-05-02 20:42:32 -04:00

71 lines
1.5 KiB
GDScript

class_name Piece
extends MeshInstance3D
const WALL = preload("res://wall.tres")
const GOAL = preload("res://goal.tres")
const BOX = preload("res://box.tres")
const PLAYER = preload("res://player.tres")
enum Type {
Wall,
Goal,
Box,
Player,
}
## squares per second
@export_range(0.1, 100) var anim_speed := 10.0
# logical position
@export var lpos: Vector2i:
get:
return lpos
set(val):
lpos = val
position = target_pos
start_pos = position
target_pos = Vector3(lpos.x, position.y, lpos.y)
anim_progress = 0
@export var type: Piece.Type
@onready var start_pos := position
@onready var target_pos := position
@onready var anim_progress := 1.0
func do_move(move: Vector2i) -> Callable:
return func():
lpos += move
func undo_move() -> Callable:
var old_pos := lpos
return func():
lpos = old_pos
static func make(lpos: Vector2i, type: Piece.Type, mesh: Mesh) -> Piece:
var piece := Piece.new()
piece.lpos = lpos
piece.mesh = mesh
piece.type = type
return piece
static func wall(lpos: Vector2i) -> Piece:
return make(lpos, Piece.Type.Wall, WALL)
static func goal(lpos: Vector2i) -> Piece:
return make(lpos, Piece.Type.Goal, GOAL)
static func box(lpos: Vector2i) -> Piece:
return make(lpos, Piece.Type.Box, BOX)
static func player(lpos: Vector2i) -> Piece:
return make(lpos, Piece.Type.Player, PLAYER)
func _ready() -> void:
lpos = lpos
anim_progress = 1
func _process(delta: float) -> void:
anim_progress = min(1, anim_progress + anim_speed*delta)
position = start_pos.lerp(target_pos, anim_progress)