Add another gym about scene switching
This commit is contained in:
@@ -20,6 +20,13 @@ func _ready() -> void:
|
||||
# Connect to variable changes to watch for demo variables
|
||||
Dialogic.VAR.variable_changed.connect(_on_variable_changed)
|
||||
|
||||
# Check if we're returning from the gym09 minigame
|
||||
if Dialogic.VAR.Gym.minigame_done:
|
||||
print("[Gym Controller] Returning from minigame — starting congrats timeline.")
|
||||
Dialogic.VAR.Gym.minigame_done = false
|
||||
Dialogic.start("gym09_congrats")
|
||||
return
|
||||
|
||||
# Start the hub timeline
|
||||
Dialogic.start(start_timeline)
|
||||
|
||||
@@ -49,6 +56,14 @@ func _on_dialogic_signal(argument: Variant) -> void:
|
||||
Dialogic.end_timeline()
|
||||
Dialogic.start_timeline("gym_pattern4_signal_target")
|
||||
|
||||
elif argument is String and argument == "start_minigame":
|
||||
# Gym 09: Scene switching demo
|
||||
# Store the return path so the minigame knows where to come back to
|
||||
Dialogic.VAR.Gym.minigame_return = "hub"
|
||||
print("[Gym Controller] Signal 'start_minigame' — switching to minigame scene.")
|
||||
await get_tree().create_timer(0.3).timeout
|
||||
get_tree().change_scene_to_file("res://docs/gyms/gym09_scene_switching/gym09_minigame.tscn")
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
@@ -50,7 +50,24 @@ Miko (neutral): Which pattern would you like to explore?
|
||||
Miko (joy): The variable itself is the jump target!
|
||||
jump gym_pattern8_dynamic_label/start
|
||||
|
||||
- More patterns...
|
||||
Miko (smile): There's more to explore on the next page!
|
||||
jump menu_p2
|
||||
|
||||
- I've seen enough. Goodbye!
|
||||
Miko (smile): Thanks for exploring! Come back anytime.
|
||||
Advisor (pl5): Until next time.
|
||||
[end_timeline]
|
||||
|
||||
label menu_p2
|
||||
|
||||
Miko (neutral): More patterns to explore:
|
||||
|
||||
- 9. Scene switching (Dialogic ↔ gameplay)
|
||||
Miko (smile): This one changes scenes — a timeline, then a minigame, then back!
|
||||
Advisor (pl5): I'll take you to the intro, which will trigger the minigame.
|
||||
Miko (neutral): Press the button 5 times to return.
|
||||
jump gym09_intro/
|
||||
|
||||
- Back to first page
|
||||
jump menu
|
||||
|
||||
27
docs/gyms/gym09_scene_switching/README.md
Normal file
27
docs/gyms/gym09_scene_switching/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Gym 09 — Scene Switching
|
||||
|
||||
Demonstrates switching between a Dialogic timeline scene and a non-Dialogic gameplay scene.
|
||||
|
||||
## Flow
|
||||
|
||||
```
|
||||
gym09_main.tscn gym09_minigame.tscn
|
||||
┌─────────────────┐ ┌──────────────────┐
|
||||
│ gym09_intro.dtl │ │ Press button 5x │
|
||||
│ ↓ │ │ ↓ │
|
||||
│ [signal] │ ───→ │ set variable │
|
||||
│ │ ←─── │ change_scene back │
|
||||
│ gym09_congrats │ │ │
|
||||
│ .dtl │ └──────────────────┘
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
## How to Run
|
||||
|
||||
Open `gym09_main.tscn` in the Godot editor and press **F6** (Run Current Scene).
|
||||
|
||||
## Key Mechanic
|
||||
|
||||
- `Dialogic.VAR.Gym.minigame_done` acts as a flag between scenes
|
||||
- `[signal arg=start_minigame]` triggers `get_tree().change_scene_to_file()`
|
||||
- The controller's `_ready()` checks the flag to know which timeline to start
|
||||
51
docs/gyms/gym09_scene_switching/gym09_congrats.dtl
Normal file
51
docs/gyms/gym09_scene_switching/gym09_congrats.dtl
Normal file
@@ -0,0 +1,51 @@
|
||||
# ============================================================
|
||||
# Gym 09 — Scene Switching: Congratulations Timeline
|
||||
# ============================================================
|
||||
# This timeline runs AFTER the player returns from the
|
||||
# minigame. It congratulates them and explains the mechanism.
|
||||
# ============================================================
|
||||
|
||||
join Miko center
|
||||
join Advisor right
|
||||
|
||||
Miko (joy): You did it! You pressed the button 5 times!
|
||||
|
||||
[wait time="0.5"]
|
||||
|
||||
Advisor (pl5): Welcome back to a Dialogic timeline.
|
||||
Advisor (pl5): Notice what just happened:
|
||||
|
||||
[wait time="1.0"]
|
||||
|
||||
Advisor (pl5): 1. You started in a Dialogic timeline (the intro).
|
||||
Advisor (pl5): 2. A signal triggered a scene change to a pure\
|
||||
gameplay scene with no Dialogic UI.
|
||||
Advisor (pl5): 3. The minigame set a Dialogic variable:\
|
||||
`Gym.minigame_done = true`
|
||||
Advisor (pl5): 4. Then it called `change_scene_to_file()` back here.
|
||||
Advisor (pl5): 5. This scene's controller checked the variable\
|
||||
and started THIS timeline.
|
||||
|
||||
[wait time="2.0"]
|
||||
|
||||
Miko (smile): The magic is that Dialogic is an AUTOLOAD!
|
||||
Miko (joy): Its variables survive scene changes because the\
|
||||
autoload never gets freed.
|
||||
|
||||
Advisor (doubt): This pattern is essential for:
|
||||
Advisor (doubt): • Minigames (fishing, crafting, lockpicking)
|
||||
Advisor (doubt): • Combat encounters between dialog scenes
|
||||
Advisor (doubt): • Exploration that triggers narrative beats
|
||||
Advisor (doubt): • Any gameplay/dialog hybrid
|
||||
|
||||
[wait time="2.0"]
|
||||
|
||||
Miko (smile): Want to try again?
|
||||
|
||||
- Yes, play the minigame again!
|
||||
set {Gym.minigame_done} = false
|
||||
[signal arg=start_minigame]
|
||||
|
||||
- No, I understand the pattern. Back to hub.
|
||||
set {Gym.minigame_done} = false
|
||||
jump gym_main/menu
|
||||
1
docs/gyms/gym09_scene_switching/gym09_congrats.dtl.uid
Normal file
1
docs/gyms/gym09_scene_switching/gym09_congrats.dtl.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b8hj1owk0somk
|
||||
37
docs/gyms/gym09_scene_switching/gym09_controller.gd
Normal file
37
docs/gyms/gym09_scene_switching/gym09_controller.gd
Normal file
@@ -0,0 +1,37 @@
|
||||
# ============================================================
|
||||
# Gym 09 — Scene Switching Controller
|
||||
# ============================================================
|
||||
# This root node handles:
|
||||
# 1. Starting the right timeline on scene load
|
||||
# (intro on first visit, congrats after minigame)
|
||||
# 2. Catching the [signal arg=start_minigame] to change scenes
|
||||
# ============================================================
|
||||
extends Node2D
|
||||
|
||||
const MINIGAME_SCENE_PATH := "res://docs/gyms/gym09_scene_switching/gym09_minigame.tscn"
|
||||
|
||||
@export var intro_timeline: DialogicTimeline
|
||||
@export var congrats_timeline: DialogicTimeline
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# Connect to signal events from timelines
|
||||
Dialogic.signal_event.connect(_on_dialogic_signal)
|
||||
|
||||
# Check if we're returning from the minigame
|
||||
if Dialogic.VAR.Gym.minigame_done:
|
||||
print("[Gym09 Controller] Returning from minigame — starting congrats timeline.")
|
||||
Dialogic.VAR.Gym.minigame_done = false
|
||||
Dialogic.start(congrats_timeline)
|
||||
else:
|
||||
print("[Gym09 Controller] First visit — starting intro timeline.")
|
||||
Dialogic.start(intro_timeline)
|
||||
|
||||
|
||||
func _on_dialogic_signal(argument: Variant) -> void:
|
||||
if argument is String and argument == "start_minigame":
|
||||
print("[Gym09 Controller] Signal 'start_minigame' received — switching to minigame scene.")
|
||||
# Tell the minigame where to return
|
||||
Dialogic.VAR.Gym.minigame_return = "standalone"
|
||||
await get_tree().create_timer(0.3).timeout
|
||||
get_tree().change_scene_to_file(MINIGAME_SCENE_PATH)
|
||||
1
docs/gyms/gym09_scene_switching/gym09_controller.gd.uid
Normal file
1
docs/gyms/gym09_scene_switching/gym09_controller.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://k82wjnwinxwp
|
||||
43
docs/gyms/gym09_scene_switching/gym09_intro.dtl
Normal file
43
docs/gyms/gym09_scene_switching/gym09_intro.dtl
Normal file
@@ -0,0 +1,43 @@
|
||||
# ============================================================
|
||||
# Gym 09 — Scene Switching: Intro Timeline
|
||||
# ============================================================
|
||||
# This timeline introduces the scene-switching concept,
|
||||
# then emits a signal that triggers a scene change to the
|
||||
# minigame (a non-Dialogic scene).
|
||||
# ============================================================
|
||||
|
||||
join Miko center
|
||||
join Advisor right
|
||||
|
||||
Miko (joy): Welcome to Gym 09 — Scene Switching!
|
||||
Advisor (pl5): This gym demonstrates how Dialogic timelines and\
|
||||
non-Dialogic gameplay scenes can flow back and forth.
|
||||
|
||||
[wait time="1.0"]
|
||||
|
||||
Miko (neutral): Here's the plan:
|
||||
Miko (smile): 1. You're reading this dialog (Dialogic timeline).
|
||||
Advisor (pl5): 2. I'll emit a signal that changes the scene to a\
|
||||
pure minigame — no dialog, no portraits, just gameplay.
|
||||
Miko (smile): 3. In the minigame, press the button 5 times!
|
||||
Advisor (pl5): 4. After 5 presses, you'll automatically return here\
|
||||
and I'll congratulate you with another timeline.
|
||||
|
||||
[wait time="1.5"]
|
||||
|
||||
Miko (joy): That shows the full loop:\
|
||||
Dialogic scene → gameplay scene → Dialogic scene!
|
||||
|
||||
Advisor (pl5): The key insight: Dialogic is an autoload, so\
|
||||
variables persist even in non-Dialogic scenes.
|
||||
|
||||
[wait time="1.0"]
|
||||
|
||||
Miko (smile): Ready? Let's go to the minigame!
|
||||
|
||||
# This signal is caught by gym09_controller.gd,
|
||||
# which calls get_tree().change_scene_to_file("...minigame.tscn")
|
||||
[signal arg=start_minigame]
|
||||
|
||||
# This line won't be reached — the scene changes immediately
|
||||
Miko (surprise): Wait, shouldn't I still be here?
|
||||
1
docs/gyms/gym09_scene_switching/gym09_intro.dtl.uid
Normal file
1
docs/gyms/gym09_scene_switching/gym09_intro.dtl.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://my3sk1mu2lx6
|
||||
10
docs/gyms/gym09_scene_switching/gym09_main.tscn
Normal file
10
docs/gyms/gym09_scene_switching/gym09_main.tscn
Normal file
@@ -0,0 +1,10 @@
|
||||
[gd_scene format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://docs/gyms/gym09_scene_switching/gym09_controller.gd" id="1_ctrl"]
|
||||
[ext_resource type="Resource" path="res://docs/gyms/gym09_scene_switching/gym09_intro.dtl" id="2_intro"]
|
||||
[ext_resource type="Resource" path="res://docs/gyms/gym09_scene_switching/gym09_congrats.dtl" id="3_congrats"]
|
||||
|
||||
[node name="Gym09SceneSwitching" type="Node2D"]
|
||||
script = ExtResource("1_ctrl")
|
||||
intro_timeline = ExtResource("2_intro")
|
||||
congrats_timeline = ExtResource("3_congrats")
|
||||
55
docs/gyms/gym09_scene_switching/gym09_minigame.gd
Normal file
55
docs/gyms/gym09_scene_switching/gym09_minigame.gd
Normal file
@@ -0,0 +1,55 @@
|
||||
# ============================================================
|
||||
# Gym 09 — Minigame Scene
|
||||
# ============================================================
|
||||
# A pure gameplay scene with NO Dialogic UI.
|
||||
# Press the button 5 times, then return to the Dialogic scene.
|
||||
# ============================================================
|
||||
extends Control
|
||||
|
||||
@export var required_presses: int = 5
|
||||
|
||||
var _press_count: int = 0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
print("[Gym09 Minigame] Ready! Press the button ", required_presses, " times.")
|
||||
_update_label()
|
||||
|
||||
|
||||
func _on_button_pressed() -> void:
|
||||
_press_count += 1
|
||||
print("[Gym09 Minigame] Press ", _press_count, " of ", required_presses)
|
||||
_update_label()
|
||||
|
||||
if _press_count >= required_presses:
|
||||
_on_complete()
|
||||
|
||||
|
||||
func _update_label() -> void:
|
||||
var remaining := required_presses - _press_count
|
||||
if remaining > 0:
|
||||
%CounterLabel.text = "Presses remaining: " + str(remaining)
|
||||
%Button.text = "Press Me! (" + str(_press_count) + "/" + str(required_presses) + ")"
|
||||
else:
|
||||
%CounterLabel.text = "Complete!"
|
||||
%Button.text = "Returning..."
|
||||
|
||||
|
||||
func _on_complete() -> void:
|
||||
print("[Gym09 Minigame] Complete! Setting variable and switching back.")
|
||||
# Dialogic is an autoload, so this works even without a Dialogic layout
|
||||
Dialogic.VAR.Gym.minigame_done = true
|
||||
|
||||
# Disable the button so player can't spam it
|
||||
%Button.disabled = true
|
||||
|
||||
# Brief pause so the player sees "Complete!"
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
|
||||
# Determine where to return based on who started us
|
||||
var return_path := "res://docs/gyms/gym09_scene_switching/gym09_main.tscn"
|
||||
if Dialogic.VAR.Gym.minigame_return == "hub":
|
||||
return_path = "res://docs/gyms/cross-timeline-interactions/gym_controller.tscn"
|
||||
|
||||
print("[Gym09 Minigame] Returning to: ", return_path)
|
||||
get_tree().change_scene_to_file(return_path)
|
||||
1
docs/gyms/gym09_scene_switching/gym09_minigame.gd.uid
Normal file
1
docs/gyms/gym09_scene_switching/gym09_minigame.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bpu7ehr2qjc1f
|
||||
45
docs/gyms/gym09_scene_switching/gym09_minigame.tscn
Normal file
45
docs/gyms/gym09_scene_switching/gym09_minigame.tscn
Normal file
@@ -0,0 +1,45 @@
|
||||
[gd_scene format=3 uid="uid://p83ndnog4l2h"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bpu7ehr2qjc1f" path="res://docs/gyms/gym09_scene_switching/gym09_minigame.gd" id="1_script"]
|
||||
|
||||
[node name="Gym09Minigame" type="Control" unique_id=313626257]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_script")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=419254278]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -150.0
|
||||
offset_top = -80.0
|
||||
offset_right = 150.0
|
||||
offset_bottom = 80.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="TitleLabel" type="Label" parent="VBoxContainer" unique_id=529708548]
|
||||
layout_mode = 2
|
||||
text = "MINIGAME"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="CounterLabel" type="Label" parent="VBoxContainer" unique_id=1005168486]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
text = "Presses remaining: 5"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="Button" type="Button" parent="VBoxContainer" unique_id=211036225]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
text = "Press Me! (0/5)"
|
||||
|
||||
[connection signal="pressed" from="VBoxContainer/Button" to="." method="_on_button_pressed"]
|
||||
@@ -27,6 +27,8 @@ directories/dch_directory={
|
||||
"Raptor": "res://docs/museums/dialogic/Raptor.dch"
|
||||
}
|
||||
directories/dtl_directory={
|
||||
"gym09_congrats": "res://docs/gyms/gym09_scene_switching/gym09_congrats.dtl",
|
||||
"gym09_intro": "res://docs/gyms/gym09_scene_switching/gym09_intro.dtl",
|
||||
"gym_main": "res://docs/gyms/cross-timeline-interactions/gym_main.dtl",
|
||||
"gym_pattern1_jump": "res://docs/gyms/cross-timeline-interactions/gym_pattern1_jump.dtl",
|
||||
"gym_pattern1_target": "res://docs/gyms/cross-timeline-interactions/gym_pattern1_target.dtl",
|
||||
@@ -50,6 +52,8 @@ layout/default_style="Default"
|
||||
variables={
|
||||
"Gym": {
|
||||
"demo_flag": false,
|
||||
"minigame_done": false,
|
||||
"minigame_return": "",
|
||||
"player_name": "Hero",
|
||||
"sub_value": 0,
|
||||
"time_of_day": "morning"
|
||||
|
||||
Reference in New Issue
Block a user