use tweens for animation
This commit is contained in:
parent
d3a5b737d9
commit
66314ebe4c
3 changed files with 63 additions and 45 deletions
29
main.gd
29
main.gd
|
|
@ -19,7 +19,13 @@ var levels: Array[PackedScene] = [
|
|||
preload("res://level/level_03.tscn"),
|
||||
preload("res://level/level_04.tscn"),
|
||||
]
|
||||
var time := 0
|
||||
# TODO: screen transition to hide awkward animations lol
|
||||
var time := 0:
|
||||
set(new_time):
|
||||
var tween := get_tree().create_tween()
|
||||
var anim_time = 1 if slowmo() else 0.1
|
||||
tween.tween_property($Sun, "rotation_degrees:y", -20*new_time, anim_time)
|
||||
time = new_time
|
||||
var advancing := false
|
||||
|
||||
@onready var sound: AudioStreamPlayer = $Sound
|
||||
|
|
@ -35,9 +41,8 @@ func _process(delta: float) -> void:
|
|||
$RedoButton.disabled = not hist.has_redo()
|
||||
$RestartButton.disabled = not hist.has_undo()
|
||||
$Clock.text = "T = %d" % time
|
||||
$Sun.rotation_degrees.y = -10*time
|
||||
if $TopLeft.is_on_screen() and $BottomRight.is_on_screen():
|
||||
return
|
||||
$SlowmoIndicator.text = "slowmo" if slowmo() else ""
|
||||
if not $TopLeft.is_on_screen() or not $BottomRight.is_on_screen():
|
||||
camera.position.y += 10*delta
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
|
|
@ -72,6 +77,11 @@ func redo():
|
|||
func restart():
|
||||
while hist.has_undo():
|
||||
hist.undo()
|
||||
# HACK: avoid an inconsistent visual board state
|
||||
for piece in board.pieces():
|
||||
for tween in piece.tweens:
|
||||
tween.kill()
|
||||
piece.tween_to_target()
|
||||
# i think it's unintuitive to be able to redo from restart
|
||||
# scratch that i like that, don't clear the history
|
||||
# you can like replay your steps up to a point
|
||||
|
|
@ -83,19 +93,12 @@ func board_step():
|
|||
hist.add_undo_method(board.undo_step())
|
||||
hist.add_undo_property(self, "time", time)
|
||||
|
||||
# TODO: OH MY GOSH OG MY GOSH OH MY GOSH
|
||||
# CONSOLIDATE ALL MOVEMENT INTO APPLYING VELOCITY
|
||||
# INCLUDING PLAYER MOVEMENT
|
||||
# I REALLY REALLY REALLY REALLY LIKE ADDING VELOCITY WITH TIME
|
||||
# NOT CHANGING OH MY GOSH THAT IS *GOOD*
|
||||
func step(move: Vector2i):
|
||||
if advancing:
|
||||
return
|
||||
if won():
|
||||
advance_level()
|
||||
return
|
||||
# the ability to wait removes some parity stuff
|
||||
# but that stuff kinda sucks
|
||||
if move == Vector2i.ZERO:
|
||||
hist.create_action("wait")
|
||||
board_step()
|
||||
|
|
@ -139,6 +142,7 @@ func advance_level():
|
|||
print("level won")
|
||||
await get_tree().create_timer(1).timeout
|
||||
advancing = false
|
||||
$Sun.rotation.y = 0
|
||||
time = 0
|
||||
level_num += 1
|
||||
if level_num >= levels.size():
|
||||
|
|
@ -167,3 +171,6 @@ func audio_stream_randomizer_from_dir(dir: String) -> AudioStreamRandomizer:
|
|||
stream.add_stream(-1, load(dir+"/"+file_name))
|
||||
file_name = hit_dir.get_next()
|
||||
return stream
|
||||
|
||||
func slowmo() -> bool:
|
||||
return Input.is_action_pressed("slowmo")
|
||||
|
|
|
|||
11
main.tscn
11
main.tscn
|
|
@ -24,7 +24,7 @@ albedo_color = Color(0.250136, 0.493198, 0.284902, 1)
|
|||
|
||||
[sub_resource type="PlaneMesh" id="PlaneMesh_1bvp3"]
|
||||
material = SubResource("StandardMaterial3D_1bvp3")
|
||||
size = Vector2(200, 200)
|
||||
size = Vector2(64, 64)
|
||||
|
||||
[node name="Main" type="Node3D"]
|
||||
script = ExtResource("1_ig7tw")
|
||||
|
|
@ -90,6 +90,15 @@ theme_override_font_sizes/normal_font_size = 32
|
|||
text = "T = 0"
|
||||
fit_content = true
|
||||
|
||||
[node name="SlowmoIndicator" type="Label" parent="."]
|
||||
offset_left = 1065.0
|
||||
offset_top = 615.0
|
||||
offset_right = 1150.0
|
||||
offset_bottom = 659.0
|
||||
text = "slowmo"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Ground" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.1, 0)
|
||||
mesh = SubResource("PlaneMesh_1bvp3")
|
||||
|
|
|
|||
66
piece.gd
66
piece.gd
|
|
@ -16,37 +16,45 @@ enum Type {
|
|||
}
|
||||
|
||||
## squares per second
|
||||
@export_range(0.1, 50) var anim_speed := 10.0
|
||||
@export_range(0.1, 50) var anim_speed_normal := 10.0
|
||||
@export_range(0.1, 50) var anim_speed_slow := 1.0
|
||||
|
||||
var tweens: Array[Tween] = []
|
||||
|
||||
func anim_speed() -> float:
|
||||
return anim_speed_slow if Input.is_action_pressed("slowmo") else anim_speed_normal
|
||||
|
||||
func anim_time() -> float:
|
||||
return 1/anim_speed()
|
||||
|
||||
#TODO: {un,}do_bump animation method (good visual clarity)
|
||||
|
||||
func pos_of_lpos(pos: Vector2i, y := 0.0) -> Vector3:
|
||||
return Vector3(pos.x, y, pos.y)
|
||||
|
||||
func target_pos() -> Vector3:
|
||||
return pos_of_lpos(lpos, position.y) + Vector3(0.5, 0, 0.5)
|
||||
|
||||
func tween_to_target(tween := create_tween()):
|
||||
tween.tween_property(self, "position", target_pos(), anim_time())
|
||||
tweens.push_back(tween)
|
||||
|
||||
func lpos_of_pos(pos: Vector3) -> Vector2i:
|
||||
return Vector2i(int(pos.x), int(pos.z))
|
||||
|
||||
## logical position
|
||||
var lpos: Vector2i:
|
||||
get:
|
||||
return Vector2i(int(target_pos.x), int(target_pos.z))
|
||||
set(val):
|
||||
position = target_pos
|
||||
start_pos = position
|
||||
# we offset by 0.5 to be in the middle of the square (for easier editing)
|
||||
target_pos = Vector3(val.x + 0.5, position.y, val.y + 0.5)
|
||||
anim_progress = 0
|
||||
@onready var lpos := lpos_of_pos(position)
|
||||
|
||||
## logical velocity
|
||||
@export var lvel := Vector2i.ZERO
|
||||
|
||||
@export var type: Piece.Type
|
||||
|
||||
@onready var start_pos := position
|
||||
@onready var target_pos := position
|
||||
@onready var anim_progress := 1.0
|
||||
var speedometer: Label3D
|
||||
|
||||
# TODO: much, *much* better animation is needed. ESPECIALLY if we're doing slowmo
|
||||
# (we're doing slowmo because it is SICK)
|
||||
func do_step(board: Board):
|
||||
if lvel == Vector2i.ZERO:
|
||||
return
|
||||
var move := lvel.clampi(-1, 1)
|
||||
var new_pos := lpos + move
|
||||
# ball being collided *with* gets the remainder of the momentum
|
||||
|
|
@ -65,6 +73,7 @@ func do_step(board: Board):
|
|||
var on_ice := !!board.type_at(lpos, Piece.Type.FloorIce)
|
||||
if not on_ice:
|
||||
lvel -= move
|
||||
tween_to_target()
|
||||
|
||||
func undo_step() -> Callable:
|
||||
var old_pos := lpos
|
||||
|
|
@ -72,35 +81,39 @@ func undo_step() -> Callable:
|
|||
return func():
|
||||
lpos = old_pos
|
||||
lvel = old_vel
|
||||
tween_to_target()
|
||||
|
||||
func do_move(move: Vector2i) -> Callable:
|
||||
return func():
|
||||
for tween in tweens:
|
||||
tween.kill()
|
||||
position = target_pos()
|
||||
lpos += move
|
||||
tween_to_target()
|
||||
|
||||
func undo_move() -> Callable:
|
||||
var old_pos := lpos
|
||||
return func():
|
||||
lpos = old_pos
|
||||
tween_to_target()
|
||||
|
||||
func do_push(move: Vector2i) -> Callable:
|
||||
return func():
|
||||
lvel += move
|
||||
anim_progress = 1
|
||||
|
||||
func undo_push() -> Callable:
|
||||
var old_vel := lvel
|
||||
return func():
|
||||
lvel = old_vel
|
||||
anim_progress = 1
|
||||
|
||||
# no logical effect, purely for aesthetics
|
||||
# (and communicating !!!! player yes)
|
||||
func do_bump(move: Vector2i) -> Callable:
|
||||
var real_lpos := lpos
|
||||
return func():
|
||||
lpos += move
|
||||
lpos = real_lpos
|
||||
anim_progress = 0.5
|
||||
var tween := create_tween()
|
||||
tween.tween_property(self, "position", target_pos() + pos_of_lpos(move)/2, anim_time())
|
||||
tween_to_target(tween)
|
||||
tweens.push_back(tween)
|
||||
|
||||
# TODO?: maybe fix? maybe the bump should be more complicated?
|
||||
func undo_bump(move: Vector2i) -> Callable:
|
||||
|
|
@ -122,7 +135,6 @@ static func wall(pos: Vector2i) -> Piece:
|
|||
return WALL.instantiate().with_lpos(pos)
|
||||
|
||||
func _ready() -> void:
|
||||
anim_progress = 1
|
||||
speedometer = Label3D.new()
|
||||
speedometer.billboard = BaseMaterial3D.BILLBOARD_ENABLED
|
||||
speedometer.no_depth_test = true
|
||||
|
|
@ -137,14 +149,4 @@ func format_vel(vel: Vector2) -> String:
|
|||
return "%d,%d" % [vel.x,vel.y]
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
var speed := anim_speed_slow if Input.is_action_pressed("slowmo") else anim_speed
|
||||
anim_progress = min(1, anim_progress + speed*delta)
|
||||
position = start_pos.lerp(target_pos, anim_progress)
|
||||
speedometer.text = format_vel(lvel)
|
||||
|
||||
# weird hack only necessary for the soon to be gone text parser
|
||||
func with_lpos(pos: Vector2i) -> Piece:
|
||||
lpos = pos
|
||||
lpos = pos
|
||||
anim_progress = 1
|
||||
return self
|
||||
|
|
|
|||
Loading…
Reference in a new issue