94 lines
2.8 KiB
GDScript
94 lines
2.8 KiB
GDScript
extends CharacterBody2D
|
|
|
|
signal place_shape(global_pos : Vector2, curve : Curve2D)
|
|
signal cut_shapes(global_pos : Vector2, curve : Curve2D)
|
|
signal has_won()
|
|
|
|
const SPEED := 500.0
|
|
const JUMP_VELOCITY = -300.0
|
|
|
|
var dead := false
|
|
var won := false
|
|
var bumped_into_wall := false
|
|
var finish : VisibleOnScreenNotifier2D = null
|
|
@onready var orig_pos := position
|
|
|
|
func _ready() -> void:
|
|
$AnimationPlayer.play("run")
|
|
$ShapeHintEllipse.visible = false
|
|
$ShapeHintRectangle.visible = true
|
|
|
|
func _process(delta: float) -> void:
|
|
var global_mouse_pos := get_global_mouse_position()
|
|
$ShapeHintEllipse.global_position = global_mouse_pos
|
|
$ShapeHintRectangle.global_position = global_mouse_pos
|
|
|
|
|
|
func _unhandled_input(event: InputEvent) -> void:
|
|
if event is InputEventMouseButton:
|
|
if event.button_index in [MOUSE_BUTTON_WHEEL_UP, MOUSE_BUTTON_WHEEL_DOWN] and not event.pressed:
|
|
$ShapeHintEllipse.visible = not $ShapeHintEllipse.visible
|
|
$ShapeHintRectangle.visible = not $ShapeHintRectangle.visible
|
|
|
|
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
|
var cur_shape : ScalableVectorShape2D = $ShapeHintEllipse if $ShapeHintEllipse.visible else $ShapeHintRectangle
|
|
place_shape.emit(get_global_mouse_position(), cur_shape.curve)
|
|
|
|
if event.button_index == MOUSE_BUTTON_RIGHT and event.pressed:
|
|
var cur_shape : ScalableVectorShape2D = $ShapeHintEllipse if $ShapeHintEllipse.visible else $ShapeHintRectangle
|
|
cut_shapes.emit(get_global_mouse_position(), cur_shape.curve)
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if dead or won:
|
|
return
|
|
if not is_on_floor():
|
|
velocity += get_gravity() * delta * 3
|
|
velocity.x = move_toward(velocity.x, 0.0, SPEED * delta)
|
|
else:
|
|
velocity.x = SPEED if $Pivot.scale.x > 0 else -SPEED
|
|
move_and_slide()
|
|
if bumped_into_wall:
|
|
bumped_into_wall = false
|
|
$Pivot.scale.x = -$Pivot.scale.x
|
|
elif is_on_wall() and is_on_floor():
|
|
velocity.y = JUMP_VELOCITY
|
|
|
|
if is_instance_valid(finish):
|
|
if not finish.is_on_screen():
|
|
$TargetArrow.show()
|
|
$TargetArrow.look_at(finish.global_position)
|
|
$TargetArrow/CutoutOfTargetArrow/TheCheese.rotation = -$TargetArrow.rotation
|
|
else:
|
|
$TargetArrow.hide()
|
|
if position.distance_to(finish.global_position) < 150.0:
|
|
win()
|
|
|
|
func _on_wall_detector_body_entered(body: Node2D) -> void:
|
|
if body is StaticBody2D:
|
|
bumped_into_wall = true
|
|
|
|
|
|
func die() -> void:
|
|
dead = true
|
|
$AnimationPlayer.play("disappear")
|
|
|
|
|
|
func win() -> void:
|
|
won = true
|
|
$AnimationPlayer.play("win")
|
|
|
|
|
|
func _on_animation_player_animation_finished(anim_name: StringName) -> void:
|
|
if anim_name == "disappear" or anim_name == "win":
|
|
position = orig_pos
|
|
modulate = Color(1.0, 1.0, 1.0, 1.0)
|
|
$AnimationPlayer.play("run")
|
|
dead = false
|
|
won = false
|
|
velocity = Vector2.ZERO
|
|
if anim_name == "win" and is_instance_valid(finish):
|
|
finish.queue_free()
|
|
has_won.emit()
|
|
|