Compare commits
6 commits
20250423.0
...
master
Author | SHA1 | Date | |
---|---|---|---|
2f646169fb | |||
edf99640cf | |||
709ce8eea3 | |||
38897c706a | |||
71441a9335 | |||
59bed24acd |
22 changed files with 870 additions and 452 deletions
|
@ -4,31 +4,38 @@
|
||||||
script/source = "class_name Player
|
script/source = "class_name Player
|
||||||
extends Node3D
|
extends Node3D
|
||||||
|
|
||||||
var velocity: Vector3 = Vector3(0, 0, 0)
|
signal velocity_change
|
||||||
|
var velocity := 0.0:
|
||||||
|
get: return velocity
|
||||||
|
set(value):
|
||||||
|
if value != velocity:
|
||||||
|
velocity_change.emit(value)
|
||||||
|
velocity = value
|
||||||
|
@onready var ball_position: Vector3 = $Sphere.position
|
||||||
|
|
||||||
func _physics_process(_delta: float) -> void:
|
func _physics_process(_delta: float) -> void:
|
||||||
|
ball_position = $Sphere.position
|
||||||
$SpotLightMain.position = $Sphere.position + Vector3(0, 5, 0)
|
$SpotLightMain.position = $Sphere.position + Vector3(0, 5, 0)
|
||||||
$SpotLightTop.position = $Sphere.position
|
$SpotLightTop.position = $Sphere.position
|
||||||
$SpotLightLeft.position = $Sphere.position
|
$SpotLightLeft.position = $Sphere.position
|
||||||
$SpotLightRight.position = $Sphere.position
|
$SpotLightRight.position = $Sphere.position
|
||||||
$SpotLightBottom.position = $Sphere.position
|
$SpotLightBottom.position = $Sphere.position
|
||||||
|
|
||||||
## Keep the ball at the center of the camera, at a distance
|
# Keep the ball at the center of the camera, at a distance
|
||||||
$Camera.position = $Sphere.position + Vector3(0, 0, 15)
|
$Camera.position = $Sphere.position + Vector3(0, 0, 15)
|
||||||
|
|
||||||
## Angle of the camera, so the player can see where the ball is going
|
# Angle of the camera, so the player can see where the ball is going
|
||||||
velocity = $Sphere.linear_velocity
|
velocity = abs($Sphere.linear_velocity.x) + abs($Sphere.linear_velocity.y)
|
||||||
var desired_x = max(min(velocity.y, 35), -35)
|
var desired_x = max(min($Sphere.linear_velocity.y, 35), -35)
|
||||||
var desired_y = max(min(-velocity.x, 50), -50)
|
var desired_y = max(min(-$Sphere.linear_velocity.x, 50), -50)
|
||||||
var difference_x = $Camera.rotation_degrees.x - desired_x
|
var difference_x = $Camera.rotation_degrees.x - desired_x
|
||||||
var difference_y = $Camera.rotation_degrees.y - desired_y
|
var difference_y = $Camera.rotation_degrees.y - desired_y
|
||||||
$Camera.rotation_degrees.x -= max(min(difference_x / 2, 3), -3)
|
$Camera.rotation_degrees.x -= max(min(difference_x / 2, 3), -3)
|
||||||
$Camera.rotation_degrees.y -= max(min(difference_y / 2, 3), -3)
|
$Camera.rotation_degrees.y -= max(min(difference_y / 2, 3), -3)
|
||||||
|
|
||||||
## FOV of the camera, so it unzooms more at higher velocities
|
# FOV of the camera, so it unzooms more at higher velocities
|
||||||
const default_fov = 75
|
const default_fov = 75
|
||||||
var total_velocity = abs(velocity.x) + abs(velocity.y)
|
$Camera.fov = default_fov + (velocity / 12)
|
||||||
$Camera.fov = default_fov + (total_velocity / 12)
|
|
||||||
"
|
"
|
||||||
|
|
||||||
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_vumbr"]
|
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_vumbr"]
|
||||||
|
|
|
@ -29,6 +29,7 @@ vertex_color_use_as_albedo = true
|
||||||
albedo_color = Color(0.212217, 0.468618, 0, 1)
|
albedo_color = Color(0.212217, 0.468618, 0, 1)
|
||||||
|
|
||||||
[node name="Tree" type="Node3D"]
|
[node name="Tree" type="Node3D"]
|
||||||
|
physics_interpolation_mode = 2
|
||||||
script = SubResource("GDScript_tbkod")
|
script = SubResource("GDScript_tbkod")
|
||||||
|
|
||||||
[node name="Dirt" type="CSGBox3D" parent="."]
|
[node name="Dirt" type="CSGBox3D" parent="."]
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
[gd_scene load_steps=8 format=3 uid="uid://dw0xl8644x166"]
|
[gd_scene load_steps=7 format=3 uid="uid://dw0xl8644x166"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://ctjugvy1v3y6b" path="res://graphics/arrow.svg" id="1_4mbho"]
|
[ext_resource type="Texture2D" uid="uid://ctjugvy1v3y6b" path="res://graphics/arrow.svg" id="1_4mbho"]
|
||||||
[ext_resource type="AudioStream" uid="uid://dmdbharecy448" path="res://sounds/gravity.ogg" id="2_5uwlw"]
|
[ext_resource type="AudioStream" uid="uid://dmdbharecy448" path="res://sounds/gravity.ogg" id="2_5uwlw"]
|
||||||
|
@ -6,66 +6,35 @@
|
||||||
[sub_resource type="GDScript" id="GDScript_3yq1l"]
|
[sub_resource type="GDScript" id="GDScript_3yq1l"]
|
||||||
script/source = "extends Control
|
script/source = "extends Control
|
||||||
|
|
||||||
var player_ready = false
|
@onready var direction_node: TextureRect = $Direction
|
||||||
const normal = 7
|
@onready var animation: AnimationPlayer = $Direction/AnimationPlayer
|
||||||
const stronger = normal * 3
|
@onready var audio: AudioStreamPlayer = $Direction/AudioStreamPlayer
|
||||||
|
|
||||||
func _input(_event: InputEvent) -> void:
|
|
||||||
if player_ready:
|
|
||||||
var grav = stronger if Input.is_action_pressed(\"gravity_strong\") else normal
|
|
||||||
PhysicsServer3D.area_set_param(get_viewport().find_world_3d().space, PhysicsServer3D.AREA_PARAM_GRAVITY, grav)
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="GDScript" id="GDScript_my602"]
|
|
||||||
script/source = "extends TextureRect
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
# set the indicator to be fully transparent when it first spawns
|
# set the indicator to be fully transparent when it first spawns
|
||||||
self.self_modulate = Color(1, 1, 1, 0)
|
direction_node.self_modulate = Color(1, 1, 1, 0)
|
||||||
|
|
||||||
func _input(ev: InputEvent) -> void:
|
func react_to_gravity_change(direction: Vector3) -> void:
|
||||||
if ev is InputEventKey and ev.is_pressed():
|
if direction == Vector3.UP:
|
||||||
var up := Input.is_action_just_pressed(\"gravity_up\")
|
direction_node.rotation_degrees = -90
|
||||||
var left := Input.is_action_just_pressed(\"gravity_left\")
|
audio.pitch_scale = 1.05
|
||||||
var right := Input.is_action_just_pressed(\"gravity_right\")
|
elif direction == Vector3.LEFT:
|
||||||
var down := Input.is_action_just_pressed(\"gravity_down\")
|
direction_node.rotation_degrees = -180
|
||||||
|
audio.pitch_scale = 1.02
|
||||||
if up or left or right or down:
|
elif direction == Vector3.RIGHT:
|
||||||
var direction = Vector3()
|
direction = Vector3.RIGHT
|
||||||
if up:
|
direction_node.rotation_degrees = 0
|
||||||
direction = Vector3.UP
|
audio.pitch_scale = 0.98
|
||||||
self.rotation_degrees = -90
|
elif direction == Vector3.DOWN:
|
||||||
$AudioStreamPlayer.pitch_scale = 1.05
|
direction_node.rotation_degrees = 90
|
||||||
elif left:
|
audio.pitch_scale = 0.95
|
||||||
direction = Vector3.LEFT
|
|
||||||
self.rotation_degrees = -180
|
if animation.is_playing():
|
||||||
$AudioStreamPlayer.pitch_scale = 1.02
|
animation.stop()
|
||||||
elif right:
|
animation.play(\"grow_fadeout\")
|
||||||
direction = Vector3.RIGHT
|
|
||||||
self.rotation_degrees = 0
|
if Settings.sound_on_gravity_change:
|
||||||
$AudioStreamPlayer.pitch_scale = 0.98
|
audio.play()
|
||||||
elif down:
|
|
||||||
direction = Vector3.DOWN
|
|
||||||
self.rotation_degrees = 90
|
|
||||||
$AudioStreamPlayer.pitch_scale = 0.95
|
|
||||||
|
|
||||||
if get_parent().player_ready == false or direction != PhysicsServer3D.area_get_param(
|
|
||||||
get_viewport().find_world_3d().space,
|
|
||||||
PhysicsServer3D.AREA_PARAM_GRAVITY_VECTOR
|
|
||||||
):
|
|
||||||
get_parent().player_ready = true
|
|
||||||
PhysicsServer3D.area_set_param(
|
|
||||||
get_viewport().find_world_3d().space,
|
|
||||||
PhysicsServer3D.AREA_PARAM_GRAVITY_VECTOR,
|
|
||||||
direction
|
|
||||||
)
|
|
||||||
|
|
||||||
if $AnimationPlayer.is_playing():
|
|
||||||
$AnimationPlayer.stop()
|
|
||||||
$AnimationPlayer.play(\"grow_fadeout\")
|
|
||||||
|
|
||||||
if Settings.sound_on_gravity_change:
|
|
||||||
$AudioStreamPlayer.play()
|
|
||||||
"
|
"
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_6rwl4"]
|
[sub_resource type="Animation" id="Animation_6rwl4"]
|
||||||
|
@ -137,6 +106,7 @@ anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
script = SubResource("GDScript_3yq1l")
|
script = SubResource("GDScript_3yq1l")
|
||||||
|
|
||||||
[node name="Direction" type="TextureRect" parent="."]
|
[node name="Direction" type="TextureRect" parent="."]
|
||||||
|
@ -155,8 +125,8 @@ grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
scale = Vector2(0.3, 0.3)
|
scale = Vector2(0.3, 0.3)
|
||||||
pivot_offset = Vector2(400, 400)
|
pivot_offset = Vector2(400, 400)
|
||||||
|
mouse_filter = 2
|
||||||
texture = ExtResource("1_4mbho")
|
texture = ExtResource("1_4mbho")
|
||||||
script = SubResource("GDScript_my602")
|
|
||||||
|
|
||||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="Direction"]
|
[node name="AnimationPlayer" type="AnimationPlayer" parent="Direction"]
|
||||||
libraries = {
|
libraries = {
|
66
gui/map.tscn
Normal file
66
gui/map.tscn
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
[gd_scene load_steps=2 format=3 uid="uid://bcxbw6wd54ksv"]
|
||||||
|
|
||||||
|
[sub_resource type="GDScript" id="GDScript_r4thc"]
|
||||||
|
script/source = "extends Control
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
$TemplateRing.hide()
|
||||||
|
|
||||||
|
func display_rings(player: Node3D, rings: Array[Ring]) -> void:
|
||||||
|
var old_rings_display := $Rings.get_children()
|
||||||
|
var difference := len(rings) - len(old_rings_display)
|
||||||
|
|
||||||
|
# Too many displayed, free them
|
||||||
|
for i in -difference:
|
||||||
|
old_rings_display[-(1 + i)].queue_free()
|
||||||
|
# Not enough displayed, create some
|
||||||
|
for i in difference:
|
||||||
|
var new_child := $TemplateRing.duplicate()
|
||||||
|
new_child.name = \"Ring\" + str(i + 1)
|
||||||
|
new_child.show()
|
||||||
|
$Rings.add_child(new_child)
|
||||||
|
|
||||||
|
var rings_display := $Rings.get_children()
|
||||||
|
var center: Vector2i = get_viewport().size / 2
|
||||||
|
for i in len(rings):
|
||||||
|
rings_display[i].color = rings[i].material.albedo_color
|
||||||
|
rings_display[i].rotation = rings[i].rotation.z
|
||||||
|
rings_display[i].position.x = center.x + rings[i].position.x - player.ball_position.x
|
||||||
|
rings_display[i].position.y = center.y - rings[i].position.y + player.ball_position.y
|
||||||
|
|
||||||
|
if rings[i].collected:
|
||||||
|
rings_display[i].scale = $TemplateRing.scale * 2 * min(4, max(1, rings[i].scale.x))
|
||||||
|
else:
|
||||||
|
rings_display[i].scale = $TemplateRing.scale * 3 * min(4, max(1, rings[i].scale.x))
|
||||||
|
"
|
||||||
|
|
||||||
|
[node name="Map" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = SubResource("GDScript_r4thc")
|
||||||
|
|
||||||
|
[node name="ColorRect" type="ColorRect" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
color = Color(1, 0, 1, 0.0392157)
|
||||||
|
|
||||||
|
[node name="Rings" type="Control" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="TemplateRing" type="ColorRect" parent="."]
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 2.0
|
||||||
|
offset_bottom = 2.0
|
|
@ -8,13 +8,9 @@ script/source = "extends VBoxContainer
|
||||||
var enabled := false:
|
var enabled := false:
|
||||||
get: return enabled
|
get: return enabled
|
||||||
set(value):
|
set(value):
|
||||||
|
if enabled == value:
|
||||||
|
return
|
||||||
enabled = value
|
enabled = value
|
||||||
if value == true:
|
|
||||||
var save_file = SaveFiles.read(SaveFiles.selected_file)
|
|
||||||
if save_file.has(\"played_for\") and save_file.played_for is float:
|
|
||||||
seconds_spent_total = save_file.played_for
|
|
||||||
else:
|
|
||||||
seconds_spent_total = 0.0
|
|
||||||
if value == false:
|
if value == false:
|
||||||
$AnimationPlayer.play(\"scale_linear\")
|
$AnimationPlayer.play(\"scale_linear\")
|
||||||
await get_tree().create_timer($AnimationPlayer.current_animation_length).timeout
|
await get_tree().create_timer($AnimationPlayer.current_animation_length).timeout
|
||||||
|
@ -31,10 +27,13 @@ var seconds_spent_level_attempt := 0.0:
|
||||||
seconds_spent_level_attempt = value
|
seconds_spent_level_attempt = value
|
||||||
$Level.text = \"Level: \" + seconds_to_readable(seconds_spent_level_attempt)
|
$Level.text = \"Level: \" + seconds_to_readable(seconds_spent_level_attempt)
|
||||||
|
|
||||||
func _ready():
|
func _on_visibility_changed() -> void:
|
||||||
var data = SaveFiles.read(SaveFiles.selected_file)
|
if self.visible and len(SaveFiles.selected_file):
|
||||||
if data.has(\"played_for\") and data.played_for is float:
|
var save_file = SaveFiles.read(SaveFiles.selected_file)
|
||||||
seconds_spent_total = data.played_for
|
if save_file.has(\"played_for\") and save_file.played_for is float:
|
||||||
|
seconds_spent_total = save_file.played_for
|
||||||
|
else:
|
||||||
|
seconds_spent_total = 0.0
|
||||||
|
|
||||||
func seconds_to_readable(seconds: float) -> String:
|
func seconds_to_readable(seconds: float) -> String:
|
||||||
var minutes: int = floor(seconds / 60)
|
var minutes: int = floor(seconds / 60)
|
||||||
|
@ -77,23 +76,6 @@ tracks/0/keys = {
|
||||||
"values": [Vector2(1, 1)]
|
"values": [Vector2(1, 1)]
|
||||||
}
|
}
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_2a86r"]
|
|
||||||
resource_name = "scale_linear"
|
|
||||||
length = 0.25
|
|
||||||
step = 0.25
|
|
||||||
tracks/0/type = "value"
|
|
||||||
tracks/0/imported = false
|
|
||||||
tracks/0/enabled = true
|
|
||||||
tracks/0/path = NodePath(".:scale")
|
|
||||||
tracks/0/interp = 1
|
|
||||||
tracks/0/loop_wrap = true
|
|
||||||
tracks/0/keys = {
|
|
||||||
"times": PackedFloat32Array(0, 0.25),
|
|
||||||
"transitions": PackedFloat32Array(1, 1),
|
|
||||||
"update": 0,
|
|
||||||
"values": [Vector2(1, 1), Vector2(1.2, 1.2)]
|
|
||||||
}
|
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_houb3"]
|
[sub_resource type="Animation" id="Animation_houb3"]
|
||||||
resource_name = "scale_cubic"
|
resource_name = "scale_cubic"
|
||||||
length = 0.25
|
length = 0.25
|
||||||
|
@ -111,6 +93,23 @@ tracks/0/keys = {
|
||||||
"values": [Vector2(1, 1), Vector2(1.2, 1.2)]
|
"values": [Vector2(1, 1), Vector2(1.2, 1.2)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_2a86r"]
|
||||||
|
resource_name = "scale_linear"
|
||||||
|
length = 0.25
|
||||||
|
step = 0.25
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath(".:scale")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 0.25),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector2(1, 1), Vector2(1.2, 1.2)]
|
||||||
|
}
|
||||||
|
|
||||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_jmgpn"]
|
[sub_resource type="AnimationLibrary" id="AnimationLibrary_jmgpn"]
|
||||||
_data = {
|
_data = {
|
||||||
&"RESET": SubResource("Animation_m1tld"),
|
&"RESET": SubResource("Animation_m1tld"),
|
||||||
|
@ -120,27 +119,24 @@ _data = {
|
||||||
|
|
||||||
[node name="Timer" type="VBoxContainer"]
|
[node name="Timer" type="VBoxContainer"]
|
||||||
process_mode = 3
|
process_mode = 3
|
||||||
anchors_preset = 15
|
offset_right = 315.0
|
||||||
anchor_right = 1.0
|
offset_bottom = 85.0
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_right = -992.0
|
|
||||||
offset_bottom = -563.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
theme_override_constants/separation = -5
|
theme_override_constants/separation = -5
|
||||||
script = SubResource("GDScript_q235s")
|
script = SubResource("GDScript_q235s")
|
||||||
|
|
||||||
[node name="Total" type="Label" parent="."]
|
[node name="Total" type="Label" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Total timer"
|
text = "Total: 0:00.000"
|
||||||
label_settings = SubResource("LabelSettings_m1tld")
|
label_settings = SubResource("LabelSettings_m1tld")
|
||||||
|
|
||||||
[node name="Level" type="Label" parent="."]
|
[node name="Level" type="Label" parent="."]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Level timer"
|
text = "Level: 0:00.000"
|
||||||
label_settings = SubResource("LabelSettings_2a86r")
|
label_settings = SubResource("LabelSettings_2a86r")
|
||||||
|
|
||||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||||
libraries = {
|
libraries = {
|
||||||
&"": SubResource("AnimationLibrary_jmgpn")
|
&"": SubResource("AnimationLibrary_jmgpn")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[connection signal="visibility_changed" from="." to="." method="_on_visibility_changed"]
|
||||||
|
|
195
index.tscn
195
index.tscn
|
@ -1,24 +1,26 @@
|
||||||
[gd_scene load_steps=7 format=3 uid="uid://ccgnnif026wb4"]
|
[gd_scene load_steps=8 format=3 uid="uid://ccgnnif026wb4"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://xd3nsiglcdfc" path="res://gui/timer.tscn" id="1_356j3"]
|
[ext_resource type="PackedScene" uid="uid://xd3nsiglcdfc" path="res://gui/timer.tscn" id="1_356j3"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dw0xl8644x166" path="res://gui/gravity.tscn" id="1_ir7so"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cckeamgkt8bqo" path="res://gui/speed.tscn" id="2_2gn6w"]
|
[ext_resource type="PackedScene" uid="uid://cckeamgkt8bqo" path="res://gui/speed.tscn" id="2_2gn6w"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bcxbw6wd54ksv" path="res://gui/map.tscn" id="2_d1yoc"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cn55m5dqo3m6u" path="res://gui/rings.tscn" id="3_mbj17"]
|
[ext_resource type="PackedScene" uid="uid://cn55m5dqo3m6u" path="res://gui/rings.tscn" id="3_mbj17"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dkxtwpcy4moyo" path="res://menus/pause_menu.tscn" id="4_3bfj3"]
|
[ext_resource type="PackedScene" uid="uid://dkxtwpcy4moyo" path="res://menus/pause_menu.tscn" id="4_3bfj3"]
|
||||||
|
|
||||||
[sub_resource type="GDScript" id="GDScript_8n212"]
|
[sub_resource type="GDScript" id="GDScript_8n212"]
|
||||||
script/source = "extends Node
|
script/source = "extends Node
|
||||||
|
|
||||||
var playing: bool = false
|
var playing := false
|
||||||
var changing_level: bool = false
|
var changing_level := false
|
||||||
|
|
||||||
var current_level_int: int = 0
|
var main_menu: Node
|
||||||
var levels = [
|
var current_level: Level
|
||||||
preload(\"res://levels/base/level.tscn\"),
|
var current_level_scene: PackedScene
|
||||||
preload(\"res://levels/forest/level.tscn\"),
|
|
||||||
preload(\"res://levels/night/level.tscn\"),
|
|
||||||
]
|
|
||||||
var area_resource = preload(\"res://menus/main/area.tscn\")
|
|
||||||
|
|
||||||
|
const res_main_menu = preload(\"res://menus/main/main_menu.tscn\")
|
||||||
|
|
||||||
|
@onready var gui_gravity := $GUI/Gravity
|
||||||
|
@onready var gui_map := $GUI/Map
|
||||||
@onready var gui_timer := $GUI/TopLeft/Timer
|
@onready var gui_timer := $GUI/TopLeft/Timer
|
||||||
@onready var gui_speed := $GUI/TopRight/Speed
|
@onready var gui_speed := $GUI/TopRight/Speed
|
||||||
@onready var gui_rings := $GUI/BottomRight/Rings
|
@onready var gui_rings := $GUI/BottomRight/Rings
|
||||||
|
@ -31,8 +33,6 @@ func _ready() -> void:
|
||||||
$DevInfos.text += \"build \" + ProjectSettings.get_setting(\"application/config/version\") + \" (\" + OS.get_name() + \")\"
|
$DevInfos.text += \"build \" + ProjectSettings.get_setting(\"application/config/version\") + \" (\" + OS.get_name() + \")\"
|
||||||
|
|
||||||
## Hide UI stuff that shouldn't be visible until later in the game
|
## Hide UI stuff that shouldn't be visible until later in the game
|
||||||
$VictoryScreen.hide()
|
|
||||||
$GUI.hide()
|
|
||||||
pause_menu.hide()
|
pause_menu.hide()
|
||||||
|
|
||||||
## Connect to necessary signals
|
## Connect to necessary signals
|
||||||
|
@ -40,107 +40,84 @@ func _ready() -> void:
|
||||||
pause_menu.connect(\"request_fullscreen\", fullscreen_game)
|
pause_menu.connect(\"request_fullscreen\", fullscreen_game)
|
||||||
pause_menu.connect(\"request_restart\", restart_level)
|
pause_menu.connect(\"request_restart\", restart_level)
|
||||||
|
|
||||||
launch_area()
|
set_main_menu()
|
||||||
|
|
||||||
func launch_area():
|
func set_main_menu() -> void:
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||||
var area := area_resource.instantiate()
|
$GUI.hide()
|
||||||
area.connect(\"request_start\", start_game)
|
|
||||||
$Levels.add_child(area)
|
## If no main menu exists yet, create one
|
||||||
|
if !is_instance_valid(main_menu):
|
||||||
|
main_menu = res_main_menu.instantiate()
|
||||||
|
main_menu.connect(\"request_play_level\", start_level)
|
||||||
|
add_child(main_menu)
|
||||||
|
|
||||||
## Get all the levels that are currently being played!
|
func start_level(level: Level, scene: PackedScene) -> void:
|
||||||
## In theory, there should ever be only zero or one,
|
if is_instance_valid(current_level):
|
||||||
## but it turns out it's more simple to handle things by using Arrays.
|
current_level.queue_free()
|
||||||
func get_current_levels() -> Array[Level]:
|
if is_instance_valid(main_menu) and self.is_ancestor_of(main_menu):
|
||||||
var children := $Levels.get_children(true)
|
self.remove_child(main_menu)
|
||||||
var current_levels: Array[Level] = []
|
|
||||||
for child in children:
|
current_level = level
|
||||||
if is_instance_of(child, Level):
|
current_level_scene = scene
|
||||||
current_levels.push_back(child)
|
add_child(current_level)
|
||||||
return current_levels
|
|
||||||
|
current_level.connect(\"started_playing\", func(): gui_timer.enabled = true)
|
||||||
func start_level(level_scene: PackedScene) -> void:
|
current_level.connect(\"gravity_change\", gui_gravity.react_to_gravity_change)
|
||||||
$VictoryScreen.hide()
|
current_level.connect(\"completed\", finish_current_level)
|
||||||
var level = level_scene.instantiate()
|
current_level.connect(\"ring_collected\", func():
|
||||||
$Levels.add_child(level)
|
gui_rings.remaining_rings = len(current_level.rings) - current_level.finished_rings_count
|
||||||
level.connect(\"completed\", stop_level)
|
|
||||||
level.connect(\"ring_collected\", func():
|
|
||||||
gui_rings.remaining_rings = len(level.rings) - level.finished_rings_count
|
|
||||||
)
|
)
|
||||||
gui_rings.remaining_rings = len(level.rings) - level.finished_rings_count
|
gui_rings.remaining_rings = len(current_level.rings) - current_level.finished_rings_count
|
||||||
|
|
||||||
|
$GUI.show()
|
||||||
|
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
|
||||||
|
pause_game(false)
|
||||||
|
|
||||||
playing = true
|
playing = true
|
||||||
PhysicsServer3D.area_set_param(
|
|
||||||
get_viewport().find_world_3d().space,
|
|
||||||
PhysicsServer3D.AREA_PARAM_GRAVITY_VECTOR,
|
|
||||||
Vector3.DOWN
|
|
||||||
)
|
|
||||||
changing_level = false
|
changing_level = false
|
||||||
gui_timer.seconds_spent_level_attempt = 0.0
|
gui_timer.seconds_spent_level_attempt = 0.0
|
||||||
gui_timer.enabled = true
|
|
||||||
|
|
||||||
func stop_level() -> void:
|
func finish_current_level() -> void:
|
||||||
gui_timer.enabled = false
|
gui_timer.enabled = false
|
||||||
PhysicsServer3D.area_set_param(get_viewport().find_world_3d().space, PhysicsServer3D.AREA_PARAM_GRAVITY, 1)
|
PhysicsServer3D.area_set_param(get_viewport().find_world_3d().space, PhysicsServer3D.AREA_PARAM_GRAVITY, 0.5)
|
||||||
playing = false
|
playing = false
|
||||||
changing_level = true
|
changing_level = true
|
||||||
|
|
||||||
SaveFiles.change_property(\"played_for\", gui_timer.seconds_spent_total, SaveFiles.selected_file)
|
SaveFiles.change_property(\"played_for\", gui_timer.seconds_spent_total, SaveFiles.selected_file)
|
||||||
var save_file_data = SaveFiles.read(SaveFiles.selected_file)
|
var save_file_data = SaveFiles.read(SaveFiles.selected_file)
|
||||||
var property_name := \"best_time_for_level_\" + str(current_level_int)
|
var property_name := current_level.id + \"_best_time\"
|
||||||
if !save_file_data.has(property_name) or save_file_data[property_name] is not float or save_file_data[property_name] > gui_timer.seconds_spent_level_attempt:
|
if !save_file_data.has(property_name) or save_file_data[property_name] is not float or save_file_data[property_name] > gui_timer.seconds_spent_level_attempt:
|
||||||
SaveFiles.change_property(property_name, gui_timer.seconds_spent_level_attempt, SaveFiles.selected_file)
|
SaveFiles.change_property(property_name, gui_timer.seconds_spent_level_attempt, SaveFiles.selected_file)
|
||||||
|
|
||||||
var current_levels = get_current_levels()
|
current_level.music.fadeOut(2)
|
||||||
for level in current_levels:
|
|
||||||
level.music.fadeOut(2)
|
|
||||||
await get_tree().create_timer(2).timeout
|
|
||||||
level.queue_free()
|
|
||||||
|
|
||||||
if len(levels) > current_level_int + 1:
|
|
||||||
current_level_int += 1
|
|
||||||
start_level(levels[current_level_int])
|
|
||||||
else:
|
|
||||||
win_game()
|
|
||||||
|
|
||||||
func win_game() -> void:
|
|
||||||
$VictoryScreen.show()
|
|
||||||
await get_tree().create_timer(2).timeout
|
await get_tree().create_timer(2).timeout
|
||||||
launch_area()
|
current_level.queue_free()
|
||||||
$VictoryScreen.hide()
|
|
||||||
|
set_main_menu()
|
||||||
|
|
||||||
func restart_level() -> void:
|
func restart_level() -> void:
|
||||||
var current_levels := get_current_levels()
|
gui_timer.enabled = false
|
||||||
if len(current_levels) && !changing_level:
|
if !current_level or changing_level:
|
||||||
pause_game(false)
|
return
|
||||||
changing_level = true
|
if current_level_scene is not PackedScene:
|
||||||
|
print(\"Tried to restart the level despite not having the level scene\")
|
||||||
for level in current_levels:
|
return
|
||||||
level.queue_free()
|
SaveFiles.change_property(\"played_for\", gui_timer.seconds_spent_total, SaveFiles.selected_file)
|
||||||
start_level(levels[current_level_int])
|
start_level(current_level_scene.instantiate(), current_level_scene)
|
||||||
|
|
||||||
func start_game() -> void:
|
|
||||||
current_level_int = 0
|
|
||||||
|
|
||||||
var current_levels = $Levels.get_children(true)
|
|
||||||
for level in current_levels:
|
|
||||||
level.queue_free()
|
|
||||||
|
|
||||||
$GUI.show()
|
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
|
|
||||||
start_level(levels[current_level_int])
|
|
||||||
|
|
||||||
func pause_game(to_pause: bool) -> void:
|
func pause_game(to_pause: bool) -> void:
|
||||||
if !len(get_current_levels()) or changing_level:
|
if !is_instance_valid(current_level) or changing_level:
|
||||||
return
|
return
|
||||||
|
|
||||||
SaveFiles.change_property(\"played_for\", gui_timer.seconds_spent_total, SaveFiles.selected_file)
|
|
||||||
if to_pause:
|
if to_pause:
|
||||||
$Levels.process_mode = Node.PROCESS_MODE_DISABLED
|
SaveFiles.change_property(\"played_for\", gui_timer.seconds_spent_total, SaveFiles.selected_file)
|
||||||
|
current_level.process_mode = Node.PROCESS_MODE_DISABLED
|
||||||
playing = false
|
playing = false
|
||||||
pause_menu.show()
|
pause_menu.show()
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||||
else:
|
else:
|
||||||
$Levels.process_mode = Node.PROCESS_MODE_INHERIT
|
current_level.process_mode = Node.PROCESS_MODE_INHERIT
|
||||||
playing = true
|
playing = true
|
||||||
pause_menu.hide()
|
pause_menu.hide()
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
|
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
|
||||||
|
@ -153,12 +130,16 @@ func fullscreen_game() -> void:
|
||||||
DisplayServer.window_set_mode(DisplayServer.WindowMode.WINDOW_MODE_WINDOWED)
|
DisplayServer.window_set_mode(DisplayServer.WindowMode.WINDOW_MODE_WINDOWED)
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
var current_levels = get_current_levels()
|
if is_instance_valid(current_level):
|
||||||
if len(current_levels):
|
|
||||||
var current_level = current_levels[0]
|
|
||||||
gui_speed.ball_velocity = current_level.velocity
|
gui_speed.ball_velocity = current_level.velocity
|
||||||
|
if Input.is_action_pressed(\"display_map\"):
|
||||||
|
gui_map.display_rings(current_level.player, current_level.rings)
|
||||||
|
|
||||||
func _input(_event: InputEvent) -> void:
|
func _input(_event: InputEvent) -> void:
|
||||||
|
if Input.is_action_just_released(\"display_map\"):
|
||||||
|
gui_map.hide()
|
||||||
|
if Input.is_action_just_pressed(\"display_map\"):
|
||||||
|
gui_map.show()
|
||||||
if Input.is_action_just_pressed(\"restart_level\"):
|
if Input.is_action_just_pressed(\"restart_level\"):
|
||||||
restart_level()
|
restart_level()
|
||||||
|
|
||||||
|
@ -166,11 +147,6 @@ func _on_btn_quit_pressed() -> void:
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
"
|
"
|
||||||
|
|
||||||
[sub_resource type="LabelSettings" id="LabelSettings_1bs00"]
|
|
||||||
font_size = 160
|
|
||||||
outline_size = 20
|
|
||||||
outline_color = Color(0, 0, 0, 1)
|
|
||||||
|
|
||||||
[node name="Game" type="Node"]
|
[node name="Game" type="Node"]
|
||||||
script = SubResource("GDScript_8n212")
|
script = SubResource("GDScript_8n212")
|
||||||
|
|
||||||
|
@ -181,7 +157,14 @@ anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
mouse_filter = 1
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="Gravity" parent="GUI" instance=ExtResource("1_ir7so")]
|
||||||
|
layout_mode = 1
|
||||||
|
|
||||||
|
[node name="Map" parent="GUI" instance=ExtResource("2_d1yoc")]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 1
|
||||||
|
|
||||||
[node name="TopLeft" type="MarginContainer" parent="GUI"]
|
[node name="TopLeft" type="MarginContainer" parent="GUI"]
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
|
@ -226,30 +209,6 @@ theme_override_constants/margin_bottom = 15
|
||||||
[node name="Rings" parent="GUI/BottomRight" instance=ExtResource("3_mbj17")]
|
[node name="Rings" parent="GUI/BottomRight" instance=ExtResource("3_mbj17")]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
|
||||||
[node name="VictoryScreen" type="Control" parent="."]
|
|
||||||
layout_mode = 3
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="VictoryScreen"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
text = "YOU WON!"
|
|
||||||
label_settings = SubResource("LabelSettings_1bs00")
|
|
||||||
horizontal_alignment = 1
|
|
||||||
vertical_alignment = 1
|
|
||||||
|
|
||||||
[node name="Levels" type="Node" parent="."]
|
|
||||||
|
|
||||||
[node name="PauseMenu" parent="." instance=ExtResource("4_3bfj3")]
|
|
||||||
|
|
||||||
[node name="DevInfos" type="Label" parent="."]
|
[node name="DevInfos" type="Label" parent="."]
|
||||||
anchors_preset = 12
|
anchors_preset = 12
|
||||||
anchor_top = 1.0
|
anchor_top = 1.0
|
||||||
|
@ -259,3 +218,5 @@ offset_top = -23.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 0
|
grow_vertical = 0
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
|
||||||
|
[node name="PauseMenu" parent="." instance=ExtResource("4_3bfj3")]
|
||||||
|
|
|
@ -1,12 +1,21 @@
|
||||||
[gd_scene load_steps=12 format=3 uid="uid://ovtknjyj83gh"]
|
[gd_scene load_steps=11 format=3 uid="uid://ovtknjyj83gh"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://w3fetao1pegm" path="res://levels/level.gd" id="1_rj40i"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_b00jj"]
|
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_b00jj"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="3_hel5x"]
|
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="3_hel5x"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dw0xl8644x166" path="res://elements/gravity.tscn" id="3_muudg"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://c77bli40240nk" path="res://elements/sign.tscn" id="4_atq6y"]
|
[ext_resource type="PackedScene" uid="uid://c77bli40240nk" path="res://elements/sign.tscn" id="4_atq6y"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dnuakh7n3fuij" path="res://levels/base/music.tscn" id="4_uq42r"]
|
[ext_resource type="PackedScene" uid="uid://dnuakh7n3fuij" path="res://levels/base/music.tscn" id="4_uq42r"]
|
||||||
|
|
||||||
|
[sub_resource type="GDScript" id="GDScript_1yugx"]
|
||||||
|
script/source = "extends Level
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
self.id = \"base\"
|
||||||
|
|
||||||
|
func _on_player_velocity_change(new_velocity: float) -> void:
|
||||||
|
self.velocity = new_velocity
|
||||||
|
self.music.adaptInstrumentsToVelocity(new_velocity * 1.5)
|
||||||
|
"
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_hs6gw"]
|
[sub_resource type="Gradient" id="Gradient_hs6gw"]
|
||||||
|
|
||||||
[sub_resource type="GradientTexture2D" id="GradientTexture2D_hyysp"]
|
[sub_resource type="GradientTexture2D" id="GradientTexture2D_hyysp"]
|
||||||
|
@ -30,11 +39,9 @@ ambient_light_color = Color(1, 1, 1, 1)
|
||||||
reflected_light_source = 2
|
reflected_light_source = 2
|
||||||
|
|
||||||
[node name="Base" type="Node3D"]
|
[node name="Base" type="Node3D"]
|
||||||
script = ExtResource("1_rj40i")
|
script = SubResource("GDScript_1yugx")
|
||||||
metadata/_custom_type_script = "uid://w3fetao1pegm"
|
metadata/_custom_type_script = "uid://w3fetao1pegm"
|
||||||
|
|
||||||
[node name="Gravity" parent="." instance=ExtResource("3_muudg")]
|
|
||||||
|
|
||||||
[node name="Environment" type="WorldEnvironment" parent="."]
|
[node name="Environment" type="WorldEnvironment" parent="."]
|
||||||
environment = SubResource("Environment_y0yoy")
|
environment = SubResource("Environment_y0yoy")
|
||||||
|
|
||||||
|
@ -155,6 +162,8 @@ transform = Transform3D(0.0172464, 0.899835, 0, -0.899835, 0.0172464, 0, 0, 0, 0
|
||||||
[node name="Ring13" parent="Rings" instance=ExtResource("3_hel5x")]
|
[node name="Ring13" parent="Rings" instance=ExtResource("3_hel5x")]
|
||||||
transform = Transform3D(0.0114976, 0.59989, 0, -0.59989, 0.0114976, 0, 0, 0, 0.6, -414.274, 8.64172, 0)
|
transform = Transform3D(0.0114976, 0.59989, 0, -0.59989, 0.0114976, 0, 0, 0, 0.6, -414.274, 8.64172, 0)
|
||||||
|
|
||||||
|
[connection signal="velocity_change" from="Player" to="." method="_on_player_velocity_change"]
|
||||||
|
|
||||||
[editable path="Signs/Sign"]
|
[editable path="Signs/Sign"]
|
||||||
[editable path="Signs/Sign7"]
|
[editable path="Signs/Sign7"]
|
||||||
[editable path="Signs/Sign2"]
|
[editable path="Signs/Sign2"]
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
[gd_scene load_steps=11 format=3 uid="uid://0re2mcnpub4e"]
|
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://w3fetao1pegm" path="res://levels/level.gd" id="1_scm0b"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://dw0xl8644x166" path="res://elements/gravity.tscn" id="2_fo4i1"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://drfy3vhe6skp1" path="res://levels/night/music.tscn" id="4_qr8kk"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="5_j5vh3"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="6_st6rs"]
|
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_x6q8u"]
|
|
||||||
|
|
||||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_lu6nv"]
|
|
||||||
gradient = SubResource("Gradient_x6q8u")
|
|
||||||
|
|
||||||
[sub_resource type="PanoramaSkyMaterial" id="PanoramaSkyMaterial_4yv3y"]
|
|
||||||
panorama = SubResource("GradientTexture1D_lu6nv")
|
|
||||||
|
|
||||||
[sub_resource type="Sky" id="Sky_ys2yp"]
|
|
||||||
sky_material = SubResource("PanoramaSkyMaterial_4yv3y")
|
|
||||||
|
|
||||||
[sub_resource type="Environment" id="Environment_8o42c"]
|
|
||||||
background_mode = 1
|
|
||||||
sky = SubResource("Sky_ys2yp")
|
|
||||||
ambient_light_source = 2
|
|
||||||
ambient_light_color = Color(1, 1, 1, 1)
|
|
||||||
reflected_light_source = 2
|
|
||||||
|
|
||||||
[node name="Demo" type="Node3D"]
|
|
||||||
script = ExtResource("1_scm0b")
|
|
||||||
metadata/_custom_type_script = "uid://w3fetao1pegm"
|
|
||||||
|
|
||||||
[node name="Gravity" parent="." instance=ExtResource("2_fo4i1")]
|
|
||||||
|
|
||||||
[node name="Environment" type="WorldEnvironment" parent="."]
|
|
||||||
environment = SubResource("Environment_8o42c")
|
|
||||||
|
|
||||||
[node name="Music" parent="." instance=ExtResource("4_qr8kk")]
|
|
||||||
|
|
||||||
[node name="Player" parent="." instance=ExtResource("5_j5vh3")]
|
|
||||||
|
|
||||||
[node name="Rings" type="Node3D" parent="."]
|
|
||||||
|
|
||||||
[node name="Ring" parent="Rings" instance=ExtResource("6_st6rs")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 15.6731, -50)
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="Ring2" parent="Rings" instance=ExtResource("6_st6rs")]
|
|
||||||
transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 10, -10, 0)
|
|
||||||
|
|
||||||
[node name="Ring3" parent="Rings" instance=ExtResource("6_st6rs")]
|
|
||||||
transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, -10, -10, 0)
|
|
|
@ -1,13 +1,32 @@
|
||||||
[gd_scene load_steps=11 format=3 uid="uid://e1761h6d522a"]
|
[gd_scene load_steps=10 format=3 uid="uid://e1761h6d522a"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://w3fetao1pegm" path="res://levels/level.gd" id="1_fdxcj"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://dw0xl8644x166" path="res://elements/gravity.tscn" id="2_gxmta"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_mjogx"]
|
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_mjogx"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cakmsiye3hjfe" path="res://levels/forest/music.tscn" id="3_n1xsx"]
|
[ext_resource type="PackedScene" uid="uid://cakmsiye3hjfe" path="res://levels/forest/music.tscn" id="3_n1xsx"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="4_p8yhq"]
|
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="4_p8yhq"]
|
||||||
[ext_resource type="PackedScene" uid="uid://da6lkdiskdh8v" path="res://elements/tree.tscn" id="6_1e514"]
|
[ext_resource type="PackedScene" uid="uid://da6lkdiskdh8v" path="res://elements/tree.tscn" id="6_1e514"]
|
||||||
[ext_resource type="PackedScene" uid="uid://c77bli40240nk" path="res://elements/sign.tscn" id="6_ifogr"]
|
[ext_resource type="PackedScene" uid="uid://c77bli40240nk" path="res://elements/sign.tscn" id="6_ifogr"]
|
||||||
|
|
||||||
|
[sub_resource type="GDScript" id="GDScript_mqwxc"]
|
||||||
|
script/source = "extends Level
|
||||||
|
|
||||||
|
var cycle := 0
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
self.id = \"forest\"
|
||||||
|
self.thumbnail = load(\"res://levels/forest/thumbnail.png\")
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
var moving_ring: Ring = $Rings/Ring18
|
||||||
|
if !moving_ring.collected:
|
||||||
|
if moving_ring.position.y < 55 or moving_ring.position.y > 65:
|
||||||
|
cycle += 1
|
||||||
|
moving_ring.position.y += 0.5 if cycle % 2 else -0.5
|
||||||
|
|
||||||
|
func _on_player_velocity_change(new_velocity: float) -> void:
|
||||||
|
self.velocity = new_velocity
|
||||||
|
self.music.adaptInstrumentsToVelocity(new_velocity)
|
||||||
|
"
|
||||||
|
|
||||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_grcut"]
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_grcut"]
|
||||||
sky_top_color = Color(0, 0.504542, 0.579919, 1)
|
sky_top_color = Color(0, 0.504542, 0.579919, 1)
|
||||||
sky_horizon_color = Color(9.62615e-08, 0.776269, 0.496436, 1)
|
sky_horizon_color = Color(9.62615e-08, 0.776269, 0.496436, 1)
|
||||||
|
@ -29,11 +48,9 @@ ambient_light_color = Color(1, 1, 1, 1)
|
||||||
reflected_light_source = 2
|
reflected_light_source = 2
|
||||||
|
|
||||||
[node name="Forest" type="Node3D"]
|
[node name="Forest" type="Node3D"]
|
||||||
script = ExtResource("1_fdxcj")
|
script = SubResource("GDScript_mqwxc")
|
||||||
metadata/_custom_type_script = "uid://w3fetao1pegm"
|
metadata/_custom_type_script = "uid://w3fetao1pegm"
|
||||||
|
|
||||||
[node name="Gravity" parent="." instance=ExtResource("2_gxmta")]
|
|
||||||
|
|
||||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
transform = Transform3D(-0.920505, 0.195366, -0.338383, 0, 0.866025, 0.5, 0.390731, 0.460252, -0.797181, 0, 0, 0)
|
transform = Transform3D(-0.920505, 0.195366, -0.338383, 0, 0.866025, 0.5, 0.390731, 0.460252, -0.797181, 0, 0, 0)
|
||||||
shadow_enabled = true
|
shadow_enabled = true
|
||||||
|
@ -261,4 +278,6 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -218.208, 206.247, 0)
|
||||||
[node name="Ring23" parent="Rings" instance=ExtResource("4_p8yhq")]
|
[node name="Ring23" parent="Rings" instance=ExtResource("4_p8yhq")]
|
||||||
transform = Transform3D(0.939693, 0.34202, 0, -0.34202, 0.939693, 0, 0, 0, 1, -1018.15, -96.9134, 0)
|
transform = Transform3D(0.939693, 0.34202, 0, -0.34202, 0.939693, 0, 0, 0, 1, -1018.15, -96.9134, 0)
|
||||||
|
|
||||||
|
[connection signal="velocity_change" from="Player" to="." method="_on_player_velocity_change"]
|
||||||
|
|
||||||
[editable path="Sign"]
|
[editable path="Sign"]
|
||||||
|
|
BIN
levels/forest/thumbnail.png
Normal file
BIN
levels/forest/thumbnail.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 195 KiB |
34
levels/forest/thumbnail.png.import
Normal file
34
levels/forest/thumbnail.png.import
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
[remap]
|
||||||
|
|
||||||
|
importer="texture"
|
||||||
|
type="CompressedTexture2D"
|
||||||
|
uid="uid://dhyxogc13hnbe"
|
||||||
|
path="res://.godot/imported/thumbnail.png-6909560b6205778a3cb325a584af7ca5.ctex"
|
||||||
|
metadata={
|
||||||
|
"vram_texture": false
|
||||||
|
}
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
|
||||||
|
source_file="res://levels/forest/thumbnail.png"
|
||||||
|
dest_files=["res://.godot/imported/thumbnail.png-6909560b6205778a3cb325a584af7ca5.ctex"]
|
||||||
|
|
||||||
|
[params]
|
||||||
|
|
||||||
|
compress/mode=0
|
||||||
|
compress/high_quality=false
|
||||||
|
compress/lossy_quality=0.7
|
||||||
|
compress/hdr_compression=1
|
||||||
|
compress/normal_map=0
|
||||||
|
compress/channel_pack=0
|
||||||
|
mipmaps/generate=false
|
||||||
|
mipmaps/limit=-1
|
||||||
|
roughness/mode=0
|
||||||
|
roughness/src_normal=""
|
||||||
|
process/fix_alpha_border=true
|
||||||
|
process/premult_alpha=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
|
process/hdr_as_srgb=false
|
||||||
|
process/hdr_clamp_exposure=false
|
||||||
|
process/size_limit=0
|
||||||
|
detect_3d/compress_to=1
|
|
@ -1,20 +1,47 @@
|
||||||
class_name Level
|
class_name Level
|
||||||
extends Node3D
|
extends Node3D
|
||||||
|
|
||||||
|
signal started_playing
|
||||||
|
signal gravity_change
|
||||||
signal ring_collected
|
signal ring_collected
|
||||||
signal completed
|
signal completed
|
||||||
|
|
||||||
var seconds_spent: float = 0.00
|
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 music: Music
|
||||||
var velocity: float = 0.0
|
|
||||||
var rings: Array[Ring] = []
|
var rings: Array[Ring] = []
|
||||||
|
|
||||||
var finished_rings_count: int = 0
|
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:
|
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()
|
var children = get_children()
|
||||||
for child in children:
|
for child in children:
|
||||||
if is_instance_of(child, Music):
|
if is_instance_of(child, Music):
|
||||||
music = child
|
music = child
|
||||||
|
if child.name == "Player" and is_instance_of(child, Node3D):
|
||||||
|
player = child
|
||||||
assert(is_instance_valid(music), self.name + " has no music!")
|
assert(is_instance_valid(music), self.name + " has no music!")
|
||||||
|
|
||||||
var rings_node = get_node("Rings")
|
var rings_node = get_node("Rings")
|
||||||
|
@ -32,7 +59,46 @@ func collect_ring():
|
||||||
if finished_rings_count >= len(rings):
|
if finished_rings_count >= len(rings):
|
||||||
completed.emit()
|
completed.emit()
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
func _input(_event: InputEvent) -> void:
|
||||||
seconds_spent += delta
|
if Input.is_action_pressed("gravity_strong") or Input.is_action_just_released("gravity_strong"):
|
||||||
velocity = abs($Player.velocity.x) + abs($Player.velocity.y)
|
PhysicsServer3D.area_set_param(
|
||||||
music.adaptInstrumentsToVelocity(velocity, delta)
|
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)
|
||||||
|
|
|
@ -40,7 +40,9 @@ func changeVolume(db: float) -> void:
|
||||||
AudioServer.set_bus_volume_db(bus_index, db + Settings.volume_music)
|
AudioServer.set_bus_volume_db(bus_index, db + Settings.volume_music)
|
||||||
AudioServer.set_bus_mute(bus_index, Settings.volume_music <= -15.0)
|
AudioServer.set_bus_mute(bus_index, Settings.volume_music <= -15.0)
|
||||||
|
|
||||||
func adaptInstrumentsToVelocity(velocity: float, delta: float) -> void:
|
func adaptInstrumentsToVelocity(velocity: float) -> void:
|
||||||
|
## temp
|
||||||
|
const delta = 0.00833333333333
|
||||||
var instruments_needed = floor(velocity / 8)
|
var instruments_needed = floor(velocity / 8)
|
||||||
var instruments_playing = instruments.filter(func(i: AudioStreamPlayer): return i.volume_db > -50)
|
var instruments_playing = instruments.filter(func(i: AudioStreamPlayer): return i.volume_db > -50)
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,27 @@
|
||||||
[gd_scene load_steps=14 format=3 uid="uid://drnqmu4lka22d"]
|
[gd_scene load_steps=13 format=3 uid="uid://drnqmu4lka22d"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://w3fetao1pegm" path="res://levels/level.gd" id="1_3m1pa"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://drfy3vhe6skp1" path="res://levels/night/music.tscn" id="1_npc74"]
|
[ext_resource type="PackedScene" uid="uid://drfy3vhe6skp1" path="res://levels/night/music.tscn" id="1_npc74"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_bc1ig"]
|
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_bc1ig"]
|
||||||
[ext_resource type="PackedScene" uid="uid://dw0xl8644x166" path="res://elements/gravity.tscn" id="2_lfplq"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="4_brcr0"]
|
[ext_resource type="PackedScene" uid="uid://cpm3laywhlbq5" path="res://elements/ring.tscn" id="4_brcr0"]
|
||||||
[ext_resource type="PackedScene" uid="uid://c77bli40240nk" path="res://elements/sign.tscn" id="6_36yav"]
|
[ext_resource type="PackedScene" uid="uid://c77bli40240nk" path="res://elements/sign.tscn" id="6_36yav"]
|
||||||
[ext_resource type="PackedScene" uid="uid://b4jtpua36m6b1" path="res://elements/star.tscn" id="7_ltcl0"]
|
[ext_resource type="PackedScene" uid="uid://b4jtpua36m6b1" path="res://elements/star.tscn" id="7_ltcl0"]
|
||||||
[ext_resource type="PackedScene" uid="uid://da6lkdiskdh8v" path="res://elements/tree.tscn" id="8_kgstj"]
|
[ext_resource type="PackedScene" uid="uid://da6lkdiskdh8v" path="res://elements/tree.tscn" id="8_kgstj"]
|
||||||
|
|
||||||
|
[sub_resource type="GDScript" id="GDScript_akhnt"]
|
||||||
|
script/source = "extends Level
|
||||||
|
|
||||||
|
func _init() -> void:
|
||||||
|
self.id = \"night\"
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
$Tree.rotate_x(delta / 3)
|
||||||
|
$Tree.rotate_y(delta)
|
||||||
|
|
||||||
|
func _on_player_velocity_change(new_velocity: float) -> void:
|
||||||
|
self.velocity = new_velocity
|
||||||
|
self.music.adaptInstrumentsToVelocity(new_velocity * 2)
|
||||||
|
"
|
||||||
|
|
||||||
[sub_resource type="Gradient" id="Gradient_x6q8u"]
|
[sub_resource type="Gradient" id="Gradient_x6q8u"]
|
||||||
|
|
||||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_lu6nv"]
|
[sub_resource type="GradientTexture1D" id="GradientTexture1D_lu6nv"]
|
||||||
|
@ -28,11 +41,9 @@ ambient_light_color = Color(1, 1, 1, 1)
|
||||||
reflected_light_source = 2
|
reflected_light_source = 2
|
||||||
|
|
||||||
[node name="Night" type="Node3D"]
|
[node name="Night" type="Node3D"]
|
||||||
script = ExtResource("1_3m1pa")
|
script = SubResource("GDScript_akhnt")
|
||||||
metadata/_custom_type_script = "uid://w3fetao1pegm"
|
metadata/_custom_type_script = "uid://w3fetao1pegm"
|
||||||
|
|
||||||
[node name="Gravity" parent="." instance=ExtResource("2_lfplq")]
|
|
||||||
|
|
||||||
[node name="Environment" type="WorldEnvironment" parent="."]
|
[node name="Environment" type="WorldEnvironment" parent="."]
|
||||||
environment = SubResource("Environment_8o42c")
|
environment = SubResource("Environment_8o42c")
|
||||||
|
|
||||||
|
@ -193,7 +204,7 @@ transform = Transform3D(-1.31134e-07, -3, 0, 3, -1.31134e-07, 0, 0, 0, 3, -104.2
|
||||||
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -12.3896, -2, 0)
|
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, -12.3896, -2, 0)
|
||||||
|
|
||||||
[node name="Tree" parent="." instance=ExtResource("8_kgstj")]
|
[node name="Tree" parent="." instance=ExtResource("8_kgstj")]
|
||||||
transform = Transform3D(-3.79443, -7.04289, 0, 7.04289, -3.79443, 0, 0, 0, 8, 28.958, -413.185, -93.8242)
|
transform = Transform3D(-3.79271, -7.04382, 0, 7.04382, -3.79271, 0, 0, 0, 8, 28.958, -413.185, -93.8242)
|
||||||
|
|
||||||
[node name="Signs" type="Node3D" parent="."]
|
[node name="Signs" type="Node3D" parent="."]
|
||||||
|
|
||||||
|
@ -327,6 +338,8 @@ transform = Transform3D(-0.99693, 0.0731445, -0.0279554, -0.0555776, -0.912445,
|
||||||
[node name="Star32" parent="Stars" instance=ExtResource("7_ltcl0")]
|
[node name="Star32" parent="Stars" instance=ExtResource("7_ltcl0")]
|
||||||
transform = Transform3D(-0.99693, 0.0731445, -0.0279554, -0.0555776, -0.912445, -0.405407, -0.055161, -0.402609, 0.913709, 0.952739, 0.24193, 7.10684)
|
transform = Transform3D(-0.99693, 0.0731445, -0.0279554, -0.0555776, -0.912445, -0.405407, -0.055161, -0.402609, 0.913709, 0.952739, 0.24193, 7.10684)
|
||||||
|
|
||||||
|
[connection signal="velocity_change" from="Player" to="." method="_on_player_velocity_change"]
|
||||||
|
|
||||||
[editable path="Signs/Sign"]
|
[editable path="Signs/Sign"]
|
||||||
[editable path="Signs/Sign4"]
|
[editable path="Signs/Sign4"]
|
||||||
[editable path="Signs/Sign2"]
|
[editable path="Signs/Sign2"]
|
||||||
|
|
|
@ -1,146 +0,0 @@
|
||||||
[gd_scene load_steps=10 format=3 uid="uid://ikeidrgprk8k"]
|
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://wlhsarkeqe8r" path="res://menus/main/panel.tscn" id="1_qfa5o"]
|
|
||||||
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_0jxef"]
|
|
||||||
|
|
||||||
[sub_resource type="GDScript" id="GDScript_bt14i"]
|
|
||||||
script/source = "extends Node3D
|
|
||||||
|
|
||||||
signal request_start
|
|
||||||
|
|
||||||
var start_menu = preload(\"res://menus/main/start_menu.tscn\")
|
|
||||||
var save_file_manager = preload(\"res://menus/main/save_file_manager.tscn\")
|
|
||||||
var settings_menu = preload(\"res://menus/main/settings_menu.tscn\")
|
|
||||||
|
|
||||||
func _ready() -> void:
|
|
||||||
$Menus/Panel2.connect(\"request_return\", func(): rotate_cube_to(0))
|
|
||||||
$Menus/Panel3.connect(\"request_return\", func(): rotate_cube_to(90))
|
|
||||||
$Menus/Panel4.connect(\"request_return\", func(): rotate_cube_to(180))
|
|
||||||
|
|
||||||
var sm = start_menu.instantiate()
|
|
||||||
sm.connect(\"request_start\", start)
|
|
||||||
sm.connect(\"request_settings\", settings)
|
|
||||||
$Menus/Panel1.change_menu(sm, false)
|
|
||||||
|
|
||||||
func start() -> void:
|
|
||||||
var svm = save_file_manager.instantiate()
|
|
||||||
svm.connect(\"request_start\", func(): request_start.emit())
|
|
||||||
$Menus/Panel2.change_menu(svm)
|
|
||||||
rotate_cube_to(90)
|
|
||||||
|
|
||||||
func settings() -> void:
|
|
||||||
var sm = settings_menu.instantiate()
|
|
||||||
$Menus/Panel2.change_menu(sm)
|
|
||||||
rotate_cube_to(90)
|
|
||||||
|
|
||||||
func rotate_cube_to(degrees: int) -> void:
|
|
||||||
if $Menus/AnimationPlayer.is_playing():
|
|
||||||
return
|
|
||||||
degrees = -degrees
|
|
||||||
|
|
||||||
var animation: Animation = $Menus/AnimationPlayer.get_animation(\"rotate\")
|
|
||||||
var new_rotation = Vector3(0, degrees, 0)
|
|
||||||
animation.track_set_key_value(0, 0, $Menus.rotation_degrees)
|
|
||||||
animation.track_set_key_value(0, 1, new_rotation)
|
|
||||||
|
|
||||||
$Menus/AnimationPlayer.play(\"rotate\")
|
|
||||||
"
|
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_0jxef"]
|
|
||||||
length = 0.001
|
|
||||||
tracks/0/type = "value"
|
|
||||||
tracks/0/imported = false
|
|
||||||
tracks/0/enabled = true
|
|
||||||
tracks/0/path = NodePath(".:rotation_degrees")
|
|
||||||
tracks/0/interp = 1
|
|
||||||
tracks/0/loop_wrap = true
|
|
||||||
tracks/0/keys = {
|
|
||||||
"times": PackedFloat32Array(0),
|
|
||||||
"transitions": PackedFloat32Array(1),
|
|
||||||
"update": 0,
|
|
||||||
"values": [Vector3(0, 0, 0)]
|
|
||||||
}
|
|
||||||
|
|
||||||
[sub_resource type="Animation" id="Animation_bt14i"]
|
|
||||||
resource_name = "rotate"
|
|
||||||
length = 0.3
|
|
||||||
step = 0.3
|
|
||||||
tracks/0/type = "value"
|
|
||||||
tracks/0/imported = false
|
|
||||||
tracks/0/enabled = true
|
|
||||||
tracks/0/path = NodePath(".:rotation_degrees")
|
|
||||||
tracks/0/interp = 2
|
|
||||||
tracks/0/loop_wrap = true
|
|
||||||
tracks/0/keys = {
|
|
||||||
"times": PackedFloat32Array(0, 0.3),
|
|
||||||
"transitions": PackedFloat32Array(1, 1),
|
|
||||||
"update": 0,
|
|
||||||
"values": [Vector3(0, 0, 0), Vector3(0, 0, 0)]
|
|
||||||
}
|
|
||||||
|
|
||||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_3bwb0"]
|
|
||||||
_data = {
|
|
||||||
&"RESET": SubResource("Animation_0jxef"),
|
|
||||||
&"rotate": SubResource("Animation_bt14i")
|
|
||||||
}
|
|
||||||
|
|
||||||
[sub_resource type="PhysicalSkyMaterial" id="PhysicalSkyMaterial_bt14i"]
|
|
||||||
ground_color = Color(0.794232, 0.673177, 0.531056, 1)
|
|
||||||
|
|
||||||
[sub_resource type="Sky" id="Sky_0jxef"]
|
|
||||||
sky_material = SubResource("PhysicalSkyMaterial_bt14i")
|
|
||||||
|
|
||||||
[sub_resource type="Environment" id="Environment_qfa5o"]
|
|
||||||
background_mode = 2
|
|
||||||
background_color = Color(0.804743, 0.804743, 0.804743, 1)
|
|
||||||
sky = SubResource("Sky_0jxef")
|
|
||||||
ambient_light_source = 3
|
|
||||||
ambient_light_color = Color(0.986752, 0.986752, 0.986752, 1)
|
|
||||||
reflected_light_source = 2
|
|
||||||
|
|
||||||
[node name="Area" type="Node3D"]
|
|
||||||
process_mode = 3
|
|
||||||
script = SubResource("GDScript_bt14i")
|
|
||||||
|
|
||||||
[node name="Menus" type="CSGBox3D" parent="."]
|
|
||||||
use_collision = true
|
|
||||||
|
|
||||||
[node name="Panel1" parent="Menus" instance=ExtResource("1_qfa5o")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.501)
|
|
||||||
|
|
||||||
[node name="Panel2" parent="Menus" instance=ExtResource("1_qfa5o")]
|
|
||||||
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0.501, 0, 0)
|
|
||||||
|
|
||||||
[node name="Panel3" parent="Menus" instance=ExtResource("1_qfa5o")]
|
|
||||||
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, -0.501)
|
|
||||||
|
|
||||||
[node name="Panel4" parent="Menus" instance=ExtResource("1_qfa5o")]
|
|
||||||
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -0.501, 0, 0)
|
|
||||||
|
|
||||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="Menus"]
|
|
||||||
libraries = {
|
|
||||||
&"": SubResource("AnimationLibrary_3bwb0")
|
|
||||||
}
|
|
||||||
|
|
||||||
[node name="Camera3D" type="Camera3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2.5)
|
|
||||||
current = true
|
|
||||||
fov = 40.0
|
|
||||||
|
|
||||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
|
||||||
environment = SubResource("Environment_qfa5o")
|
|
||||||
|
|
||||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
|
||||||
transform = Transform3D(0.819152, -0.412596, 0.39844, 0, 0.694658, 0.71934, -0.573576, -0.589249, 0.569031, 0, 0, 0)
|
|
||||||
|
|
||||||
[node name="Player" parent="." instance=ExtResource("2_0jxef")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.87335, 0)
|
|
||||||
|
|
||||||
[node name="Camera" parent="Player" index="0"]
|
|
||||||
visible = false
|
|
||||||
current = false
|
|
||||||
|
|
||||||
[node name="GPUParticles3D" parent="Player/Sphere" index="2"]
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[editable path="Player"]
|
|
|
@ -16,7 +16,7 @@ func _on_btn_exit_pressed() -> void:
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
"
|
"
|
||||||
|
|
||||||
[node name="StartMenu" type="Control"]
|
[node name="InitialMenu" type="Control"]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
152
menus/main/level_selection_menu.tscn
Normal file
152
menus/main/level_selection_menu.tscn
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
[gd_scene load_steps=2 format=3 uid="uid://d3b12iqla7uh6"]
|
||||||
|
|
||||||
|
[sub_resource type="GDScript" id="GDScript_rmgh7"]
|
||||||
|
script/source = "extends Control
|
||||||
|
|
||||||
|
signal request_play_level
|
||||||
|
|
||||||
|
@onready var carousel := $VBoxContainer/Selection/Carousel
|
||||||
|
@onready var label_time := $VBoxContainer/Presentation/MarginContainer/VBoxContainer/BestTime
|
||||||
|
const levels = [
|
||||||
|
\"res://levels/base/level.tscn\",
|
||||||
|
\"res://levels/forest/level.tscn\",
|
||||||
|
\"res://levels/night/level.tscn\",
|
||||||
|
]
|
||||||
|
var loaded_level: Level
|
||||||
|
var loaded_level_scene: PackedScene
|
||||||
|
var loaded_level_path: String
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
if len(loaded_level_path):
|
||||||
|
prepare_level(loaded_level_path)
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
var placeholders := carousel.get_children()
|
||||||
|
for placeholder in placeholders:
|
||||||
|
placeholder.queue_free()
|
||||||
|
|
||||||
|
for i in len(levels):
|
||||||
|
var btn := Button.new()
|
||||||
|
btn.text = \"Level \" + str(i + 1)
|
||||||
|
btn.connect(\"pressed\", func(): prepare_level(levels[i]))
|
||||||
|
carousel.add_child(btn)
|
||||||
|
|
||||||
|
func prepare_level(level_scene_path: String):
|
||||||
|
if is_instance_valid(loaded_level):
|
||||||
|
loaded_level.queue_free()
|
||||||
|
|
||||||
|
ResourceLoader.load_threaded_request(level_scene_path)
|
||||||
|
loaded_level_scene = ResourceLoader.load_threaded_get(level_scene_path)
|
||||||
|
loaded_level = loaded_level_scene.instantiate()
|
||||||
|
loaded_level_path = level_scene_path
|
||||||
|
$VBoxContainer/Presentation/Thumbnail.texture = loaded_level.thumbnail
|
||||||
|
$VBoxContainer/Presentation/MarginContainer/VBoxContainer/LevelName.text = \"The \" + loaded_level.id.capitalize()
|
||||||
|
$VBoxContainer/Presentation.show()
|
||||||
|
$VBoxContainer/MarginContainer/PlayButton.show()
|
||||||
|
display_file_data(SaveFiles.read(SaveFiles.selected_file))
|
||||||
|
|
||||||
|
func display_file_data(data: Variant) -> void:
|
||||||
|
label_time.text = \"Best time: \"
|
||||||
|
var property_name := loaded_level.id + \"_best_time\"
|
||||||
|
if data.has(property_name) and data[property_name] is float:
|
||||||
|
var seconds: float = data[property_name]
|
||||||
|
var minutes: int = floor(seconds / 60)
|
||||||
|
label_time.text += (\"%0*d\" % [2, minutes]) + \":\" + (\"%0*.3f\" % [6, seconds - (minutes * 60)])
|
||||||
|
else:
|
||||||
|
label_time.text += \"00:00.000\"
|
||||||
|
|
||||||
|
func _on_play_button_pressed() -> void:
|
||||||
|
if is_instance_valid(loaded_level):
|
||||||
|
request_play_level.emit(loaded_level, loaded_level_scene)
|
||||||
|
|
||||||
|
func seconds_to_readable(seconds: float) -> String:
|
||||||
|
var minutes: int = floor(seconds / 60)
|
||||||
|
return (\"%0*d\" % [2, minutes]) + \":\" + (\"%0*.3f\" % [6, seconds - (minutes * 60)])
|
||||||
|
|
||||||
|
## This prevents a memory leak that is possible when this menu is destroyed
|
||||||
|
## and the loaded_level becomes unavailable to the rest of the game
|
||||||
|
## For example in the main menu, go to this menu, select a level,
|
||||||
|
## press \"return\" and go to this menu again, boom, memory leak prevented by this
|
||||||
|
func _notification(what: int) -> void:
|
||||||
|
match what:
|
||||||
|
NOTIFICATION_PREDELETE:
|
||||||
|
if is_instance_valid(loaded_level) && !loaded_level.is_inside_tree():
|
||||||
|
loaded_level.queue_free()
|
||||||
|
"
|
||||||
|
|
||||||
|
[node name="LevelSelectionMenu" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = SubResource("GDScript_rmgh7")
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="Selection" type="ScrollContainer" parent="VBoxContainer"]
|
||||||
|
custom_minimum_size = Vector2(0, 50)
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="Carousel" type="HBoxContainer" parent="VBoxContainer/Selection"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
theme_override_constants/separation = 10
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="Placeholder1" type="Button" parent="VBoxContainer/Selection/Carousel"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/icon_max_width = 150
|
||||||
|
text = "Placeholder"
|
||||||
|
|
||||||
|
[node name="Placeholder2" type="Button" parent="VBoxContainer/Selection/Carousel"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Placeholder"
|
||||||
|
|
||||||
|
[node name="Placeholder3" type="Button" parent="VBoxContainer/Selection/Carousel"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Placeholder"
|
||||||
|
|
||||||
|
[node name="Presentation" type="HBoxContainer" parent="VBoxContainer"]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="Thumbnail" type="TextureRect" parent="VBoxContainer/Presentation"]
|
||||||
|
custom_minimum_size = Vector2(150, 150)
|
||||||
|
layout_mode = 2
|
||||||
|
expand_mode = 1
|
||||||
|
stretch_mode = 4
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/Presentation"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/margin_left = 5
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/Presentation/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="LevelName" type="Label" parent="VBoxContainer/Presentation/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Placeholder"
|
||||||
|
|
||||||
|
[node name="BestTime" type="Label" parent="VBoxContainer/Presentation/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Best time: 00:00.000"
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
theme_override_constants/margin_top = 15
|
||||||
|
|
||||||
|
[node name="PlayButton" type="Button" parent="VBoxContainer/MarginContainer"]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Play!"
|
||||||
|
|
||||||
|
[connection signal="pressed" from="VBoxContainer/MarginContainer/PlayButton" to="." method="_on_play_button_pressed"]
|
296
menus/main/main_menu.tscn
Normal file
296
menus/main/main_menu.tscn
Normal file
|
@ -0,0 +1,296 @@
|
||||||
|
[gd_scene load_steps=16 format=3 uid="uid://ikeidrgprk8k"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://wlhsarkeqe8r" path="res://menus/main/panel.tscn" id="1_5vmsf"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cnnvwotv33u1b" path="res://elements/player.tscn" id="2_2rexg"]
|
||||||
|
|
||||||
|
[sub_resource type="GDScript" id="GDScript_bt14i"]
|
||||||
|
script/source = "extends Node3D
|
||||||
|
|
||||||
|
signal request_play_level
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
$Camera3D/AnimationPlayer.play_backwards(\"camera_pan\")
|
||||||
|
PhysicsServer3D.area_set_param(
|
||||||
|
get_viewport().find_world_3d().space,
|
||||||
|
PhysicsServer3D.AREA_PARAM_GRAVITY_VECTOR,
|
||||||
|
Vector3.DOWN
|
||||||
|
)
|
||||||
|
|
||||||
|
# Display on Panel 1
|
||||||
|
const res_initial_menu = preload(\"res://menus/main/initial_menu.tscn\")
|
||||||
|
func _ready() -> void:
|
||||||
|
$Menus/Panel2.connect(\"request_return\", func(): rotate_cube_to(0))
|
||||||
|
$Menus/Panel3.connect(\"request_return\", func(): rotate_cube_to(90))
|
||||||
|
$Menus/Panel4.connect(\"request_return\", func(): rotate_cube_to(180))
|
||||||
|
|
||||||
|
var initial_menu := res_initial_menu.instantiate()
|
||||||
|
initial_menu.connect(\"request_start\", start)
|
||||||
|
initial_menu.connect(\"request_settings\", settings)
|
||||||
|
$Menus/Panel1.change_menu(initial_menu, false)
|
||||||
|
|
||||||
|
# Display on Panel 2
|
||||||
|
const res_settings_menu = preload(\"res://menus/main/settings_menu.tscn\")
|
||||||
|
func settings() -> void:
|
||||||
|
var settings_menu := res_settings_menu.instantiate()
|
||||||
|
$Menus/Panel2.change_menu(settings_menu)
|
||||||
|
rotate_cube_to(90)
|
||||||
|
|
||||||
|
const res_save_file_manager = preload(\"res://menus/main/save_file_manager.tscn\")
|
||||||
|
func start() -> void:
|
||||||
|
var save_file_manager := res_save_file_manager.instantiate()
|
||||||
|
save_file_manager.connect(\"request_start\", level_selection)
|
||||||
|
$Menus/Panel2.change_menu(save_file_manager)
|
||||||
|
rotate_cube_to(90)
|
||||||
|
|
||||||
|
# Display on Panel 3
|
||||||
|
const res_level_selection_menu = preload(\"res://menus/main/level_selection_menu.tscn\")
|
||||||
|
func level_selection() -> void:
|
||||||
|
var level_selection_menu := res_level_selection_menu.instantiate()
|
||||||
|
level_selection_menu.connect(\"request_play_level\", func(level: Level, scene: PackedScene):
|
||||||
|
$Camera3D/AnimationPlayer.play(\"camera_pan\")
|
||||||
|
await get_tree().create_timer(1.5).timeout
|
||||||
|
request_play_level.emit(level, scene)
|
||||||
|
)
|
||||||
|
$Menus/Panel3.change_menu(level_selection_menu)
|
||||||
|
rotate_cube_to(180)
|
||||||
|
|
||||||
|
# cube
|
||||||
|
func rotate_cube_to(degrees: int) -> void:
|
||||||
|
if $Menus/AnimationPlayer.is_playing():
|
||||||
|
return
|
||||||
|
|
||||||
|
var cube_animation: Animation = $Menus/AnimationPlayer.get_animation(\"rotate\")
|
||||||
|
cube_animation.track_set_key_value(0, 0, $Menus.rotation_degrees)
|
||||||
|
cube_animation.track_set_key_value(0, 1, Vector3(0, -degrees, 0))
|
||||||
|
$Menus/AnimationPlayer.play(\"rotate\")
|
||||||
|
|
||||||
|
if $AnimationPlayer.is_playing():
|
||||||
|
await get_tree().create_timer($AnimationPlayer.current_animation_length).timeout
|
||||||
|
var sky_animation: Animation = $AnimationPlayer.get_animation(\"sky_brightness\")
|
||||||
|
sky_animation.track_set_key_value(0, 0, $WorldEnvironment.environment.sky.sky_material.energy_multiplier)
|
||||||
|
sky_animation.track_set_key_value(0, 1, max(90, degrees * 2) / 90)
|
||||||
|
$AnimationPlayer.play(\"sky_brightness\")
|
||||||
|
"
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_0jxef"]
|
||||||
|
length = 0.001
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath(".:rotation_degrees")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector3(0, 0, 0)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_bt14i"]
|
||||||
|
resource_name = "rotate"
|
||||||
|
length = 0.3
|
||||||
|
step = 0.3
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath(".:rotation_degrees")
|
||||||
|
tracks/0/interp = 2
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 0.3),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector3(0, 0, 0), Vector3(0, 0, 0)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="AnimationLibrary" id="AnimationLibrary_3bwb0"]
|
||||||
|
_data = {
|
||||||
|
&"RESET": SubResource("Animation_0jxef"),
|
||||||
|
&"rotate": SubResource("Animation_bt14i")
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_2rexg"]
|
||||||
|
length = 0.001
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("WorldEnvironment:environment:sky:sky_material:energy_multiplier")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [1.0]
|
||||||
|
}
|
||||||
|
tracks/1/type = "value"
|
||||||
|
tracks/1/imported = false
|
||||||
|
tracks/1/enabled = true
|
||||||
|
tracks/1/path = NodePath("Camera3D:fov")
|
||||||
|
tracks/1/interp = 1
|
||||||
|
tracks/1/loop_wrap = true
|
||||||
|
tracks/1/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [40.0]
|
||||||
|
}
|
||||||
|
tracks/2/type = "value"
|
||||||
|
tracks/2/imported = false
|
||||||
|
tracks/2/enabled = true
|
||||||
|
tracks/2/path = NodePath("Camera3D:position")
|
||||||
|
tracks/2/interp = 1
|
||||||
|
tracks/2/loop_wrap = true
|
||||||
|
tracks/2/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector3(0, 0, 2.5)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_jinmx"]
|
||||||
|
resource_name = "camera_pan"
|
||||||
|
length = 1.5
|
||||||
|
step = 0.1
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("Camera3D:fov")
|
||||||
|
tracks/0/interp = 2
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 1.5),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [40.0, 75.0]
|
||||||
|
}
|
||||||
|
tracks/1/type = "value"
|
||||||
|
tracks/1/imported = false
|
||||||
|
tracks/1/enabled = true
|
||||||
|
tracks/1/path = NodePath("Camera3D:position")
|
||||||
|
tracks/1/interp = 2
|
||||||
|
tracks/1/loop_wrap = true
|
||||||
|
tracks/1/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 1.5),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector3(0, 0, 2.5), Vector3(0, 0, 15)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="AnimationLibrary" id="AnimationLibrary_jinmx"]
|
||||||
|
_data = {
|
||||||
|
&"RESET": SubResource("Animation_2rexg"),
|
||||||
|
&"camera_pan": SubResource("Animation_jinmx")
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="PhysicalSkyMaterial" id="PhysicalSkyMaterial_bt14i"]
|
||||||
|
ground_color = Color(1, 0.484315, 0.700558, 1)
|
||||||
|
|
||||||
|
[sub_resource type="Sky" id="Sky_0jxef"]
|
||||||
|
sky_material = SubResource("PhysicalSkyMaterial_bt14i")
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_qfa5o"]
|
||||||
|
background_mode = 2
|
||||||
|
background_color = Color(0.804743, 0.804743, 0.804743, 1)
|
||||||
|
sky = SubResource("Sky_0jxef")
|
||||||
|
ambient_light_source = 3
|
||||||
|
ambient_light_color = Color(0.986752, 0.986752, 0.986752, 1)
|
||||||
|
reflected_light_source = 2
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_j2kye"]
|
||||||
|
length = 0.001
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("../../WorldEnvironment:environment:sky:sky_material:energy_multiplier")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [1.0]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_gma2u"]
|
||||||
|
resource_name = "sky_brightness"
|
||||||
|
length = 0.3
|
||||||
|
step = 0.1
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath("../../WorldEnvironment:environment:sky:sky_material:energy_multiplier")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 0.3),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [1.0, 1.0]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="AnimationLibrary" id="AnimationLibrary_wruj6"]
|
||||||
|
_data = {
|
||||||
|
&"RESET": SubResource("Animation_j2kye"),
|
||||||
|
&"sky_brightness": SubResource("Animation_gma2u")
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="MainMenu" type="Node3D"]
|
||||||
|
process_mode = 3
|
||||||
|
script = SubResource("GDScript_bt14i")
|
||||||
|
|
||||||
|
[node name="Menus" type="CSGBox3D" parent="."]
|
||||||
|
use_collision = true
|
||||||
|
|
||||||
|
[node name="Panel1" parent="Menus" instance=ExtResource("1_5vmsf")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.501)
|
||||||
|
|
||||||
|
[node name="Panel2" parent="Menus" instance=ExtResource("1_5vmsf")]
|
||||||
|
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0.501, 0, 0)
|
||||||
|
|
||||||
|
[node name="Panel3" parent="Menus" instance=ExtResource("1_5vmsf")]
|
||||||
|
transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, -0.501)
|
||||||
|
|
||||||
|
[node name="Panel4" parent="Menus" instance=ExtResource("1_5vmsf")]
|
||||||
|
transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -0.501, 0, 0)
|
||||||
|
|
||||||
|
[node name="AnimationPlayer" type="AnimationPlayer" parent="Menus"]
|
||||||
|
libraries = {
|
||||||
|
&"": SubResource("AnimationLibrary_3bwb0")
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2.5)
|
||||||
|
current = true
|
||||||
|
fov = 40.0
|
||||||
|
|
||||||
|
[node name="AnimationPlayer" type="AnimationPlayer" parent="Camera3D"]
|
||||||
|
root_node = NodePath("../..")
|
||||||
|
libraries = {
|
||||||
|
&"": SubResource("AnimationLibrary_jinmx")
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_qfa5o")
|
||||||
|
|
||||||
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
|
transform = Transform3D(0.819152, -0.412596, 0.39844, 0, 0.694658, 0.71934, -0.573576, -0.589249, 0.569031, 0, 0, 0)
|
||||||
|
|
||||||
|
[node name="Player" parent="." instance=ExtResource("2_2rexg")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4, 0)
|
||||||
|
|
||||||
|
[node name="Camera" parent="Player" index="0"]
|
||||||
|
visible = false
|
||||||
|
current = false
|
||||||
|
|
||||||
|
[node name="GPUParticles3D" parent="Player/Sphere" index="2"]
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||||
|
root_node = NodePath("../Camera3D/AnimationPlayer")
|
||||||
|
libraries = {
|
||||||
|
&"": SubResource("AnimationLibrary_wruj6")
|
||||||
|
}
|
||||||
|
|
||||||
|
[editable path="Player"]
|
|
@ -6,21 +6,31 @@ script/source = "extends Control
|
||||||
signal request_start
|
signal request_start
|
||||||
|
|
||||||
@onready var label_name = $VBoxContainer/MarginContainer/VBoxContainer/Description/Name
|
@onready var label_name = $VBoxContainer/MarginContainer/VBoxContainer/Description/Name
|
||||||
@onready var label_time = $VBoxContainer/MarginContainer/VBoxContainer/Description/Time
|
|
||||||
|
func _ready() -> void:
|
||||||
|
$VBoxContainer/MarginContainer.hide()
|
||||||
|
|
||||||
|
## Get the newest \"played_for\" when the main menu appears again
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
if len(SaveFiles.selected_file):
|
||||||
|
display_file_data(SaveFiles.selected_file)
|
||||||
|
|
||||||
func _on_save_1_pressed() -> void:
|
func _on_save_1_pressed() -> void:
|
||||||
label_name.text = $VBoxContainer/Save1.text
|
label_name.text = $VBoxContainer/Save1.text
|
||||||
display_file_data(SaveFiles.read(SaveFiles.names[0]))
|
display_file_data(SaveFiles.names[0])
|
||||||
|
|
||||||
func _on_save_2_pressed() -> void:
|
func _on_save_2_pressed() -> void:
|
||||||
label_name.text = $VBoxContainer/Save2.text
|
label_name.text = $VBoxContainer/Save2.text
|
||||||
display_file_data(SaveFiles.read(SaveFiles.names[1]))
|
display_file_data(SaveFiles.names[1])
|
||||||
|
|
||||||
func _on_save_3_pressed() -> void:
|
func _on_save_3_pressed() -> void:
|
||||||
label_name.text = $VBoxContainer/Save3.text
|
label_name.text = $VBoxContainer/Save3.text
|
||||||
display_file_data(SaveFiles.read(SaveFiles.names[2]))
|
display_file_data(SaveFiles.names[2])
|
||||||
|
|
||||||
func display_file_data(data: Variant) -> void:
|
func display_file_data(file_name: String) -> void:
|
||||||
|
$VBoxContainer/MarginContainer.show()
|
||||||
|
var label_time := $VBoxContainer/MarginContainer/VBoxContainer/Description/Time
|
||||||
|
var data = SaveFiles.read(file_name)
|
||||||
$VBoxContainer/MarginContainer.show()
|
$VBoxContainer/MarginContainer.show()
|
||||||
label_time.text = \" | \"
|
label_time.text = \" | \"
|
||||||
if data.has(\"played_for\") and data.played_for is float:
|
if data.has(\"played_for\") and data.played_for is float:
|
||||||
|
@ -28,14 +38,14 @@ func display_file_data(data: Variant) -> void:
|
||||||
var minutes: int = floor(seconds / 60)
|
var minutes: int = floor(seconds / 60)
|
||||||
label_time.text += (\"%0*d\" % [2, minutes]) + \":\" + (\"%0*.3f\" % [6, seconds - (minutes * 60)])
|
label_time.text += (\"%0*d\" % [2, minutes]) + \":\" + (\"%0*.3f\" % [6, seconds - (minutes * 60)])
|
||||||
else:
|
else:
|
||||||
label_time.text += \"00:00\"
|
label_time.text += \"00:00.000\"
|
||||||
|
|
||||||
func _on_start_pressed() -> void:
|
func _on_start_pressed() -> void:
|
||||||
request_start.emit()
|
request_start.emit()
|
||||||
|
|
||||||
func _on_delete_pressed() -> void:
|
func _on_delete_pressed() -> void:
|
||||||
SaveFiles.empty(SaveFiles.selected_file)
|
SaveFiles.empty(SaveFiles.selected_file)
|
||||||
display_file_data(SaveFiles.read(SaveFiles.selected_file))
|
display_file_data(SaveFiles.selected_file)
|
||||||
"
|
"
|
||||||
|
|
||||||
[node name="SaveFileManager" type="Control"]
|
[node name="SaveFileManager" type="Control"]
|
||||||
|
|
|
@ -114,10 +114,12 @@ libraries = {
|
||||||
}
|
}
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="VSplitContainer"]
|
[node name="Label" type="Label" parent="VSplitContainer"]
|
||||||
|
custom_minimum_size = Vector2(1, 1)
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "MENU NAME"
|
text = "MENU NAME"
|
||||||
label_settings = SubResource("LabelSettings_2d4ws")
|
label_settings = SubResource("LabelSettings_2d4ws")
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
autowrap_mode = 3
|
||||||
uppercase = true
|
uppercase = true
|
||||||
|
|
||||||
[node name="MarginContainer" type="MarginContainer" parent="VSplitContainer"]
|
[node name="MarginContainer" type="MarginContainer" parent="VSplitContainer"]
|
||||||
|
|
|
@ -13,7 +13,7 @@ config_version=5
|
||||||
config/name="DreamBall"
|
config/name="DreamBall"
|
||||||
config/description="Manipulate the gravity to make a ball go through every ring!
|
config/description="Manipulate the gravity to make a ball go through every ring!
|
||||||
https://kitsunes.dev/Taevas/DreamBall"
|
https://kitsunes.dev/Taevas/DreamBall"
|
||||||
config/version="20250423.0"
|
config/version="20250503.0"
|
||||||
run/main_scene="res://index.tscn"
|
run/main_scene="res://index.tscn"
|
||||||
config/features=PackedStringArray("4.4", "GL Compatibility")
|
config/features=PackedStringArray("4.4", "GL Compatibility")
|
||||||
boot_splash/show_image=false
|
boot_splash/show_image=false
|
||||||
|
@ -78,6 +78,13 @@ restart_level={
|
||||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":2,"pressure":0.0,"pressed":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
display_map={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":9,"pressure":0.0,"pressed":false,"script":null)
|
||||||
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":10,"pressure":0.0,"pressed":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
[physics]
|
[physics]
|
||||||
|
|
||||||
|
@ -86,6 +93,7 @@ common/physics_ticks_per_second=120
|
||||||
common/max_physics_steps_per_frame=20
|
common/max_physics_steps_per_frame=20
|
||||||
3d/physics_engine="GodotPhysics3D"
|
3d/physics_engine="GodotPhysics3D"
|
||||||
3d/default_gravity=1.0
|
3d/default_gravity=1.0
|
||||||
|
3d/default_gravity_vector=Vector3(0, -0.5, 0)
|
||||||
3d/solver/solver_iterations=40
|
3d/solver/solver_iterations=40
|
||||||
3d/solver/default_contact_bias=1.0
|
3d/solver/default_contact_bias=1.0
|
||||||
common/physics_interpolation=true
|
common/physics_interpolation=true
|
||||||
|
|
|
@ -6,7 +6,7 @@ const names := [
|
||||||
"user://save_file_3.save",
|
"user://save_file_3.save",
|
||||||
]
|
]
|
||||||
|
|
||||||
var selected_file := names[0]
|
var selected_file: String
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
for save_file_name in names:
|
for save_file_name in names:
|
||||||
|
@ -22,6 +22,7 @@ func empty(save_file_name: String) -> void:
|
||||||
write(JSON.stringify({}), save_file_name)
|
write(JSON.stringify({}), save_file_name)
|
||||||
|
|
||||||
func read(save_file_name: String) -> Variant:
|
func read(save_file_name: String) -> Variant:
|
||||||
|
print("Reading from save file ", save_file_name)
|
||||||
ensure_existence(save_file_name)
|
ensure_existence(save_file_name)
|
||||||
selected_file = save_file_name
|
selected_file = save_file_name
|
||||||
|
|
||||||
|
@ -41,6 +42,7 @@ func write(json_string: String, save_file_name: String) -> void:
|
||||||
save_file.store_line("FOR YOUR SAFETY, ALWAYS CHECK IF THE DATA OF THE FILES YOU DOWNLOAD LOOKS OKAY")
|
save_file.store_line("FOR YOUR SAFETY, ALWAYS CHECK IF THE DATA OF THE FILES YOU DOWNLOAD LOOKS OKAY")
|
||||||
|
|
||||||
func change_property(property: String, value, save_file_name: String) -> void:
|
func change_property(property: String, value, save_file_name: String) -> void:
|
||||||
|
print("Changing property '", property, "' on save file ", save_file_name)
|
||||||
ensure_existence(save_file_name)
|
ensure_existence(save_file_name)
|
||||||
var data = read(save_file_name)
|
var data = read(save_file_name)
|
||||||
data[property] = value
|
data[property] = value
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue