Crabs first version

This commit is contained in:
Laurent Tourte
2023-02-03 11:17:07 +01:00
parent ff9f0827d9
commit 86d2d7ecd0
56 changed files with 1105 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
extends Node2D
class_name Crab
signal crab_hit(stimulus: Dictionary)
@onready var animation_player: = $AnimationPlayer
@onready var label: = $Label
@onready var button: = $Button
var stimulus: Dictionary
func _ready() -> void:
set_button_active(false)
func set_button_active(active: bool) -> void:
button.disabled = not active
func set_stimulus(p_stimulus: Dictionary) -> void:
stimulus = p_stimulus
label.text = stimulus["label"]
func _on_button_pressed() -> void:
emit_signal("crab_hit", stimulus)
animation_player.play("hit")
func _on_animation_player_animation_finished(animation_name: StringName) -> void:
var idles: = ["idle1", "idle2"]
if animation_name in idles:
var r: = randi() % idles.size()
animation_player.play(idles[r])
if animation_name == "hit":
animation_player.play("hurt")
+148
View File
@@ -0,0 +1,148 @@
[gd_scene load_steps=16 format=3 uid="uid://bwe3fp0vkpufb"]
[ext_resource type="Script" path="res://sources/minigames/crabs/crab/crab.gd" id="1_5hgg8"]
[ext_resource type="Texture2D" uid="uid://c36217nu30yh3" path="res://resources/minigames/crabs/graphic/crab_spritesheet.png" id="2_yu4q0"]
[ext_resource type="FontFile" uid="uid://b2l4jfylc1v41" path="res://resources/fonts/DidactGothic-Regular.ttf" id="3_dei0e"]
[sub_resource type="Animation" id="Animation_lftfb"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Crab:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [0]
}
[sub_resource type="Animation" id="Animation_b2qjc"]
resource_name = "hit"
length = 0.4
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Crab:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3),
"transitions": PackedFloat32Array(1, 1, 1, 1),
"update": 1,
"values": [18, 19, 20, 21]
}
[sub_resource type="Animation" id="Animation_aahhw"]
resource_name = "hurt"
length = 0.6
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Crab:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
"update": 1,
"values": [12, 13, 14, 15, 16, 17]
}
[sub_resource type="Animation" id="Animation_5butr"]
resource_name = "idle1"
length = 0.6
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Crab:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
"update": 1,
"values": [0, 1, 2, 3, 4, 5]
}
[sub_resource type="Animation" id="Animation_0cnq1"]
resource_name = "idle2"
length = 0.6
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Crab:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5),
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1),
"update": 1,
"values": [6, 7, 8, 9, 10, 11]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ifo73"]
_data = {
"RESET": SubResource("Animation_lftfb"),
"hit": SubResource("Animation_b2qjc"),
"hurt": SubResource("Animation_aahhw"),
"idle1": SubResource("Animation_5butr"),
"idle2": SubResource("Animation_0cnq1")
}
[sub_resource type="LabelSettings" id="LabelSettings_lys05"]
font = ExtResource("3_dei0e")
font_size = 42
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_tnp5x"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_g8ffa"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_fwwak"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_tdur1"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_1h5my"]
[node name="Crab" type="Node2D"]
script = ExtResource("1_5hgg8")
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
autoplay = "idle1"
libraries = {
"": SubResource("AnimationLibrary_ifo73")
}
[node name="Crab" type="Sprite2D" parent="."]
light_mask = 1024
visibility_layer = 1024
texture = ExtResource("2_yu4q0")
offset = Vector2(-5, -8)
hframes = 6
vframes = 4
[node name="Label" type="Label" parent="."]
offset_left = -56.0
offset_top = -33.0
offset_right = 55.0
offset_bottom = 52.0
label_settings = SubResource("LabelSettings_lys05")
horizontal_alignment = 1
vertical_alignment = 1
[node name="Button" type="Button" parent="."]
offset_left = -56.0
offset_top = -33.0
offset_right = 55.0
offset_bottom = 52.0
theme_override_styles/normal = SubResource("StyleBoxEmpty_tnp5x")
theme_override_styles/hover = SubResource("StyleBoxEmpty_g8ffa")
theme_override_styles/pressed = SubResource("StyleBoxEmpty_fwwak")
theme_override_styles/disabled = SubResource("StyleBoxEmpty_tdur1")
theme_override_styles/focus = SubResource("StyleBoxEmpty_1h5my")
[connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_animation_player_animation_finished"]
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]
+143
View File
@@ -0,0 +1,143 @@
extends Minigame
@export var difficulty: = 1
const hole_class: = preload("res://sources/minigames/crabs/hole/hole.tscn")
const difficulty_settings: = {
0: {"crab_rows": [2, 1]},
1 : {"crab_rows": [3, 2]},
2 : {"crab_rows": [4, 3]},
3 : {"crab_rows": [4, 3, 2]},
4 : {"crab_rows": [4, 3, 4]},
}
@onready var top_left: = $GameRoot/TopLeft
@onready var bottom_right: = $GameRoot/BottomRight
var holes: = []
# ------------ Initialisation ------------
# Find and set the parameters of the minigame, like the number of lives or the victory conditions.
func _setup_minigame() -> void:
super._setup_minigame()
# Progression management
max_progression = 10
current_progression = 0
var max_difficulty: = 0
for d in difficulty_settings.keys():
if d > max_difficulty:
max_difficulty = d
if difficulty > max_difficulty:
difficulty = max_difficulty
var settings: Dictionary = difficulty_settings[difficulty]
for i in range(settings["crab_rows"].size()):
var fi: = float(i + 1.0) / float(settings["crab_rows"].size() + 1.0)
var y: float = (1.0 - fi) * top_left.position.y + fi * bottom_right.position.y
for j in range(settings["crab_rows"][i]):
var fj: = float(j + 1.0) / float(settings["crab_rows"][i] + 1.0)
var x: float = fj * top_left.position.x + (1.0 - fj) * bottom_right.position.x
var hole: = hole_class.instantiate()
game_root.add_child(hole)
hole.position = Vector2(x, y)
hole.connect("stimulus_hit", _on_hole_stimulus_hit)
hole.connect("crab_despawned", _on_hole_crab_despawned)
holes.append(hole)
# Find the stimuli and distractions of the minigame.
func _find_stimuli_and_distractions() -> void:
# TODO: fake stimuli and distractor for testing
# Replace in the future by a proper research
stimuli = [{"label": "a", "sound": ""}]
distractions = [
{"label": "e", "sound": ""},
{"label": "u", "sound": ""},
{"label": "o", "sound": ""},
]
# Launch the minigame
func _start() -> void:
super._start()
_on_hole_timer_timeout(stimuli[0])
for i in range(3 * holes.size() / 4):
_on_hole_crab_despawned(distractions[randi() % distractions.size()])
await get_tree().create_timer(0.1).timeout
# ------------ Crabs ------------
func _on_hole_stimulus_hit(stimulus: Dictionary) -> void:
if stimulus in stimuli:
current_progression += 1
else:
current_lives -= 1
func _on_hole_timer_timeout(stimulus: Dictionary) -> void:
var holes_range: = range(holes.size())
holes_range.shuffle()
var hole_found: = false
while not hole_found:
for i in holes_range:
if not holes[i].crab_spawned:
holes[i].spawn_crab(stimulus)
hole_found = true
break
if not hole_found:
await get_tree().create_timer(randf_range(0.1, 0.5)).timeout
func _on_hole_crab_despawned(stimulus: Dictionary) -> void:
await get_tree().create_timer(randf_range(0.1, 2.0)).timeout
_on_hole_timer_timeout(stimulus)
# ------------ Logs ------------
func _save_logs() -> void:
LessonLogger.save_logs(logs, GameGlobals.teacher_id, GameGlobals.user_id, minigame_name, lesson, Time.get_time_string_from_system())
_reset_logs()
func _reset_logs() -> void:
logs = {}
# ------------ UI ------------
# Callbacks
func _go_back_to_the_garden() -> void:
return
func _play_stimulus() -> void:
return
func _pause_game() -> void:
get_tree().paused = not get_tree().paused
func _play_kalulu() -> void:
return
@@ -0,0 +1,32 @@
[gd_scene load_steps=8 format=3 uid="uid://c8ntt5r3fjeh"]
[ext_resource type="PackedScene" uid="uid://8awe4usnucyv" path="res://sources/minigames/base/base_minigame.tscn" id="1_lbq56"]
[ext_resource type="Script" path="res://sources/minigames/crabs/crabs_minigame.gd" id="2_gierf"]
[ext_resource type="Texture2D" uid="uid://bt7u67errbjls" path="res://resources/minigames/crabs/graphic/gauge_icon_crab_empty.png" id="3_s5o38"]
[ext_resource type="AudioStream" uid="uid://4qo683e8atp4" path="res://resources/minigames/crabs/audio/kalulu/kalulu_help_crabs_language.mp3" id="3_vtu3m"]
[ext_resource type="Texture2D" uid="uid://cq5wwf7y1msh7" path="res://resources/minigames/crabs/graphic/gauge_icon_crab_full.png" id="4_a1dm5"]
[ext_resource type="AudioStream" uid="uid://cmp7vupeq11ic" path="res://resources/minigames/crabs/audio/kalulu/kalulu_end_crabs_all.mp3" id="4_eh4op"]
[ext_resource type="Texture2D" uid="uid://5bx8ugh178j1" path="res://resources/minigames/crabs/graphic/background.png" id="5_0ps1r"]
[node name="Crabs" instance=ExtResource("1_lbq56")]
script = ExtResource("2_gierf")
difficulty = 4
minigame_name = "Crabs"
start_kalulu_speech = ExtResource("3_vtu3m")
win_kalulu_speech = ExtResource("4_eh4op")
[node name="MinigameUI" parent="." index="0"]
empty_progression_icon = ExtResource("3_s5o38")
full_progression_icon = ExtResource("4_a1dm5")
[node name="Background" type="Sprite2D" parent="GameRoot" index="0"]
position = Vector2(1280, 900)
scale = Vector2(2, 2)
texture = ExtResource("5_0ps1r")
metadata/_edit_lock_ = true
[node name="TopLeft" type="Node2D" parent="GameRoot" index="1"]
position = Vector2(544, 631)
[node name="BottomRight" type="Node2D" parent="GameRoot" index="2"]
position = Vector2(2310, 1675)
+83
View File
@@ -0,0 +1,83 @@
extends Node2D
class_name CrabHole
signal stimulus_hit(stimulus: Dictionary)
signal crab_despawned(stimulus: Dictionary)
const crab_class: = preload("res://sources/minigames/crabs/crab/crab.tscn")
@onready var hole_back: = $HoleBack
@onready var hole_front: = $HoleFront
@onready var mask: = $Mask
@onready var timer: = $Timer
@onready var crab_audio_stream_player: = $CrabAudioStreamPlayer2D
var crab: Crab
var crab_hit: = false
var crab_spawned: = false
func spawn_crab(stimulus: Dictionary) -> void:
crab_spawned = true
crab = crab_class.instantiate()
mask.add_child(crab)
crab.connect("crab_hit", _crab_hit)
crab.position = Vector2(0, 200)
crab.set_stimulus(stimulus)
crab_audio_stream_player.start_playing()
var first_tween: = create_tween()
first_tween.tween_property(crab, "position", Vector2(0.0, 100.0), randf_range(0.25, 2.0))
await first_tween.finished
first_tween.kill()
crab_audio_stream_player.stop_playing()
timer.start(randf_range(0.25, 1.5))
await timer.timeout
crab_audio_stream_player.start_playing()
var second_tween: = create_tween()
second_tween.tween_property(crab, "position", Vector2(0.0, -50.0), 0.25)
await second_tween.finished
second_tween.kill()
crab_audio_stream_player.stop_playing()
crab_hit = false
crab.set_button_active(true)
timer.start(randf_range(1.0, 2.5))
await timer.timeout
crab.set_button_active(false)
var final_tween: = create_tween()
if crab_hit:
final_tween.tween_property(crab, "position", Vector2(0.0, -200.0), 0.5)
final_tween.parallel().tween_property(crab, "rotation_degrees", 540.0, 0.5)
else:
crab_audio_stream_player.start_playing()
final_tween.tween_property(crab, "position", Vector2(0.0, 200.0), 0.25)
await final_tween.finished
crab_audio_stream_player.stop_playing()
crab.queue_free()
crab_spawned = false
emit_signal("crab_despawned", stimulus)
func _crab_hit(stimulus: Dictionary) -> void:
crab_hit = true
crab.set_button_active(false)
if not timer.is_stopped():
timer.start(0.4)
emit_signal("stimulus_hit", stimulus)
+35
View File
@@ -0,0 +1,35 @@
[gd_scene load_steps=7 format=3 uid="uid://byq160dxpb3rl"]
[ext_resource type="Script" path="res://sources/minigames/crabs/hole/hole.gd" id="1_05s8c"]
[ext_resource type="Texture2D" uid="uid://tfigqbebxmal" path="res://resources/minigames/crabs/graphic/hole_back.png" id="2_f44i6"]
[ext_resource type="Texture2D" uid="uid://7nrlmc7opox1" path="res://resources/minigames/crabs/graphic/hole_mask.png" id="3_ehfgm"]
[ext_resource type="Texture2D" uid="uid://jl4sirrpr1l1" path="res://icon.svg" id="4_5yovx"]
[ext_resource type="Texture2D" uid="uid://cwebei83ml5vs" path="res://resources/minigames/crabs/graphic/hole_front.png" id="5_mhdld"]
[ext_resource type="Script" path="res://sources/minigames/crabs/hole/hole_audio_stream_player_2d.gd" id="6_2rg3s"]
[node name="Hole" type="Node2D"]
position = Vector2(947, 568)
script = ExtResource("1_05s8c")
[node name="HoleBack" type="Sprite2D" parent="."]
texture = ExtResource("2_f44i6")
[node name="Mask" type="Sprite2D" parent="."]
clip_children = 1
position = Vector2(0, -51)
texture = ExtResource("3_ehfgm")
[node name="IconToHideTheMask" type="Sprite2D" parent="Mask"]
position = Vector2(-1, 263)
texture = ExtResource("4_5yovx")
[node name="HoleFront" type="Sprite2D" parent="."]
position = Vector2(0, 2)
texture = ExtResource("5_mhdld")
[node name="Timer" type="Timer" parent="."]
[node name="CrabAudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
script = ExtResource("6_2rg3s")
[connection signal="finished" from="CrabAudioStreamPlayer2D" to="CrabAudioStreamPlayer2D" method="_on_finished"]
@@ -0,0 +1,34 @@
extends AudioStreamPlayer2D
const crab_sound_list: = [
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
preload("res://resources/minigames/crabs/audio/sfx/crab_random_1.mp3"),
]
var should_play: = false
func start_playing() -> void:
should_play = true
_on_finished()
func stop_playing() -> void:
should_play = false
func _on_finished() -> void:
if should_play:
stream = crab_sound_list[randi() % crab_sound_list.size()]
playing = true