Code cleanup. Removes Godot warnings. Removes unused import functions from the Database.
This commit is contained in:
@@ -22,7 +22,7 @@ const background_path_model: = "res://assets/gardens/gardens/garden_%02d_open.pn
|
||||
%Flower4,
|
||||
%Flower5,
|
||||
]
|
||||
@onready var background: = %Background
|
||||
@onready var background: TextureRect = %Background
|
||||
@onready var lesson_button_controls: Array[LessonButton] = [
|
||||
%Button1,
|
||||
%Button2,
|
||||
|
||||
@@ -7,7 +7,7 @@ extends Node2D
|
||||
@onready var sprite: Sprite2D = %Sprite
|
||||
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
if texture:
|
||||
_set_texture(texture)
|
||||
|
||||
@@ -16,9 +16,5 @@ func _set_texture(p_texture: Texture) -> void:
|
||||
texture = p_texture
|
||||
sprite.texture = p_texture
|
||||
|
||||
@warning_ignore("integer_division")
|
||||
sprite.position.y = -sprite.texture.get_height() / 2
|
||||
|
||||
|
||||
func _on_area_2d_input_event(viewport, event, shape_idx):
|
||||
if event.is_action_pressed("left_click"):
|
||||
print("CLICKKKKK")
|
||||
|
||||
@@ -24,5 +24,3 @@ position = Vector2(2312, 1544)
|
||||
rotation = -3.14159
|
||||
scale = Vector2(1, -1)
|
||||
polygon = PackedVector2Array(1030, -1546, -250, -1546, -250, 254, 1030, 254, 774, 225, 630, 163, 449, 44, 264, -167, 163, -383, 125, -619, 158, -890, 251, -1101, 390, -1282, 563, -1416, 710, -1490, 838, -1522)
|
||||
|
||||
[connection signal="input_event" from="Area2D" to="." method="_on_area_2d_input_event"]
|
||||
|
||||
@@ -14,7 +14,7 @@ class Flower:
|
||||
position = p_position
|
||||
|
||||
static func from_dict(d: Dictionary) -> Flower:
|
||||
return Flower.new(d.color, d.type, d.position)
|
||||
return Flower.new(d.color as int, d.type as int, d.position as Vector2i)
|
||||
|
||||
func to_dict() -> Dictionary:
|
||||
return {
|
||||
@@ -33,7 +33,7 @@ class LessonButton:
|
||||
path_out_position = p_path_out_position
|
||||
|
||||
static func from_dict(d: Dictionary) -> LessonButton:
|
||||
return LessonButton.new(d.position, d.path_out_position)
|
||||
return LessonButton.new(d.position as Vector2i, d.path_out_position as Vector2i)
|
||||
|
||||
func to_dict() -> Dictionary:
|
||||
return {
|
||||
|
||||
@@ -54,10 +54,11 @@ func update_from_dict(dict: Dictionary) -> void:
|
||||
last_modified = dict.last_modified
|
||||
|
||||
students.clear()
|
||||
for device: String in dict.students.keys():
|
||||
var d_students: Dictionary = dict.students
|
||||
for device: String in d_students.keys():
|
||||
var device_students: Array[StudentData] = []
|
||||
for s: Dictionary in dict.students[device]:
|
||||
var student = StudentData.new()
|
||||
var student: = StudentData.new()
|
||||
student.code = str(s.code)
|
||||
student.name = s.name
|
||||
student.age = s.age
|
||||
@@ -67,16 +68,16 @@ func update_from_dict(dict: Dictionary) -> void:
|
||||
students[int(device)] = device_students
|
||||
|
||||
func get_new_code() -> String :
|
||||
var used_codes = []
|
||||
for student_array in students.values():
|
||||
for student in student_array:
|
||||
var used_codes: = []
|
||||
for student_array: Array[StudentData] in students.values():
|
||||
for student: StudentData in student_array:
|
||||
used_codes.append(student.code)
|
||||
|
||||
if used_codes.size() == available_codes.size():
|
||||
return ""
|
||||
|
||||
var codes = available_codes.duplicate()
|
||||
for c in used_codes:
|
||||
var codes: = available_codes.duplicate()
|
||||
for c: String in used_codes:
|
||||
codes.erase(c)
|
||||
|
||||
var code : String = codes.pick_random()
|
||||
@@ -87,16 +88,16 @@ func get_students_count() -> int :
|
||||
if not students:
|
||||
return 0
|
||||
|
||||
var count = 0
|
||||
for device in students.keys():
|
||||
var students_array = students[device] as Array
|
||||
var count: = 0
|
||||
for device: int in students.keys():
|
||||
var students_array: = students[device] as Array
|
||||
if students_array:
|
||||
count += students[device].size()
|
||||
count += students_array.size()
|
||||
|
||||
return count
|
||||
|
||||
func to_dict() -> Dictionary:
|
||||
var dict = {
|
||||
var dict: = {
|
||||
"account_type": account_type,
|
||||
"email": email,
|
||||
"password": password,
|
||||
@@ -104,9 +105,10 @@ func to_dict() -> Dictionary:
|
||||
}
|
||||
|
||||
dict["students"] = {}
|
||||
for device in students.keys():
|
||||
for device: int in students.keys():
|
||||
dict["students"][device] = []
|
||||
var device_students: Array = dict["students"][device]
|
||||
for s: StudentData in students[device]:
|
||||
dict["students"][device].append(s.to_dict())
|
||||
device_students.append(s.to_dict())
|
||||
|
||||
return dict
|
||||
|
||||
+59
-48
@@ -24,13 +24,13 @@ const garden_size: = 2400
|
||||
@export var minigames_scenes: Array[PackedScene]
|
||||
@export var minigames_icons: Array[Texture]
|
||||
|
||||
@onready var garden_parent: = %GardenParent
|
||||
@onready var garden_parent: HBoxContainer = %GardenParent
|
||||
@onready var locked_line: Line2D = $ScrollContainer/LockedLine
|
||||
@onready var unlocked_line: Line2D = $ScrollContainer/UnlockedLine
|
||||
@onready var line_particles: GPUParticles2D = %LineParticles
|
||||
@onready var line_audio_stream_player: AudioStreamPlayer = %LineAudioStreamPlayer
|
||||
@onready var scroll_container: ScrollContainer = $ScrollContainer
|
||||
@onready var parallax_background: = %ParallaxBackground
|
||||
@onready var parallax_background: ParallaxBackground = %ParallaxBackground
|
||||
@onready var minigame_selection: Control = %MinigameSelection
|
||||
@onready var lesson_button: LessonButton = %LessonButton
|
||||
@onready var lesson_button_particles: GPUParticles2D = %LessonButtonParticles
|
||||
@@ -48,10 +48,10 @@ const garden_size: = 2400
|
||||
|
||||
|
||||
var lessons: = {}
|
||||
var points: = []
|
||||
var points: Array[Array]= []
|
||||
var is_scrolling: = false
|
||||
var scroll_beginning_garden: = 0
|
||||
var tween: Tween
|
||||
var scroll_tween: Tween
|
||||
|
||||
var in_minigame_selection: = false
|
||||
var current_lesson_number: = -1
|
||||
@@ -87,7 +87,7 @@ func _ready() -> void:
|
||||
if starting_garden == -1:
|
||||
var lesson_ind: = 1
|
||||
for garden_ind in garden_parent.get_child_count():
|
||||
var garden_control: = garden_parent.get_child(garden_ind)
|
||||
var garden_control: Garden = garden_parent.get_child(garden_ind)
|
||||
if starting_garden != -1:
|
||||
break
|
||||
if not lesson_ind in lessons:
|
||||
@@ -111,22 +111,21 @@ func _ready() -> void:
|
||||
|
||||
# Finds the button
|
||||
var lesson_ind: int = 1
|
||||
var lesson_button: LessonButton
|
||||
for garden_control in garden_parent.get_children():
|
||||
var current_lesson_button: LessonButton
|
||||
for garden_control: Garden in garden_parent.get_children():
|
||||
for i in garden_control.lesson_button_controls.size():
|
||||
if lesson_button:
|
||||
break
|
||||
if lesson_ind == transition_data.current_lesson_number:
|
||||
lesson_button = garden_control.lesson_button_controls[i]
|
||||
current_lesson_button = garden_control.lesson_button_controls[i]
|
||||
break
|
||||
lesson_ind += 1
|
||||
pass
|
||||
|
||||
# Re-open the minigames layout
|
||||
# If the minigame is completed: play an animation
|
||||
await _open_minigames_layout(lesson_button, transition_data.current_lesson_number, transition_data.current_garden, transition_data.current_button_global_position)
|
||||
await _open_minigames_layout(current_lesson_button, transition_data.current_lesson_number as int, transition_data.current_garden as int, transition_data.current_button_global_position as Vector2)
|
||||
|
||||
scroll_container.scroll_horizontal = garden_size * starting_garden
|
||||
@warning_ignore("integer_division")
|
||||
scroll_beginning_garden = scroll_container.scroll_horizontal / garden_size
|
||||
|
||||
await OpeningCurtain.open()
|
||||
@@ -149,11 +148,11 @@ func _unlock_new_lesson() -> void:
|
||||
await get_tree().create_timer(1).timeout
|
||||
await _close_minigames_layout()
|
||||
|
||||
var lesson_ind = 1
|
||||
var lesson_ind: = 1
|
||||
var last_lesson_button: LessonButton
|
||||
var new_lesson_button: LessonButton
|
||||
var is_last_lesson_of_garden: bool = false
|
||||
for garden_control in garden_parent.get_children():
|
||||
for garden_control: Garden in garden_parent.get_children():
|
||||
for i in garden_control.lesson_button_controls.size():
|
||||
if lesson_ind == max_lesson + 1:
|
||||
new_lesson_button = garden_control.lesson_button_controls[i]
|
||||
@@ -174,19 +173,23 @@ func _unlock_new_lesson() -> void:
|
||||
# Fill in the path towards the next lesson
|
||||
var curve: = Curve2D.new()
|
||||
for i in range(max_lesson-1, max_lesson + 1):
|
||||
curve.add_point(points[i][0], points[i][1], points[i][2])
|
||||
curve.add_point(points[i][0] as Vector2, points[i][1] as Vector2, points[i][2] as Vector2)
|
||||
|
||||
var baked_points: = curve.get_baked_points()
|
||||
|
||||
# Check if we need to scroll to the next garden
|
||||
if is_last_lesson_of_garden:
|
||||
@warning_ignore("integer_division")
|
||||
scroll_beginning_garden = scroll_container.scroll_horizontal / garden_size
|
||||
var target_scroll: int = scroll_beginning_garden * garden_size + garden_size
|
||||
var tween = create_tween()
|
||||
var tween: = create_tween()
|
||||
tween.set_ease(Tween.EASE_IN_OUT)
|
||||
tween.tween_property(scroll_container, "scroll_horizontal", target_scroll, 4)
|
||||
@warning_ignore("integer_division")
|
||||
scroll_beginning_garden = target_scroll / garden_size
|
||||
garden_parent.get_child(scroll_beginning_garden).pop_animation()
|
||||
|
||||
var g: Garden = garden_parent.get_child(scroll_beginning_garden)
|
||||
g.pop_animation()
|
||||
|
||||
line_audio_stream_player.pitch_scale = 0.95
|
||||
for point: Vector2 in baked_points:
|
||||
@@ -211,14 +214,15 @@ func _process(_delta: float) -> void:
|
||||
|
||||
|
||||
func get_gardens_db_data() -> void:
|
||||
Database.db.query("Select Grapheme, Phoneme, LessonNb, GPID FROM Lessons
|
||||
Database.db.query("SELECT Grapheme, Phoneme, LessonNb, GPID FROM Lessons
|
||||
INNER JOIN GPsInLessons ON GPsInLessons.LessonID = Lessons.ID
|
||||
INNER JOIN GPs ON GPsInLessons.GPID = GPs.ID
|
||||
ORDER BY LessonNb")
|
||||
for e in Database.db.query_result:
|
||||
if not lessons.has(e.LessonNb):
|
||||
lessons[e.LessonNb] = []
|
||||
lessons[e.LessonNb].append({grapheme = e.Grapheme, phoneme = e.Phoneme, gp_id = e.GPID})
|
||||
var lesson_array: Array = lessons[e.LessonNb]
|
||||
lesson_array.append({grapheme = e.Grapheme, phoneme = e.Phoneme, gp_id = e.GPID})
|
||||
|
||||
|
||||
func _open_minigames_layout(button: LessonButton, lesson_ind: int, garden_ind: int, button_global_position: = Vector2.ZERO) -> void:
|
||||
@@ -260,12 +264,12 @@ func _open_minigames_layout(button: LessonButton, lesson_ind: int, garden_ind: i
|
||||
minigame_background_center.modulate = garden.color
|
||||
|
||||
# Lesson button
|
||||
_handle_lesson_button(current_lesson_number, lesson_unlocks["look_and_learn"], garden.color)
|
||||
_handle_lesson_button(current_lesson_number, lesson_unlocks["look_and_learn"] as UserProgression.Status, garden.color)
|
||||
|
||||
# Minigames
|
||||
_fill_minigame_choice(minigame_layout_1, exercises[0], lesson_unlocks["games"][0], 0)
|
||||
_fill_minigame_choice(minigame_layout_2, exercises[1], lesson_unlocks["games"][1], 1)
|
||||
_fill_minigame_choice(minigame_layout_3, exercises[2], lesson_unlocks["games"][2], 2)
|
||||
_fill_minigame_choice(minigame_layout_1, exercises[0], lesson_unlocks["games"][0] as UserProgression.Status, 0)
|
||||
_fill_minigame_choice(minigame_layout_2, exercises[1], lesson_unlocks["games"][1] as UserProgression.Status, 1)
|
||||
_fill_minigame_choice(minigame_layout_3, exercises[2], lesson_unlocks["games"][2] as UserProgression.Status, 2)
|
||||
|
||||
# Animations
|
||||
minigame_selection.visible = true
|
||||
@@ -291,8 +295,8 @@ func _open_minigames_layout(button: LessonButton, lesson_ind: int, garden_ind: i
|
||||
minigame_layout_opened.emit()
|
||||
|
||||
|
||||
func _handle_lesson_button(current_lesson_number: int, status: UserProgression.Status, color: Color) -> void:
|
||||
lesson_button.text = lessons[current_lesson_number][0].grapheme
|
||||
func _handle_lesson_button(lesson: int, status: UserProgression.Status, color: Color) -> void:
|
||||
lesson_button.text = lessons[lesson][0].grapheme
|
||||
lesson_button.completed_color = color
|
||||
|
||||
lesson_button.disabled = status == UserProgression.Status.Locked
|
||||
@@ -314,7 +318,7 @@ func _fill_minigame_choice(layout: MinigameLayout, exercise_type: int, status: U
|
||||
if transition_data and transition_data.has("minigame_completed") and transition_data.minigame_completed and transition_data.minigame_number == minigame_number:
|
||||
layout.self_modulate = unlocked_color
|
||||
await minigame_layout_opened
|
||||
var tween: = create_tween().tween_property(layout, "self_modulate:a", 0, 1)
|
||||
create_tween().tween_property(layout, "self_modulate:a", 0, 1)
|
||||
else:
|
||||
layout.self_modulate.a = 0
|
||||
|
||||
@@ -353,7 +357,9 @@ func _close_minigames_layout() -> void:
|
||||
back_button.visible = true
|
||||
line_particles.visible = true
|
||||
|
||||
for button in garden_parent.get_child(current_garden).lesson_button_controls:
|
||||
var garden: Garden = garden_parent.get_child(current_garden)
|
||||
|
||||
for button in garden.lesson_button_controls:
|
||||
button.mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
|
||||
minigame_layout_1.pressed.disconnect(_on_minigame_button_pressed)
|
||||
@@ -364,11 +370,11 @@ func _close_minigames_layout() -> void:
|
||||
func set_up_lessons() -> void:
|
||||
var lesson_ind: = 1
|
||||
for garden_ind in garden_parent.get_child_count():
|
||||
var garden_control: = garden_parent.get_child(garden_ind)
|
||||
var garden_control: Garden = garden_parent.get_child(garden_ind)
|
||||
for i in garden_control.lesson_button_controls.size():
|
||||
if not lesson_ind in lessons:
|
||||
break
|
||||
garden_control.set_lesson_label(i, lessons[lesson_ind][0].grapheme)
|
||||
garden_control.set_lesson_label(i, lessons[lesson_ind][0].grapheme as String)
|
||||
garden_control.lesson_button_controls[i].pressed.connect(_on_garden_lesson_button_pressed.bind(garden_control.lesson_button_controls[i], lesson_ind, garden_ind))
|
||||
lesson_ind += 1
|
||||
|
||||
@@ -387,7 +393,7 @@ func add_gardens() -> void:
|
||||
for child in garden_parent.get_children():
|
||||
child.free()
|
||||
for garden_layout in gardens_layout.gardens:
|
||||
var garden: = garden_scene.instantiate()
|
||||
var garden: Garden = garden_scene.instantiate()
|
||||
garden_parent.add_child(garden)
|
||||
garden.garden_layout = garden_layout
|
||||
|
||||
@@ -398,16 +404,16 @@ func set_up_path() -> void:
|
||||
points = []
|
||||
var curve: = Curve2D.new()
|
||||
for i in gardens_layout.gardens.size():
|
||||
var garden_layout: = gardens_layout.gardens[i]
|
||||
var garden_control: = garden_parent.get_child(i)
|
||||
for lesson_button in garden_layout.lesson_buttons:
|
||||
var point_position: Vector2 = garden_parent.position + garden_control.position + Vector2(lesson_button.position)
|
||||
var garden_layout: GardenLayout = gardens_layout.gardens[i]
|
||||
var garden_control: Garden = garden_parent.get_child(i)
|
||||
for b in garden_layout.lesson_buttons:
|
||||
var point_position: Vector2 = garden_parent.position + garden_control.position + Vector2(b.position)
|
||||
point_position += garden_control.get_button_size() / 2
|
||||
var point_in_position: = Vector2.ZERO
|
||||
if curve.point_count > 1:
|
||||
point_in_position = curve.get_point_position(curve.point_count - 1) + curve.get_point_out(curve.point_count - 1) - point_position
|
||||
curve.add_point(point_position, point_in_position, lesson_button.path_out_position)
|
||||
points.append([point_position, point_in_position, lesson_button.path_out_position])
|
||||
curve.add_point(point_position, point_in_position, b.path_out_position)
|
||||
points.append([point_position, point_in_position, b.path_out_position])
|
||||
locked_line.points = curve.get_baked_points()
|
||||
|
||||
|
||||
@@ -419,7 +425,7 @@ func _set_progression() -> void:
|
||||
return
|
||||
|
||||
var lesson_ind: = 1
|
||||
for garden_control in garden_parent.get_children():
|
||||
for garden_control: Garden in garden_parent.get_children():
|
||||
var garden_unlocks: = 0.0
|
||||
var garden_total_unlocks: = 0.0
|
||||
for i in garden_control.lesson_button_controls.size():
|
||||
@@ -478,7 +484,7 @@ func _set_progression() -> void:
|
||||
max_lesson += 1
|
||||
|
||||
for i in range(max_lesson):
|
||||
curve.add_point(points[i][0], points[i][1], points[i][2])
|
||||
curve.add_point(points[i][0] as Vector2, points[i][1] as Vector2, points[i][2] as Vector2)
|
||||
unlocked_line.points = curve.get_baked_points()
|
||||
|
||||
line_particles.position = unlocked_line.points[unlocked_line.points.size()-1]
|
||||
@@ -529,10 +535,11 @@ func _on_scroll_container_gui_input(event: InputEvent) -> void:
|
||||
return
|
||||
if event.is_action_pressed("left_click"):
|
||||
is_scrolling = true
|
||||
@warning_ignore("integer_division")
|
||||
scroll_beginning_garden = scroll_container.scroll_horizontal / garden_size
|
||||
if tween:
|
||||
tween.stop()
|
||||
tween = null
|
||||
if scroll_tween:
|
||||
scroll_tween.stop()
|
||||
scroll_tween = null
|
||||
elif event.is_action_released("left_click"):
|
||||
is_scrolling = false
|
||||
var shift_value: int = scroll_container.scroll_horizontal - scroll_beginning_garden * garden_size
|
||||
@@ -546,19 +553,23 @@ func _on_scroll_container_gui_input(event: InputEvent) -> void:
|
||||
target_scroll += garden_size
|
||||
is_garden_changed = true
|
||||
right_audio_stream_player.play()
|
||||
tween = create_tween()
|
||||
tween.set_ease(Tween.EASE_OUT)
|
||||
tween.set_trans(Tween.TRANS_SPRING)
|
||||
tween.tween_property(scroll_container, "scroll_horizontal", target_scroll, 1)
|
||||
scroll_tween = create_tween()
|
||||
scroll_tween.set_ease(Tween.EASE_OUT)
|
||||
scroll_tween.set_trans(Tween.TRANS_SPRING)
|
||||
scroll_tween.tween_property(scroll_container, "scroll_horizontal", target_scroll, 1)
|
||||
if is_garden_changed:
|
||||
@warning_ignore("integer_division")
|
||||
var garden_ind: int = target_scroll / garden_size
|
||||
garden_parent.get_child(garden_ind).pop_animation()
|
||||
var garden: Garden = garden_parent.get_child(garden_ind)
|
||||
garden.pop_animation()
|
||||
|
||||
await tween.finished
|
||||
await scroll_tween.finished
|
||||
@warning_ignore("integer_division")
|
||||
scroll_beginning_garden = scroll_container.scroll_horizontal / garden_size
|
||||
|
||||
if is_scrolling and event is InputEventMouseMotion:
|
||||
scroll_container.scroll_horizontal -= event.relative.x
|
||||
var motion_event: InputEventMouseMotion = event
|
||||
scroll_container.scroll_horizontal -= int(motion_event.relative.x)
|
||||
|
||||
|
||||
func _on_back_button_pressed() -> void:
|
||||
@@ -566,6 +577,6 @@ func _on_back_button_pressed() -> void:
|
||||
get_tree().change_scene_to_file("res://sources/menus/brain/brain.tscn")
|
||||
|
||||
|
||||
func _on_area_2d_input_event(viewport, event, shape_idx):
|
||||
func _on_area_2d_input_event(_viewport: Node, event: InputEvent, _shape_idx: int) -> void:
|
||||
if event.is_action_pressed("left_click") and in_minigame_selection:
|
||||
_close_minigames_layout()
|
||||
|
||||
@@ -6,9 +6,9 @@ signal pressed()
|
||||
|
||||
var is_disabled: bool = false
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
area.connect("input_event", _on_click)
|
||||
|
||||
func _on_click(viewport, event, shape_idx):
|
||||
func _on_click(_viewport: Node, event: InputEvent, _shape_idx: int) -> void:
|
||||
if event.is_action_pressed("left_click") and not is_disabled:
|
||||
pressed.emit()
|
||||
|
||||
@@ -14,7 +14,7 @@ extends TextureButton
|
||||
@onready var placeholder: TextureRect = %Placeholder
|
||||
@onready var right_fx: RightFX = %RightFX
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
_set_base_color(base_color)
|
||||
_set_completed_color(completed_color)
|
||||
_set_text(text)
|
||||
|
||||
@@ -3,10 +3,13 @@ class_name LetterSegment
|
||||
|
||||
signal finished()
|
||||
|
||||
@onready var tracing_path: = $TracingPath
|
||||
@onready var tracing_effects: = $TracingEffects
|
||||
@onready var complete_particles: = $CompleteParticles
|
||||
@onready var complete_sound: = $CompleteAudioStreamPlayer
|
||||
const TracingPath: = preload("res://sources/look_and_learn/tracing_path.gd")
|
||||
const TracingEffects: = preload("res://sources/look_and_learn/tracing_effects.gd")
|
||||
|
||||
@onready var tracing_path: TracingPath = $TracingPath
|
||||
@onready var tracing_effects: TracingEffects = $TracingEffects
|
||||
@onready var complete_particles: GPUParticles2D = $CompleteParticles
|
||||
@onready var complete_sound: AudioStreamPlayer = $CompleteAudioStreamPlayer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
extends Control
|
||||
|
||||
const Gardens: = preload("res://sources/gardens/gardens.gd")
|
||||
const TracingManager: = preload("res://sources/look_and_learn/tracing_manager.gd")
|
||||
|
||||
@export var lesson_nb: = 1
|
||||
@export var current_button_pressed: = 0
|
||||
|
||||
@onready var animation_player: = $AnimationPlayer
|
||||
@onready var audio_player: = $AudioStreamPlayer
|
||||
@onready var video_player: = %VideoStreamPlayer
|
||||
@onready var image: = %Image
|
||||
@onready var grapheme_label: = %GraphemeLabel
|
||||
@onready var tracing_manager: = %TracingManager
|
||||
@onready var grapheme_particles: = $GraphemeParticles
|
||||
@onready var animation_player: AnimationPlayer = $AnimationPlayer
|
||||
@onready var audio_player: AudioStreamPlayer = $AudioStreamPlayer
|
||||
@onready var video_player: VideoStreamPlayer = %VideoStreamPlayer
|
||||
@onready var image: TextureRect = %Image
|
||||
@onready var grapheme_label: Label = %GraphemeLabel
|
||||
@onready var tracing_manager: TracingManager = %TracingManager
|
||||
@onready var grapheme_particles: GPUParticles2D = $GraphemeParticles
|
||||
|
||||
|
||||
const Gardens: = preload("res://sources/gardens/gardens.gd")
|
||||
|
||||
var gp_list: Array[Dictionary]
|
||||
|
||||
@@ -67,7 +70,7 @@ func setup() -> void:
|
||||
gp_display.append(gp_list[0])
|
||||
|
||||
grapheme_label.text = ""
|
||||
for gp in gp_display:
|
||||
for gp: Dictionary in gp_display:
|
||||
grapheme_label.text += "%s" % gp.Grapheme
|
||||
|
||||
|
||||
@@ -93,7 +96,7 @@ func play_images_and_sounds() -> void:
|
||||
|
||||
|
||||
func load_tracing() -> void:
|
||||
await tracing_manager.setup(gp_list[current_tracing]["Grapheme"])
|
||||
await tracing_manager.setup(gp_list[current_tracing]["Grapheme"] as String)
|
||||
current_tracing += 1
|
||||
|
||||
|
||||
@@ -135,7 +138,7 @@ func _on_audio_stream_player_finished() -> void:
|
||||
|
||||
func _on_tracing_manager_finished() -> void:
|
||||
if current_tracing < gp_list.size():
|
||||
await tracing_manager.setup(gp_list[current_tracing]["Grapheme"])
|
||||
await tracing_manager.setup(gp_list[current_tracing]["Grapheme"] as String)
|
||||
tracing_manager.start()
|
||||
current_tracing += 1
|
||||
else:
|
||||
|
||||
@@ -970,7 +970,6 @@ process_material = SubResource("ParticleProcessMaterial_vgnm5")
|
||||
texture = ExtResource("13_rp6w3")
|
||||
lifetime = 0.5
|
||||
|
||||
[connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_animation_player_animation_finished"]
|
||||
[connection signal="finished" from="AudioStreamPlayer" to="." method="_on_audio_stream_player_finished"]
|
||||
[connection signal="pressed" from="LeftContainer/MarginContainer/GardenButton" to="." method="_on_garden_button_pressed"]
|
||||
[connection signal="finished" from="Frame/Mask/ColorRect/TracingManager" to="." method="_on_tracing_manager_finished"]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
extends Node2D
|
||||
|
||||
@onready var particles_effect: = $TracingParticles
|
||||
@onready var sound_effect: = $TracingAudioStreamPlayer
|
||||
@onready var timer: = $Timer
|
||||
@onready var particles_effect: GPUParticles2D = $TracingParticles
|
||||
@onready var sound_effect: AudioStreamPlayer = $TracingAudioStreamPlayer
|
||||
@onready var timer: Timer = $Timer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
||||
@@ -6,8 +6,8 @@ const letter_segment_class: = preload("res://sources/look_and_learn/letter_segme
|
||||
|
||||
@export var label_settings: LabelSettings
|
||||
|
||||
@onready var lower_labels: = %LowerLabels
|
||||
@onready var upper_labels: = %UpperLabels
|
||||
@onready var lower_labels: HBoxContainer = %LowerLabels
|
||||
@onready var upper_labels: HBoxContainer = %UpperLabels
|
||||
|
||||
const tracing_data_folder: = "tracing_data/"
|
||||
const extension: = ".csv"
|
||||
@@ -18,8 +18,8 @@ func _process(_delta: float) -> void:
|
||||
|
||||
|
||||
func place_segments(labels: Array) -> void:
|
||||
for label in labels:
|
||||
for segment in label.get_children():
|
||||
for label: Label in labels:
|
||||
for segment: LetterSegment in label.get_children():
|
||||
segment.global_position = label.global_position + label.size / 2.0 + Vector2(0.0, 72.0)
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ func setup(grapheme: String) -> void:
|
||||
var tracings: = _get_letter_tracings(letter)
|
||||
|
||||
if tracings.lower:
|
||||
setup_tracing(letter, tracings["lower"], lower_labels, true)
|
||||
setup_tracing(letter, tracings["lower"] as Array, lower_labels, true)
|
||||
|
||||
if tracings.upper:
|
||||
setup_tracing(letter, tracings["upper"], upper_labels, false)
|
||||
setup_tracing(letter, tracings["upper"] as Array, upper_labels, false)
|
||||
|
||||
|
||||
func setup_tracing(letter: String, letter_tracings: Array, parent: Control, lower: bool) -> void:
|
||||
@@ -126,12 +126,12 @@ func start() -> void:
|
||||
await demo_labels(upper_labels)
|
||||
await start_labels(upper_labels)
|
||||
|
||||
emit_signal("finished")
|
||||
finished.emit()
|
||||
|
||||
|
||||
func start_labels(labels_parent: Control) -> void:
|
||||
for letter in labels_parent.get_children():
|
||||
for segment in letter.get_children():
|
||||
for segment: LetterSegment in letter.get_children():
|
||||
segment.start()
|
||||
await segment.finished
|
||||
letter.move_child(segment, 0)
|
||||
@@ -139,6 +139,6 @@ func start_labels(labels_parent: Control) -> void:
|
||||
|
||||
func demo_labels(labels_parent: Control) -> void:
|
||||
for letter in labels_parent.get_children():
|
||||
for segment in letter.get_children():
|
||||
for segment: LetterSegment in letter.get_children():
|
||||
segment.demo()
|
||||
await segment.finished
|
||||
|
||||
@@ -10,11 +10,11 @@ signal demo_finished
|
||||
|
||||
@export var color_gradient: Gradient
|
||||
|
||||
@onready var line: = $Line2D
|
||||
@onready var guide: = $GuidePathFollow
|
||||
@onready var hand: = $HandPathFollow2D
|
||||
@onready var guide_sprite: = $GuidePathFollow/Guide
|
||||
@onready var hand_sprite: = $HandPathFollow2D/Hand
|
||||
@onready var line: Line2D = $Line2D
|
||||
@onready var guide: PathFollow2D = $GuidePathFollow
|
||||
@onready var hand: PathFollow2D = $HandPathFollow2D
|
||||
@onready var guide_sprite: Sprite2D = $GuidePathFollow/Guide
|
||||
@onready var hand_sprite: Sprite2D = $HandPathFollow2D/Hand
|
||||
|
||||
var curve_points: PackedVector2Array
|
||||
@onready var remaining_curve: = Curve2D.new()
|
||||
@@ -30,7 +30,7 @@ func _ready() -> void:
|
||||
hand_sprite.visible = false
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
func _exit_tree() -> void:
|
||||
pass
|
||||
#if is_instance_valid(remaining_curve):
|
||||
#remaining_curve.free()
|
||||
@@ -66,7 +66,7 @@ func _tracing_process() -> void:
|
||||
while touch_positions.size() > 0:
|
||||
var touch_position: Vector2 = touch_positions.pop_front()
|
||||
var touch_vector: Vector2 = touch_position - guide.global_position
|
||||
var current_offset = 0.0
|
||||
var current_offset: = 0.0
|
||||
if touch_vector.length() < distance:
|
||||
var target_offset: float = remaining_curve.get_closest_offset(touch_position - global_position)
|
||||
if target_offset > current_offset and target_offset - current_offset <= distance:
|
||||
@@ -76,11 +76,11 @@ func _tracing_process() -> void:
|
||||
should_play_effects = true
|
||||
var remove_up_to: = 0
|
||||
for i in curve_points.size():
|
||||
var offset = curve.get_closest_offset(curve_points[i])
|
||||
var offset: = curve.get_closest_offset(curve_points[i])
|
||||
if offset > guide.progress:
|
||||
remove_up_to = i
|
||||
break
|
||||
for i in int(min(remove_up_to, curve_points.size() - 2)):
|
||||
for i: int in min(remove_up_to, curve_points.size() - 2):
|
||||
curve_points.remove_at(0)
|
||||
remaining_curve.remove_point(0)
|
||||
|
||||
@@ -106,7 +106,7 @@ func setup(points: Array) -> void:
|
||||
line.width = 50.0
|
||||
|
||||
var smooth_points: = _smooth_points(points)
|
||||
for point in smooth_points:
|
||||
for point: Vector2 in smooth_points:
|
||||
curve.add_point(point)
|
||||
|
||||
guide.progress = 0.0
|
||||
@@ -120,12 +120,12 @@ func setup(points: Array) -> void:
|
||||
|
||||
|
||||
func _smooth_points(points: Array) -> Array:
|
||||
return Bezier.bezier_sampling(points, max(points_per_curve, points.size()))
|
||||
return Bezier.bezier_sampling(points, max(points_per_curve, points.size()) as int)
|
||||
|
||||
|
||||
func set_points(points: Array) -> void:
|
||||
curve.clear_points()
|
||||
for point in points:
|
||||
for point: Vector2 in points:
|
||||
curve.add_point(point)
|
||||
|
||||
|
||||
|
||||
@@ -31,9 +31,9 @@ func _ready() -> void:
|
||||
var current_version: Dictionary = UserDataManager.get_device_settings().language_versions.get(device_language, {})
|
||||
|
||||
# Gets the info of the language pack on the server
|
||||
var res = await ServerManager.get_language_pack_url(device_language)
|
||||
var res: = await ServerManager.get_language_pack_url(device_language)
|
||||
if res.code == 200:
|
||||
server_version = Time.get_datetime_dict_from_datetime_string(res.body.last_modified, false)
|
||||
server_version = Time.get_datetime_dict_from_datetime_string(res.body.last_modified as String, false)
|
||||
else:
|
||||
# Offline mode, if a pack is already downloaded, go to next scene
|
||||
if DirAccess.dir_exists_absolute(current_language_path):
|
||||
@@ -62,18 +62,20 @@ func _ready() -> void:
|
||||
|
||||
# Download the pack
|
||||
http_request.set_download_file(user_language_resources_path.path_join(device_language + ".zip"))
|
||||
http_request.request(res.body.url)
|
||||
http_request.request(res.body.url as String)
|
||||
else:
|
||||
download_bar.value = 1
|
||||
extract_bar.value = 1
|
||||
_go_to_main_menu()
|
||||
|
||||
|
||||
func _process(delta):
|
||||
func _process(_delta: float) -> void:
|
||||
if http_request.get_body_size() > 0:
|
||||
var max = int(http_request.get_body_size()/1024)
|
||||
var current = int(http_request.get_downloaded_bytes()/1024)
|
||||
download_bar.max_value = max
|
||||
@warning_ignore("integer_division")
|
||||
var maximum: = int(http_request.get_body_size()/1024)
|
||||
@warning_ignore("integer_division")
|
||||
var current: = int(http_request.get_downloaded_bytes()/1024)
|
||||
download_bar.max_value = maximum
|
||||
download_bar.value = current
|
||||
download_info.text = str(current) + "KB/" + str(max) + "KB"
|
||||
|
||||
@@ -128,7 +130,7 @@ func _go_to_main_menu() -> void:
|
||||
|
||||
|
||||
func _delete_dir(path: String) -> void:
|
||||
var dir = DirAccess.open(path)
|
||||
var dir: = DirAccess.open(path)
|
||||
for file in dir.get_files():
|
||||
dir.remove(file)
|
||||
for subfolder in dir.get_directories():
|
||||
@@ -136,7 +138,7 @@ func _delete_dir(path: String) -> void:
|
||||
dir.remove(subfolder)
|
||||
|
||||
|
||||
func _on_http_request_request_completed(result, response_code, headers, body):
|
||||
func _on_http_request_request_completed(_result: int, response_code: int, _headers: PackedStringArray, _body: PackedByteArray) -> void:
|
||||
if response_code == 200:
|
||||
mutex = Mutex.new()
|
||||
thread = Thread.new()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extends Control
|
||||
|
||||
@onready var speech_player : AudioStreamPlayer = $SpeechPlayer
|
||||
@onready var sprite: = $Sprite
|
||||
@onready var sprite: AnimatedSprite2D = $Sprite
|
||||
|
||||
var tuto_speech :AudioStreamMP3
|
||||
var feedback_speech :AudioStreamMP3
|
||||
@@ -17,13 +17,13 @@ var isSpeaking : bool = false :
|
||||
var elapsedTime : float = 0.0
|
||||
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
tuto_speech = Database.load_external_sound(Database.get_kalulu_speech_path("title_screen", "tuto_welcome_oneshot"))
|
||||
feedback_speech = Database.load_external_sound(Database.get_kalulu_speech_path("title_screen", "feedback_welcome"))
|
||||
_play_speech(tuto_speech)
|
||||
|
||||
|
||||
func _process(delta):
|
||||
func _process(delta: float) -> void:
|
||||
if not visible:
|
||||
return
|
||||
|
||||
@@ -35,7 +35,7 @@ func _process(delta):
|
||||
if elapsedTime > 20:
|
||||
start_speech()
|
||||
|
||||
func _play_speech(speech : AudioStream):
|
||||
func _play_speech(speech : AudioStream) -> void:
|
||||
if not speech:
|
||||
push_warning("Speech not found")
|
||||
isSpeaking = false
|
||||
@@ -50,11 +50,11 @@ func _play_speech(speech : AudioStream):
|
||||
isSpeaking = false
|
||||
|
||||
|
||||
func start_speech():
|
||||
func start_speech() -> void:
|
||||
_play_speech(feedback_speech)
|
||||
|
||||
|
||||
func stop_speech():
|
||||
func stop_speech() -> void:
|
||||
sprite.stop()
|
||||
speech_player.stop()
|
||||
isSpeaking = false
|
||||
|
||||
@@ -2,7 +2,7 @@ extends OptionButton
|
||||
|
||||
var items : Array[String]
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
# Adds the supported locales to the field
|
||||
var idx: int = 0
|
||||
for language_locale in DeviceSettings.supported_locales:
|
||||
@@ -22,9 +22,9 @@ func _ready():
|
||||
|
||||
|
||||
func get_selected_language() -> String:
|
||||
var id = get_selected_id()
|
||||
var id: = get_selected_id()
|
||||
return items[id]
|
||||
|
||||
|
||||
func _on_item_selected(index: int):
|
||||
func _on_item_selected(index: int) -> void:
|
||||
UserDataManager.set_language(items[index])
|
||||
|
||||
@@ -13,13 +13,13 @@ signal logged_in
|
||||
|
||||
var account_type: TeacherSettings.AccountType
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
email_field.text_changed.connect(_hide_login_error)
|
||||
password_field.text_changed.connect(_hide_login_error)
|
||||
device_id_field.value_changed.connect(_hide_login_error)
|
||||
|
||||
|
||||
func show_form(is_teacher : bool):
|
||||
func show_form(is_teacher : bool) -> void:
|
||||
self.show()
|
||||
|
||||
if is_teacher:
|
||||
@@ -35,13 +35,13 @@ func show_form(is_teacher : bool):
|
||||
parent_label.show()
|
||||
|
||||
|
||||
func _hide_login_error(_value):
|
||||
func _hide_login_error(_value: Variant) -> void:
|
||||
if login_message.visible:
|
||||
login_message.hide()
|
||||
|
||||
|
||||
func _on_login_form_validator_control_validated(control, passed, messages):
|
||||
var label = find_child(control.name + "Error", true, false) as Label
|
||||
func _on_login_form_validator_control_validated(control: Control, passed: Variant, messages: PackedStringArray) -> void:
|
||||
var label: = find_child(control.name + "Error", true, false) as Label
|
||||
if not label:
|
||||
return
|
||||
if passed:
|
||||
@@ -57,10 +57,10 @@ func _on_validate_button_pressed() -> void:
|
||||
return
|
||||
|
||||
# Request server for login
|
||||
var res = await ServerManager.login(account_type, int(device_id_field.value), email_field.text, password_field.text)
|
||||
var res: = await ServerManager.login(account_type, int(device_id_field.value), email_field.text, password_field.text)
|
||||
if res.code == 200:
|
||||
# Login
|
||||
if UserDataManager.login(res.body):
|
||||
if UserDataManager.login(res.body as Dictionary):
|
||||
logged_in.emit()
|
||||
else:
|
||||
login_message.visible = true
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
extends Control
|
||||
|
||||
const Kalulu: = preload("res://sources/menus/main/kalulu.gd")
|
||||
const LoginForm: = preload("res://sources/menus/main/login.gd")
|
||||
|
||||
const adult_check_scene_path := "res://sources/menus/adult_check/adult_check.tscn"
|
||||
const package_loader_scene_path: = "res://sources/menus/language_selection/package_downloader.tscn"
|
||||
|
||||
@@ -7,21 +10,21 @@ const package_loader_scene_path: = "res://sources/menus/language_selection/packa
|
||||
@onready var teacher_label : Label = $Informations/TeacherValue
|
||||
@onready var device_id_label : Label = $Informations/DeviceIDValue
|
||||
|
||||
@onready var kalulu : Control = $Kalulu
|
||||
@onready var kalulu : Kalulu = $Kalulu
|
||||
@onready var user_selection : Control = $UserSelection
|
||||
@onready var login_form : Control = %LoginForm
|
||||
@onready var login_form : LoginForm = %LoginForm
|
||||
@onready var interface_left : MarginContainer = %InterfaceLeft
|
||||
@onready var keyboard_spacer: KeyboardSpacer = %KeyboardSpacer
|
||||
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
version_label.text = ProjectSettings.get_setting("application/config/version")
|
||||
teacher_label.text = UserDataManager.get_device_settings().teacher
|
||||
device_id_label.text = str(UserDataManager.get_device_settings().device_id)
|
||||
OpeningCurtain.open()
|
||||
|
||||
|
||||
func _on_main_button_pressed():
|
||||
func _on_main_button_pressed() -> void:
|
||||
if UserDataManager.get_device_settings().teacher:
|
||||
_on_login_in()
|
||||
else:
|
||||
@@ -31,31 +34,31 @@ func _on_main_button_pressed():
|
||||
interface_left.show()
|
||||
|
||||
|
||||
func _on_back_button_pressed():
|
||||
func _on_back_button_pressed() -> void:
|
||||
keyboard_spacer.hide()
|
||||
user_selection.hide()
|
||||
kalulu.show()
|
||||
interface_left.hide()
|
||||
|
||||
|
||||
func _on_sign_in_teacher_pressed():
|
||||
func _on_sign_in_teacher_pressed() -> void:
|
||||
user_selection.hide()
|
||||
kalulu.hide()
|
||||
keyboard_spacer.show()
|
||||
login_form.show_form(true)
|
||||
|
||||
|
||||
func _on_sign_in_parent_pressed():
|
||||
func _on_sign_in_parent_pressed() -> void:
|
||||
user_selection.hide()
|
||||
kalulu.hide()
|
||||
keyboard_spacer.show()
|
||||
login_form.show_form(false)
|
||||
|
||||
|
||||
func _on_register_pressed():
|
||||
func _on_register_pressed() -> void:
|
||||
await OpeningCurtain.close()
|
||||
get_tree().change_scene_to_file(adult_check_scene_path)
|
||||
|
||||
|
||||
func _on_login_in():
|
||||
func _on_login_in() -> void:
|
||||
get_tree().change_scene_to_file(package_loader_scene_path)
|
||||
|
||||
@@ -7,10 +7,10 @@ func _go_to_main_menu() -> void:
|
||||
get_tree().change_scene_to_file(main_menu_scene_path)
|
||||
|
||||
|
||||
func _on_timer_timeout():
|
||||
func _on_timer_timeout() -> void:
|
||||
_go_to_main_menu()
|
||||
|
||||
|
||||
func _on_gui_input(event):
|
||||
func _on_gui_input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("left_click"):
|
||||
_go_to_main_menu()
|
||||
|
||||
@@ -5,7 +5,7 @@ func play_gp(gp: Dictionary) -> void:
|
||||
if not gp or gp.is_empty():
|
||||
return
|
||||
|
||||
var phoneme_audiostream = Database.load_external_sound(Database.get_gp_sound_path(gp)) as AudioStream
|
||||
var phoneme_audiostream: = Database.load_external_sound(Database.get_gp_sound_path(gp)) as AudioStream
|
||||
#var phoneme_audiostream = Database.get_gp_look_and_learn_sound(phoneme)
|
||||
if not phoneme_audiostream:
|
||||
push_warning("AudioStream not found for gp %s " % gp)
|
||||
|
||||
@@ -3,6 +3,7 @@ extends Control
|
||||
class_name Minigame
|
||||
|
||||
const Gardens: = preload("res://sources/gardens/gardens.gd")
|
||||
const Fireworks: = preload("res://sources/utils/fx/fireworks.gd")
|
||||
|
||||
enum Type {
|
||||
jellyfish,
|
||||
@@ -42,9 +43,9 @@ enum Type {
|
||||
@export var errors_before_help_speech: int = 2
|
||||
@export var errors_before_highlight: int = 3
|
||||
|
||||
@onready var minigame_ui: = $MinigameUI
|
||||
@onready var minigame_ui: MinigameUI = $MinigameUI
|
||||
@onready var audio_player: MinigameAudioStreamPlayer = $AudioStreamPlayer
|
||||
@onready var fireworks: = $Fireworks
|
||||
@onready var fireworks: Fireworks = $Fireworks
|
||||
|
||||
# Game root shall contain all the game tree.
|
||||
# This node is pausable unlike the others, so the pause button can stop the game but not other essential processes.
|
||||
@@ -123,11 +124,11 @@ func _ready() -> void:
|
||||
|
||||
# Difficulty
|
||||
if UserDataManager._student_difficulty:
|
||||
difficulty = UserDataManager.get_difficulty_for_minigame(Type.keys()[minigame_name])
|
||||
difficulty = UserDataManager.get_difficulty_for_minigame(Type.keys()[minigame_name] as String)
|
||||
|
||||
intro_kalulu_speech = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name], "intro"))
|
||||
help_kalulu_speech = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name], "help"))
|
||||
win_kalulu_speech = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name], "end"))
|
||||
intro_kalulu_speech = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "intro"))
|
||||
help_kalulu_speech = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "help"))
|
||||
win_kalulu_speech = Database.load_external_sound(Database.get_kalulu_speech_path(Type.keys()[minigame_name] as String, "end"))
|
||||
lose_kalulu_speech = Database.load_external_sound(Database.get_kalulu_speech_path("minigame", "lose"))
|
||||
|
||||
if not Engine.is_editor_hint():
|
||||
@@ -199,7 +200,7 @@ func _win() -> void:
|
||||
UserDataManager.update_remediation_scores(scores)
|
||||
|
||||
# Difficulty
|
||||
UserDataManager.update_difficulty_for_minigame(Type.keys()[minigame_name], true)
|
||||
UserDataManager.update_difficulty_for_minigame(Type.keys()[minigame_name] as String, true)
|
||||
|
||||
audio_player.stream = win_sound_fx
|
||||
audio_player.play()
|
||||
@@ -225,7 +226,7 @@ func _lose() -> void:
|
||||
UserDataManager.update_remediation_scores(scores)
|
||||
|
||||
# Difficulty
|
||||
UserDataManager.update_difficulty_for_minigame(Type.keys()[minigame_name], false)
|
||||
UserDataManager.update_difficulty_for_minigame(Type.keys()[minigame_name] as String, false)
|
||||
|
||||
audio_player.stream = lose_sound_fx
|
||||
audio_player.play()
|
||||
@@ -241,7 +242,7 @@ func _lose() -> void:
|
||||
#region Logs
|
||||
|
||||
func _save_logs() -> void:
|
||||
LessonLogger.save_logs(logs, UserDataManager.get_student_folder(), Type.keys()[minigame_name], lesson_nb, Time.get_time_string_from_system())
|
||||
LessonLogger.save_logs(logs, UserDataManager.get_student_folder(), Type.keys()[minigame_name] as String, lesson_nb, Time.get_time_string_from_system())
|
||||
_reset_logs()
|
||||
|
||||
|
||||
@@ -264,7 +265,8 @@ func _log_new_response(response: Dictionary, current_stimulus: Dictionary) -> vo
|
||||
"max_number_of_lives": max_number_of_lives,
|
||||
}
|
||||
|
||||
logs["answers"].append(response_log)
|
||||
var answers: Array = logs["answers"]
|
||||
answers.append(response_log)
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -275,7 +277,7 @@ func _get_stimulus_score(stimulus: Dictionary) -> int:
|
||||
var score: int = 0
|
||||
if stimulus.has("GPs"):
|
||||
for gp: Dictionary in stimulus.GPs:
|
||||
score += UserDataManager.get_GP_remediation_score(gp.ID)
|
||||
score += UserDataManager.get_GP_remediation_score(gp.ID as int)
|
||||
return score
|
||||
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ const show_sound := preload("res://assets/kalulu/audio/ui_button_on.mp3")
|
||||
const hide_sound := preload("res://assets/kalulu/audio/ui_button_off.mp3")
|
||||
|
||||
|
||||
@onready var kalulu_sprite: = $KaluluSprite
|
||||
@onready var audio_player: = $AudioStreamPlayer
|
||||
@onready var kalulu_sprite: AnimatedSprite2D = $KaluluSprite
|
||||
@onready var audio_player: AudioStreamPlayer = $AudioStreamPlayer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
||||
@@ -12,6 +12,7 @@ signal kalulu_speech_ended
|
||||
|
||||
signal pause_ended
|
||||
|
||||
const Kalulu: = preload("res://sources/minigames/base/kalulu.gd")
|
||||
const empty_lives_icon: = preload("res://assets/minigames/minigame_ui/graphic/life_empty.png")
|
||||
const full_lives_icon: = preload("res://assets/minigames/minigame_ui/graphic/life.png")
|
||||
|
||||
@@ -41,15 +42,15 @@ const full_lives_icon: = preload("res://assets/minigames/minigame_ui/graphic/lif
|
||||
@onready var center_menu: MarginContainer = %CenterMenu
|
||||
|
||||
# Kalulu
|
||||
@onready var kalulu: Control = %Kalulu
|
||||
@onready var kalulu: Kalulu = %Kalulu
|
||||
|
||||
@onready var progression_container: = %ProgressionContainer
|
||||
@onready var progression_gauge: = %ProgressionGauge
|
||||
@onready var model_progression_rect: = %ProgressionIconsRect
|
||||
@onready var lives_container: = %LivesContainer
|
||||
@onready var model_lives_rect: = %LivesIconsRect
|
||||
@onready var progression_container: VBoxContainer = %ProgressionContainer
|
||||
@onready var progression_gauge: NinePatchRect = %ProgressionGauge
|
||||
@onready var model_progression_rect: TextureRect = %ProgressionIconsRect
|
||||
@onready var lives_container: HBoxContainer = %LivesContainer
|
||||
@onready var model_lives_rect: TextureRect = %LivesIconsRect
|
||||
|
||||
@onready var animation_player: = $AnimationPlayer
|
||||
@onready var animation_player: AnimationPlayer = $AnimationPlayer
|
||||
|
||||
var is_paused: bool = false
|
||||
|
||||
@@ -93,7 +94,7 @@ func set_maximum_number_of_lives(new_max_number_of_lives: int) -> void:
|
||||
if i >= new_max_number_of_lives:
|
||||
lives_rects[i].queue_free()
|
||||
for i in range(lives_rects.size(), new_max_number_of_lives):
|
||||
var new_lives_rect: = model_lives_rect.duplicate()
|
||||
var new_lives_rect: TextureRect = model_lives_rect.duplicate()
|
||||
new_lives_rect.texture = full_lives_icon
|
||||
lives_container.add_child(new_lives_rect)
|
||||
model_lives_rect.visible = new_max_number_of_lives >= 1
|
||||
@@ -107,10 +108,11 @@ func set_number_of_lives(new_number_of_lives: int) -> void:
|
||||
set_maximum_number_of_lives(new_number_of_lives)
|
||||
var lives_rects: = lives_container.get_children()
|
||||
for i in max_lives:
|
||||
var life_rect: TextureRect = lives_rects[i]
|
||||
if i < max_lives - new_number_of_lives:
|
||||
lives_rects[i].texture = empty_lives_icon
|
||||
life_rect.texture = empty_lives_icon
|
||||
else:
|
||||
lives_rects[i].texture = full_lives_icon
|
||||
life_rect.texture = full_lives_icon
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -125,7 +127,7 @@ func set_max_progression(new_max_progression: int) -> void:
|
||||
if i >= new_max_progression:
|
||||
progression_rects[i].queue_free()
|
||||
for i in range(progression_rects.size(), new_max_progression):
|
||||
var new_progression_rect: = model_progression_rect.duplicate()
|
||||
var new_progression_rect: TextureRect = model_progression_rect.duplicate()
|
||||
new_progression_rect.show()
|
||||
new_progression_rect.texture = empty_progression_icon
|
||||
progression_container.add_child(new_progression_rect)
|
||||
@@ -140,10 +142,11 @@ func set_progression(new_progression: int) -> void:
|
||||
set_max_progression(new_progression)
|
||||
var progression_rects: = progression_container.get_children()
|
||||
for i in max_progression:
|
||||
var progression_rect: TextureRect = progression_rects[i]
|
||||
if i < new_progression:
|
||||
progression_rects[i].texture = full_progression_icon
|
||||
progression_rect.texture = full_progression_icon
|
||||
else:
|
||||
progression_rects[i].texture = empty_progression_icon
|
||||
progression_rect.texture = empty_progression_icon
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -138,9 +138,10 @@ func get_GP_for_lesson(lesson_nb: int, distinct: bool, only_new: bool = false, o
|
||||
var result: = db.query_result
|
||||
|
||||
if with_other_phonemes:
|
||||
for GP in result:
|
||||
for GP: Dictionary in result:
|
||||
if GP.OtherPhonemes:
|
||||
GP.OtherPhonemes = GP.OtherPhonemes.split(",")
|
||||
var phonemes: String = GP.OtherPhonemes
|
||||
GP.OtherPhonemes = phonemes.split(",")
|
||||
|
||||
return result
|
||||
|
||||
@@ -193,7 +194,7 @@ func get_syllables_for_lesson(lesson_nb: int, only_new: = false) -> Array[Dictio
|
||||
|
||||
var res : = db.query_result
|
||||
for syllable: Dictionary in res:
|
||||
syllable.GPs = get_GPs_from_syllable(syllable.ID)
|
||||
syllable.GPs = get_GPs_from_syllable(syllable.ID as int)
|
||||
var phonemes: Array[String] = []
|
||||
for GP: Dictionary in syllable.GPs:
|
||||
phonemes.append(GP.Phoneme)
|
||||
@@ -235,9 +236,11 @@ FROM Words
|
||||
|
||||
# Parse the GPs IDs
|
||||
for word: Dictionary in res:
|
||||
word.GPs = []
|
||||
for GPID in word.GPs_IDs.split(","):
|
||||
word.GPs.append({ID = int(GPID)})
|
||||
var word_GPs: = []
|
||||
var word_gps_id: String = word.GPs_IDs
|
||||
for GPID: String in word_gps_id.split(","):
|
||||
word_GPs.append({ID = int(GPID)})
|
||||
word.GPs = word_GPs
|
||||
word.erase("GPs_IDs")
|
||||
|
||||
return res
|
||||
@@ -284,8 +287,8 @@ func get_sentences_by_lessons() -> Dictionary:
|
||||
var sentences: = db.query_result
|
||||
|
||||
for sentence in sentences:
|
||||
var lesson_nb: = get_min_lesson_for_sentence_id(sentence.ID)
|
||||
var a = sentences_by_lesson.get(lesson_nb, [])
|
||||
var lesson_nb: = get_min_lesson_for_sentence_id(sentence.ID as int)
|
||||
var a: Array = sentences_by_lesson.get(lesson_nb, [])
|
||||
a.append(sentence)
|
||||
sentences_by_lesson[lesson_nb] = a
|
||||
return sentences_by_lesson
|
||||
@@ -300,7 +303,7 @@ func get_sentences(p_lesson_nb: int, only_new: = false, sentences_by_lesson: = {
|
||||
|
||||
var ret: Array = []
|
||||
for i in p_lesson_nb:
|
||||
ret.append_array(sentences_by_lesson.get(i, []))
|
||||
ret.append_array(sentences_by_lesson.get(i, []) as Array)
|
||||
return ret
|
||||
|
||||
|
||||
@@ -417,7 +420,7 @@ func get_min_lesson_for_word_id(word_id: int) -> int:
|
||||
ORDER BY Position", [word_id])
|
||||
var m: = -1
|
||||
for result in db.query_result:
|
||||
var i: = Database.get_min_lesson_for_gp_id(result.GPID)
|
||||
var i: = Database.get_min_lesson_for_gp_id(result.GPID as int)
|
||||
if i < 0:
|
||||
m = -1
|
||||
break
|
||||
@@ -459,10 +462,10 @@ func get_audio_stream_for_path(path: String) -> AudioStream:
|
||||
|
||||
func get_audio_stream_for_word(ID: int) -> AudioStream:
|
||||
var GPs: = get_GP_from_word(ID)
|
||||
var file_name: = _phoneme_to_string(GPs[0].Phoneme)
|
||||
var file_name: = _phoneme_to_string(GPs[0].Phoneme as String)
|
||||
for i in range(1, GPs.size()):
|
||||
var GP = GPs[i]
|
||||
file_name += "-" + _phoneme_to_string(GP.Phoneme)
|
||||
var GP: Dictionary = GPs[i]
|
||||
file_name += "-" + _phoneme_to_string(GP.Phoneme as String)
|
||||
file_name += ".mp3"
|
||||
return load(words_path + file_name)
|
||||
|
||||
@@ -498,8 +501,8 @@ func get_gp_look_and_learn_sound(gp: Dictionary) -> AudioStream:
|
||||
if ResourceLoader.exists(path):
|
||||
return load(path)
|
||||
else:
|
||||
var file = FileAccess.open(path, FileAccess.READ)
|
||||
var sound = AudioStreamMP3.new()
|
||||
var file: = FileAccess.open(path, FileAccess.READ)
|
||||
var sound: = AudioStreamMP3.new()
|
||||
sound.data = file.get_buffer(file.get_length())
|
||||
return sound
|
||||
|
||||
@@ -564,192 +567,6 @@ func _phoneme_to_string(phoneme: String) -> String:
|
||||
return "cap." + phoneme.to_lower()
|
||||
|
||||
|
||||
# Import data from previous Kalulu version
|
||||
|
||||
func _import_gps() -> void:
|
||||
var file = FileAccess.open("res://data3/gp_list.json", FileAccess.READ)
|
||||
var dict = JSON.parse_string(file.get_line())
|
||||
for e in dict.values():
|
||||
var g = e.GRAPHEME
|
||||
var p = e.PHONEME
|
||||
db.query_with_bindings("SELECT * FROM GPs WHERE Grapheme=? AND Phoneme=?", [g, p])
|
||||
if db.query_result.is_empty():
|
||||
var type = 0
|
||||
if e.CV == "V":
|
||||
type = 1
|
||||
elif e.CV == "C":
|
||||
type = 2
|
||||
db.insert_row("GPs", {Grapheme=g, Phoneme=p, Type=type})
|
||||
db.query_with_bindings("SELECT * FROM GPs WHERE Grapheme=? AND Phoneme=?", [g, p])
|
||||
print(db.query_result)
|
||||
|
||||
|
||||
func _import_look_and_learn_data() -> void:
|
||||
var file = FileAccess.open("res://data3/gp_list.json", FileAccess.READ)
|
||||
var dict = JSON.parse_string(file.get_line())
|
||||
for e in dict.values():
|
||||
var file_path: = "res://data3/".path_join(look_and_learn_images).path_join(e.IMAGE) + image_extension
|
||||
DirAccess.copy_absolute(file_path, get_gp_look_and_learn_image_path({
|
||||
Grapheme = e.GRAPHEME,
|
||||
Phoneme = e.PHONEME,
|
||||
}))
|
||||
file_path = base_path.path_join(language).path_join(look_and_learn_sounds).path_join(e.AUDIO) + sound_extension
|
||||
DirAccess.copy_absolute(file_path, get_gp_look_and_learn_sound_path({
|
||||
Grapheme = e.GRAPHEME,
|
||||
Phoneme = e.PHONEME,
|
||||
}))
|
||||
file_path = (base_path.path_join(language).path_join(look_and_learn_videos).trim_suffix("/") + "s").path_join(e.FILENAME) + "_wide" + video_extension
|
||||
DirAccess.copy_absolute(file_path, get_gp_look_and_learn_video_path({
|
||||
Grapheme = e.GRAPHEME,
|
||||
Phoneme = e.PHONEME,
|
||||
}))
|
||||
|
||||
|
||||
func _update_gps_with_type() -> void:
|
||||
var file = FileAccess.open("res://gp_list.json", FileAccess.READ)
|
||||
var dict = JSON.parse_string(file.get_line())
|
||||
for e in dict.values():
|
||||
var g = e.GRAPHEME
|
||||
var p = e.PHONEME
|
||||
db.query_with_bindings("SELECT * FROM GPs WHERE Grapheme=? AND Phoneme=?", [g, p])
|
||||
var id = db.query_result[0].ID
|
||||
var type = 0
|
||||
if e.CV == "V":
|
||||
type = 1
|
||||
elif e.CV == "C":
|
||||
type = 2
|
||||
db.query_with_bindings("UPDATE GPs SET Type=? WHERE id=?", [type, id])
|
||||
|
||||
|
||||
func _import_syllables() -> void:
|
||||
var file = FileAccess.open("res://data3/words_list.json", FileAccess.READ)
|
||||
var dict = JSON.parse_string(file.get_line())
|
||||
|
||||
for e in dict.values():
|
||||
if e.NB_GRAPHEME == 2 and e.NB_LETTER <= 3:
|
||||
|
||||
# Inserts syllable
|
||||
db.query_with_bindings("SELECT * FROM Syllables WHERE Syllable=?", [e.GRAPHEME])
|
||||
if db.query_result.is_empty():
|
||||
db.insert_row("Syllables", {Syllable=e.GRAPHEME})
|
||||
|
||||
# Inserts GPs in syllable
|
||||
db.query_with_bindings("SELECT * FROM Syllables WHERE Syllable=?", [e.GRAPHEME])
|
||||
var syllable_id = db.query_result[0]["ID"]
|
||||
|
||||
# Checks if GPsInSyllables is already inserted
|
||||
db.query_with_bindings("SELECT ID FROM GPsInSyllables WHERE SyllableID=?", [syllable_id])
|
||||
if db.query_result.is_empty():
|
||||
var GP_list_str: String = e.GPMATCH
|
||||
var GP_list: = GP_list_str.split(".")
|
||||
|
||||
for i in GP_list.size():
|
||||
var GP_str = GP_list[i]
|
||||
var GP = GP_str.split("-")
|
||||
|
||||
# Checks if GP exists
|
||||
db.query_with_bindings("SELECT * FROM GPs WHERE Grapheme=? AND Phoneme=?", [GP[0], GP[1]])
|
||||
if db.query_result.is_empty():
|
||||
push_error("GP not found for " + GP_str)
|
||||
continue
|
||||
|
||||
var GP_id = db.query_result[0]["ID"]
|
||||
db.insert_row("GPsInSyllables", {
|
||||
SyllableID = syllable_id,
|
||||
GPID = GP_id,
|
||||
Position = i,
|
||||
})
|
||||
|
||||
|
||||
func _import_words() -> void:
|
||||
var file = FileAccess.open("res://data3/words_list.json", FileAccess.READ)
|
||||
var dict = JSON.parse_string(file.get_line())
|
||||
for e in dict.values():
|
||||
db.query_with_bindings("SELECT * FROM Words WHERE Word=?", [e.GRAPHEME])
|
||||
if db.query_result.is_empty():
|
||||
db.insert_row("Words", {Word=e.GRAPHEME})
|
||||
db.query_with_bindings("SELECT * FROM Words WHERE Word=?", [e.GRAPHEME])
|
||||
var word_id = db.query_result[0]["ID"]
|
||||
var GP_list_str: String = e.GPMATCH
|
||||
var GP_list: = GP_list_str.split(".")
|
||||
for i in GP_list.size():
|
||||
var GP_str = GP_list[i]
|
||||
var GP = GP_str.split("-")
|
||||
db.query_with_bindings("SELECT * FROM GPs WHERE Grapheme=? AND Phoneme=?", [GP[0], GP[1]])
|
||||
var GP_id = db.query_result[0]["ID"]
|
||||
db.insert_row("GPsInWords", {
|
||||
WordID = word_id,
|
||||
GPID = GP_id,
|
||||
Position = i,
|
||||
})
|
||||
|
||||
|
||||
func _import_lessons() -> void:
|
||||
var file = FileAccess.open("res://data3/gp_list.json", FileAccess.READ)
|
||||
var dict = JSON.parse_string(file.get_line())
|
||||
for e in dict.values():
|
||||
var g = e.GRAPHEME
|
||||
var p = e.PHONEME
|
||||
db.query_with_bindings("SELECT * FROM GPs WHERE Grapheme=? AND Phoneme=?", [g, p])
|
||||
var GP_id = db.query_result[0]["ID"]
|
||||
var lesson_nb: = int(e.LESSON)
|
||||
db.query_with_bindings("SELECT * FROM Lessons WHERE LessonNb=?", [lesson_nb])
|
||||
var lesson_id: = -1
|
||||
if db.query_result.is_empty():
|
||||
db.insert_row("Lessons", {
|
||||
LessonNb = lesson_nb
|
||||
})
|
||||
lesson_id = db.last_insert_rowid
|
||||
else:
|
||||
lesson_id = db.query_result[0]["ID"]
|
||||
db.insert_row("GPsInLessons", {
|
||||
GPID = GP_id,
|
||||
LessonID = lesson_id,
|
||||
})
|
||||
|
||||
|
||||
func _import_kalulu_3_word_sounds() -> void:
|
||||
var file = FileAccess.open("res://data3/words_list.json", FileAccess.READ)
|
||||
var dict = JSON.parse_string(file.get_line())
|
||||
for e in dict.values():
|
||||
var file_path = "res://data3/language/" + e.FILENAME + ".mp3"
|
||||
DirAccess.copy_absolute(file_path, get_word_sound_path({
|
||||
Word = e.GRAPHEME
|
||||
}))
|
||||
|
||||
|
||||
func _import_kalulu_3_gp_sounds() -> void:
|
||||
var file = FileAccess.open("res://data3/gp_list.json", FileAccess.READ)
|
||||
var dict = JSON.parse_string(file.get_line())
|
||||
for e in dict.values():
|
||||
var file_path = "res://data3/language/" + e.FILENAME + ".mp3"
|
||||
if e.GRAPHEME == "mu":
|
||||
print("j")
|
||||
DirAccess.copy_absolute(file_path, get_gp_sound_path({
|
||||
Grapheme = e.GRAPHEME,
|
||||
Phoneme = e.PHONEME,
|
||||
}))
|
||||
|
||||
|
||||
func _remove_unusable_words() -> void:
|
||||
var file = FileAccess.open("res://words_list.json", FileAccess.READ)
|
||||
var dict = JSON.parse_string(file.get_line())
|
||||
for e in dict.values():
|
||||
if e.USABLE_WORD_GAME == "0":
|
||||
db.query_with_bindings("SELECT * FROM Words WHERE Word=?", [e.GRAPHEME])
|
||||
if not db.query_result.is_empty():
|
||||
var word_id = db.query_result[0]["ID"]
|
||||
db.delete_rows("Words", "ID=%s" % word_id)
|
||||
|
||||
|
||||
func _import_words_csv() -> void:
|
||||
var file = FileAccess.open("res://data3/Copy of Manulex-infra-2.csv", FileAccess.READ)
|
||||
file.get_line()
|
||||
while not file.eof_reached():
|
||||
var line: = file.get_csv_line()
|
||||
_import_word_from_csv(line[0], line[2])
|
||||
|
||||
|
||||
func _import_word_from_csv(ortho: String, gpmatch: String, is_word: = true) -> Array:
|
||||
var gp_list: = gpmatch.trim_prefix("(").trim_suffix(")").split(".")
|
||||
var gp_ids: Array[int] = []
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
extends Node
|
||||
|
||||
const log_resource_class: = preload("res://sources/utils/minigame_resources/log.gd")
|
||||
const Log: = preload("res://sources/utils/minigame_resources/log.gd")
|
||||
|
||||
# Contains the current log resource
|
||||
var log_resources: = {}
|
||||
@@ -9,14 +9,17 @@ var log_resources: = {}
|
||||
func save_logs(logs: Dictionary, folder_path: String, minigame_name: String, lesson_nb: int, time: String) -> void:
|
||||
var file_path: = folder_path + minigame_name + ".tres"
|
||||
|
||||
var log_resource: LogResource
|
||||
if not ResourceLoader.exists(file_path):
|
||||
var log_resource: LogResource = log_resource_class.new()
|
||||
log_resource = Log.new()
|
||||
ResourceSaver.save(log_resource, file_path, ResourceSaver.FLAG_COMPRESS)
|
||||
|
||||
if not file_path in log_resources:
|
||||
var log_resource: = ResourceLoader.load(file_path)
|
||||
log_resource = ResourceLoader.load(file_path)
|
||||
log_resources[file_path] = log_resource
|
||||
else:
|
||||
log_resource = log_resources[file_path]
|
||||
|
||||
log_resources[file_path].add_log(lesson_nb, logs, time)
|
||||
log_resource.add_log(lesson_nb, logs, time)
|
||||
|
||||
ResourceSaver.save(log_resources[file_path], file_path, ResourceSaver.FLAG_COMPRESS)
|
||||
ResourceSaver.save(log_resource, file_path, ResourceSaver.FLAG_COMPRESS)
|
||||
|
||||
@@ -22,4 +22,4 @@ func close() -> void:
|
||||
|
||||
|
||||
func _on_animation_player_animation_finished(animation_name: StringName) -> void:
|
||||
emit_signal("animation_finished", animation_name)
|
||||
animation_finished.emit(animation_name)
|
||||
|
||||
@@ -53,7 +53,7 @@ func _get_request(URI: String, params: Dictionary) -> void:
|
||||
|
||||
var req: = URL + URI
|
||||
var is_first_param: bool = true
|
||||
for key in params.keys():
|
||||
for key: String in params.keys():
|
||||
if is_first_param:
|
||||
req += "?"
|
||||
is_first_param = false
|
||||
@@ -77,8 +77,7 @@ func _post_json_request(URI: String, data: Dictionary) -> void:
|
||||
var headers: = _create_request_headers()
|
||||
headers.append("Content-Type: application/json")
|
||||
|
||||
var json = JSON.stringify(data)
|
||||
if http_request.request(req, headers, HTTPClient.METHOD_POST, json) == 0:
|
||||
if http_request.request(req, headers, HTTPClient.METHOD_POST, JSON.stringify(data)) == 0:
|
||||
await request_completed
|
||||
else:
|
||||
code = 500
|
||||
@@ -86,7 +85,7 @@ func _post_json_request(URI: String, data: Dictionary) -> void:
|
||||
|
||||
#endregion
|
||||
|
||||
func _on_http_request_request_completed(result, response_code, headers, body):
|
||||
func _on_http_request_request_completed(_result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void:
|
||||
code = response_code
|
||||
if body:
|
||||
json = JSON.parse_string(body.get_string_from_utf8())
|
||||
|
||||
@@ -103,7 +103,7 @@ func login_student(code : String) -> bool:
|
||||
if not _device_settings or not teacher_settings:
|
||||
return false
|
||||
|
||||
var students = teacher_settings.students[_device_settings.device_id] as Array[StudentData]
|
||||
var students: Array[StudentData] = teacher_settings.students[_device_settings.device_id] as Array[StudentData]
|
||||
if students:
|
||||
for s in students:
|
||||
if s.code == code:
|
||||
@@ -183,7 +183,7 @@ func add_device() -> bool:
|
||||
if not teacher_settings.students:
|
||||
return false
|
||||
|
||||
var device_id = teacher_settings.students.keys().back() + 1
|
||||
var device_id: int = teacher_settings.students.keys().back() + 1
|
||||
|
||||
# Adds the new device
|
||||
var students_array : Array[StudentData] = []
|
||||
@@ -212,7 +212,8 @@ func add_student(device_id : int, student_data : StudentData) -> bool:
|
||||
return false
|
||||
|
||||
# Adds the student on the device
|
||||
teacher_settings.students[device_id].append(student_data)
|
||||
var device_students: Array[StudentData] = teacher_settings.students[device_id]
|
||||
device_students.append(student_data)
|
||||
|
||||
# Saves the settings
|
||||
_save_teacher_settings()
|
||||
@@ -232,7 +233,7 @@ func delete_student(device_id : int, code : String) -> bool:
|
||||
|
||||
# Finds the student
|
||||
var student_data : StudentData
|
||||
for s in teacher_settings.students[device_id]:
|
||||
for s: StudentData in teacher_settings.students[device_id]:
|
||||
if s.code == code:
|
||||
student_data = s
|
||||
break
|
||||
@@ -240,7 +241,8 @@ func delete_student(device_id : int, code : String) -> bool:
|
||||
# Deletes the saves ??
|
||||
|
||||
# Removes the student
|
||||
teacher_settings.students[device_id].erase(student_data)
|
||||
var device_students: Array[StudentData] = teacher_settings.students[device_id]
|
||||
device_students.erase(student_data)
|
||||
|
||||
# Saves the settings
|
||||
_save_teacher_settings()
|
||||
@@ -300,11 +302,11 @@ func _on_user_progression_unlocks_changed() -> void:
|
||||
_save_student_progression()
|
||||
|
||||
|
||||
func get_student_progression_for_code(device: int, student: String) -> UserProgression:
|
||||
func get_student_progression_for_code(device: int, code: String) -> UserProgression:
|
||||
if not teacher_settings or not teacher_settings.students.has(device):
|
||||
return
|
||||
|
||||
var student_path: String ="user://".path_join(_device_settings.teacher).path_join(str(device)).path_join(_device_settings.language).path_join(student)
|
||||
var student_path: String ="user://".path_join(_device_settings.teacher).path_join(str(device)).path_join(_device_settings.language).path_join(code)
|
||||
var progression_path: String = student_path.path_join("progression.tres")
|
||||
|
||||
var progression: UserProgression
|
||||
@@ -318,8 +320,8 @@ func get_student_progression_for_code(device: int, student: String) -> UserProgr
|
||||
|
||||
return progression
|
||||
|
||||
func save_student_progression_for_code(device: int, student: String, progression: UserProgression) -> void:
|
||||
var progression_path: String = "user://".path_join(_device_settings.teacher).path_join(str(device)).path_join(_device_settings.language).path_join(student).path_join("progression.tres")
|
||||
func save_student_progression_for_code(device: int, code: String, progression: UserProgression) -> void:
|
||||
var progression_path: String = "user://".path_join(_device_settings.teacher).path_join(str(device)).path_join(_device_settings.language).path_join(code).path_join("progression.tres")
|
||||
ResourceSaver.save(progression, progression_path)
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -2,14 +2,17 @@ extends Node
|
||||
|
||||
signal finished()
|
||||
|
||||
const Rocket: = preload("res://sources/utils/fx/rocket.gd")
|
||||
const rocket_scene: = preload("res://sources/utils/fx/rocket.tscn")
|
||||
|
||||
@export var number_of_rockets: = 25
|
||||
|
||||
@onready var fire_delay_timer: = $FireDelayTimer
|
||||
@onready var fire_delay_timer: Timer = $FireDelayTimer
|
||||
@onready var starts: = $Starts.get_children()
|
||||
@onready var ends: = $Ends.get_children()
|
||||
@onready var rockets: = $Rockets
|
||||
@onready var rockets: Node2D = $Rockets
|
||||
|
||||
|
||||
const firework_class: = preload("res://sources/utils/fx/rocket.tscn")
|
||||
|
||||
var count: = 0
|
||||
|
||||
@@ -24,12 +27,13 @@ func _on_FireDelayTimer_timeout() -> void:
|
||||
finished.emit()
|
||||
return
|
||||
|
||||
var start_point: Vector2 = starts[randi() % starts.size()].global_position
|
||||
var end_point: Vector2 = ends[randi() % ends.size()].global_position
|
||||
|
||||
var rocket: = firework_class.instantiate()
|
||||
var start_node: Node2D = starts[randi() % starts.size()]
|
||||
var end_node: Node2D = ends[randi() % ends.size()]
|
||||
|
||||
var rocket: Rocket = rocket_scene.instantiate()
|
||||
rockets.add_child(rocket)
|
||||
rocket.start(start_point, end_point + Vector2(randf_range(-25.0, 25.0), randf_range(-25.0, 25.0)))
|
||||
rocket.start(start_node.global_position, end_node.global_position + Vector2(randf_range(-25.0, 25.0), randf_range(-25.0, 25.0)))
|
||||
|
||||
count += 1
|
||||
fire_delay_timer.start(randf_range(0.1, 0.25))
|
||||
|
||||
@@ -3,16 +3,16 @@ extends Path2D
|
||||
@export var spread_angle := PI/8.0
|
||||
@export var segments := 5
|
||||
|
||||
@onready var path_follow: = $PathFollow2D
|
||||
@onready var path_follow: PathFollow2D = $PathFollow2D
|
||||
|
||||
@onready var traveling_timer: = $TravelingTimer
|
||||
@onready var explosion_timer: = $ExplosionTimer
|
||||
@onready var traveling_timer: Timer = $TravelingTimer
|
||||
@onready var explosion_timer: Timer = $ExplosionTimer
|
||||
|
||||
@onready var rocket: = $PathFollow2D/Rocket
|
||||
@onready var explosion_particles: = $PathFollow2D/ExplosionParticles
|
||||
@onready var rocket: Sprite2D = $PathFollow2D/Rocket
|
||||
@onready var explosion_particles: GPUParticles2D = $PathFollow2D/ExplosionParticles
|
||||
|
||||
@onready var firework_audio_player: = $FireworkAudioPlayer
|
||||
@onready var blast_audio_player: = $BlastAudioPlayer
|
||||
@onready var firework_audio_player: AudioStreamPlayer2D = $FireworkAudioPlayer
|
||||
@onready var blast_audio_player: AudioStreamPlayer2D = $BlastAudioPlayer
|
||||
|
||||
const firework_sounds: = [
|
||||
preload("res://assets/sfx/fireworks_1.mp3"),
|
||||
@@ -85,7 +85,7 @@ func _on_TravelingTimer_timeout() -> void:
|
||||
rocket.visible = false
|
||||
explosion_timer.start()
|
||||
blast_audio_player.play()
|
||||
for particles in explosion_particles.get_children():
|
||||
for particles: GPUParticles2D in explosion_particles.get_children():
|
||||
particles.emitting = true
|
||||
|
||||
|
||||
|
||||
@@ -3,13 +3,14 @@ class_name KeyboardSpacer
|
||||
|
||||
var screen_scale: float
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
screen_scale = DisplayServer.screen_get_scale()
|
||||
|
||||
|
||||
func _process(delta):
|
||||
func _process(_delta: float) -> void:
|
||||
if OS.has_feature("mobile"):
|
||||
var margin = DisplayServer.virtual_keyboard_get_height()
|
||||
var margin: = DisplayServer.virtual_keyboard_get_height()
|
||||
if OS.get_name() == "Android":
|
||||
@warning_ignore("narrowing_conversion")
|
||||
margin *= screen_scale
|
||||
self["theme_override_constants/margin_bottom"] = max(floori(margin), 0)
|
||||
|
||||
@@ -6,11 +6,11 @@ static func bezier_square_error(current_points: Array, ref_points: Array) -> flo
|
||||
var samples: = bezier_sampling(current_points, 25)
|
||||
var curve: = Curve2D.new()
|
||||
|
||||
for point in samples:
|
||||
for point: Vector2 in samples:
|
||||
curve.add_point(point)
|
||||
|
||||
var error: = 0.0
|
||||
for point in ref_points:
|
||||
for point: Vector2 in ref_points:
|
||||
var curve_point: = curve.get_closest_point(point)
|
||||
error += pow(curve_point.distance_to(point), 2.0)
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
extends Resource
|
||||
class_name LogResource
|
||||
|
||||
@export var logs: = {}
|
||||
@export var logs: Dictionary = {} # int : Dictionary {String : Dictionary}
|
||||
|
||||
|
||||
func add_log(lesson_nb: int, new_log: Dictionary, time: String) -> void:
|
||||
if not logs.has(lesson_nb):
|
||||
logs[lesson_nb] = {}
|
||||
|
||||
if not logs[lesson_nb].has(time):
|
||||
var lesson_logs: Dictionary = logs[lesson_nb]
|
||||
if not lesson_logs.has(time):
|
||||
logs[lesson_nb][time] = new_log
|
||||
else:
|
||||
var i: = 2
|
||||
while logs[lesson_nb].has(time + "_" + str(i)):
|
||||
while lesson_logs.has(time + "_" + str(i)):
|
||||
i += 1
|
||||
logs[lesson_nb][time + "_" + str(i)] = new_log
|
||||
|
||||
Reference in New Issue
Block a user