DreamBall/levels/level.gd

99 lines
2.8 KiB
GDScript3
Raw Normal View History

class_name Level
2025-02-23 00:46:23 +01:00
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 music: Music
var rings: Array[Ring] = []
var finished_rings_count: int = 0
var velocity: float = 0.0
2025-02-23 00:46:23 +01:00
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
assert(is_instance_valid(music), self.name + " has no music!")
2025-02-23 00:46:23 +01:00
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)
2025-02-23 00:46:23 +01:00
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:
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)