104 lines
3 KiB
GDScript
104 lines
3 KiB
GDScript
class_name Level
|
|
extends Node3D
|
|
|
|
signal started_playing
|
|
signal gravity_change
|
|
signal ring_collected
|
|
signal completed
|
|
|
|
const gravity_strength_normal = 7
|
|
const gravity_strength_strong = gravity_strength_normal * 3
|
|
|
|
## Lowercase, spaceless name of the level
|
|
var id: String
|
|
var thumbnail: CompressedTexture2D
|
|
var player: Node3D
|
|
var music: Music
|
|
var rings: Array[Ring] = []
|
|
|
|
var finished_rings_count: int = 0
|
|
var velocity: float = 0.0
|
|
var has_started_playing: bool = false
|
|
|
|
func _init() -> void:
|
|
assert(len(id) > 0, self.name + " has no id!")
|
|
|
|
func _ready() -> void:
|
|
PhysicsServer3D.area_set_param(
|
|
get_viewport().find_world_3d().space,
|
|
PhysicsServer3D.AREA_PARAM_GRAVITY_VECTOR,
|
|
Vector3(0, 0, 0)
|
|
)
|
|
|
|
PhysicsServer3D.area_set_param(
|
|
get_viewport().find_world_3d().space,
|
|
PhysicsServer3D.AREA_PARAM_GRAVITY,
|
|
0
|
|
)
|
|
|
|
var children = get_children()
|
|
for child in children:
|
|
if is_instance_of(child, Music):
|
|
music = child
|
|
if child.name == "Player" and is_instance_of(child, Node3D):
|
|
player = child
|
|
assert(is_instance_valid(music), self.name + " has no music!")
|
|
|
|
var rings_node = get_node("Rings")
|
|
assert(is_instance_valid(rings_node), self.name + " has no Rings node!")
|
|
var rings_node_children = rings_node.get_children()
|
|
for ring in rings_node_children:
|
|
if is_instance_of(ring, Ring):
|
|
rings.push_back(ring)
|
|
ring.connect("collect_signal", collect_ring)
|
|
|
|
func collect_ring():
|
|
finished_rings_count = len(rings.filter(func(ring: Ring): return ring.collected))
|
|
ring_collected.emit()
|
|
|
|
if finished_rings_count >= len(rings):
|
|
completed.emit()
|
|
|
|
func _input(_event: InputEvent) -> void:
|
|
if Input.is_action_pressed("gravity_strong") or Input.is_action_just_released("gravity_strong"):
|
|
PhysicsServer3D.area_set_param(
|
|
get_viewport().find_world_3d().space,
|
|
PhysicsServer3D.AREA_PARAM_GRAVITY,
|
|
gravity_strength_strong if Input.is_action_pressed("gravity_strong") else gravity_strength_normal
|
|
)
|
|
|
|
var up := Input.is_action_just_pressed("gravity_up")
|
|
var left := Input.is_action_just_pressed("gravity_left")
|
|
var right := Input.is_action_just_pressed("gravity_right")
|
|
var down := Input.is_action_just_pressed("gravity_down")
|
|
|
|
if up or left or right or down:
|
|
if !has_started_playing:
|
|
has_started_playing = true
|
|
started_playing.emit()
|
|
PhysicsServer3D.area_set_param(
|
|
get_viewport().find_world_3d().space,
|
|
PhysicsServer3D.AREA_PARAM_GRAVITY,
|
|
gravity_strength_strong if Input.is_action_pressed("gravity_strong") else gravity_strength_normal
|
|
)
|
|
|
|
var direction: Vector3
|
|
if up:
|
|
direction = Vector3.UP
|
|
elif left:
|
|
direction = Vector3.LEFT
|
|
elif right:
|
|
direction = Vector3.RIGHT
|
|
elif down:
|
|
direction = Vector3.DOWN
|
|
|
|
if direction && direction != PhysicsServer3D.area_get_param(
|
|
get_viewport().find_world_3d().space,
|
|
PhysicsServer3D.AREA_PARAM_GRAVITY_VECTOR
|
|
):
|
|
PhysicsServer3D.area_set_param(
|
|
get_viewport().find_world_3d().space,
|
|
PhysicsServer3D.AREA_PARAM_GRAVITY_VECTOR,
|
|
direction
|
|
)
|
|
gravity_change.emit(direction)
|