improvements
This commit is contained in:
149
acceptance_criteria/dialogue_character_acceptance.md
Normal file
149
acceptance_criteria/dialogue_character_acceptance.md
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
# Acceptance Criteria: Base Character with Dialogue System
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This document defines the acceptance criteria for implementing a base character scene with dialogue functionality in Godot. The implementation should allow characters to have dialogue lines that can be triggered programmatically.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### 1. Base Character Scene
|
||||||
|
- **Feature**: Create a base character scene with Polygon2D sprite
|
||||||
|
- **Acceptance Criteria**:
|
||||||
|
- Scene file `scenes/base_character.tscn` exists
|
||||||
|
- Contains a Polygon2D node as the character sprite
|
||||||
|
- Character has appropriate positioning and scaling
|
||||||
|
- Scene can be instantiated in other scenes
|
||||||
|
- Scene includes necessary child nodes for dialogue system integration
|
||||||
|
|
||||||
|
### 2. Dialogue Entity
|
||||||
|
- **Feature**: Implement dialogue entity that can be triggered programmatically
|
||||||
|
- **Acceptance Criteria**:
|
||||||
|
- Dialogue entity can be attached to any character node
|
||||||
|
- Can be triggered via a public method call
|
||||||
|
- Accepts text content and duration parameters
|
||||||
|
- Supports programmatic triggering without user input
|
||||||
|
|
||||||
|
### 3. Visual Dialogue Box
|
||||||
|
- **Feature**: White dialogue box that animates in when triggered
|
||||||
|
- **Acceptance Criteria**:
|
||||||
|
- Dialogue box appears above character when triggered
|
||||||
|
- Animates in with smooth transition (fade/slide)
|
||||||
|
- Has white background with appropriate styling
|
||||||
|
- Properly positioned relative to character
|
||||||
|
- Resizes based on text content
|
||||||
|
|
||||||
|
### 4. Text Reveal Animation
|
||||||
|
- **Feature**: Text revealed one character at a time
|
||||||
|
- **Acceptance Criteria**:
|
||||||
|
- Text appears character-by-character with delay
|
||||||
|
- Each character reveal has consistent timing
|
||||||
|
- Text is properly formatted and readable
|
||||||
|
- Animation can be configured with different speeds
|
||||||
|
|
||||||
|
### 5. Duration Handling
|
||||||
|
- **Feature**: Dialogue box closes after specified duration
|
||||||
|
- **Acceptance Criteria**:
|
||||||
|
- Dialogue automatically closes after duration ends
|
||||||
|
- Smooth animation out when closing
|
||||||
|
- Duration parameter is configurable
|
||||||
|
- Can handle zero or negative durations appropriately
|
||||||
|
|
||||||
|
### 6. API Interface
|
||||||
|
- **Feature**: Clean public API for dialogue interaction
|
||||||
|
- **Acceptance Criteria**:
|
||||||
|
- Public method to trigger dialogue: `trigger_dialogue(text, duration)`
|
||||||
|
- Method returns immediately after triggering
|
||||||
|
- No blocking operations during animation
|
||||||
|
- Proper error handling for invalid parameters
|
||||||
|
|
||||||
|
### 7. Test Scene
|
||||||
|
- **Feature**: Single character automatically triggering a single dialogue line
|
||||||
|
- **Acceptance Criteria**:
|
||||||
|
- Test scene file `scenes/test_dialogue.tscn` exists
|
||||||
|
- Contains one base character instance
|
||||||
|
- Dialogue is automatically triggered on scene load
|
||||||
|
- Demonstrates complete functionality (show, reveal, hide)
|
||||||
|
- Scene runs without errors
|
||||||
|
|
||||||
|
## Technical Specifications
|
||||||
|
|
||||||
|
### File Structure
|
||||||
|
```
|
||||||
|
scenes/
|
||||||
|
├── base_character.tscn
|
||||||
|
└── test_dialogue.tscn
|
||||||
|
|
||||||
|
scripts/
|
||||||
|
├── dialogue_system.gd
|
||||||
|
└── base_character.gd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dialogue System Components
|
||||||
|
1. **DialogueBox**: Visual UI element for displaying dialogue
|
||||||
|
2. **TextRevealer**: Handles character-by-character text animation
|
||||||
|
3. **AnimationController**: Manages show/hide animations
|
||||||
|
4. **CharacterDialog**: Interface for character-to-dialogue communication
|
||||||
|
|
||||||
|
### API Methods
|
||||||
|
```gdscript
|
||||||
|
# In base_character.gd or similar
|
||||||
|
func trigger_dialogue(text: String, duration: float) -> void:
|
||||||
|
# Triggers dialogue with specified text and duration
|
||||||
|
|
||||||
|
# In dialogue_system.gd
|
||||||
|
func show_dialogue(text: String, duration: float) -> void:
|
||||||
|
# Internal method to display dialogue UI
|
||||||
|
```
|
||||||
|
|
||||||
|
### Animation Requirements
|
||||||
|
- **Show Animation**: 0.3 second fade/slide in
|
||||||
|
- **Text Reveal**: 0.05 second per character
|
||||||
|
- **Hide Animation**: 0.2 second fade out
|
||||||
|
- **Duration**: Default 3 seconds if not specified
|
||||||
|
|
||||||
|
## Success Metrics
|
||||||
|
|
||||||
|
### Functional Tests
|
||||||
|
1. [ ] Base character scene loads without errors
|
||||||
|
2. [ ] Dialogue box appears when `trigger_dialogue()` is called
|
||||||
|
3. [ ] Text reveals character-by-character with correct timing
|
||||||
|
4. [ ] Dialogue box closes automatically after duration
|
||||||
|
5. [ ] Test scene demonstrates complete workflow
|
||||||
|
6. [ ] API methods can be called from other scripts
|
||||||
|
|
||||||
|
### Performance Tests
|
||||||
|
1. [ ] No frame drops during animation sequences
|
||||||
|
2. [ ] Memory usage remains stable
|
||||||
|
3. [ ] Animation timing is consistent across different hardware
|
||||||
|
|
||||||
|
### Compatibility Tests
|
||||||
|
1. [ ] Works with existing Godot 4.x projects
|
||||||
|
2. [ ] Compatible with different character positioning
|
||||||
|
3. [ ] Handles various text lengths appropriately
|
||||||
|
4. [ ] Works with different duration values
|
||||||
|
|
||||||
|
## Non-Functional Requirements
|
||||||
|
|
||||||
|
### Code Quality
|
||||||
|
- [ ] Well-documented code with comments
|
||||||
|
- [ ] Clean, maintainable code structure
|
||||||
|
- [ ] Follows Godot coding conventions
|
||||||
|
- [ ] Proper error handling and validation
|
||||||
|
|
||||||
|
### User Experience
|
||||||
|
- [ ] Smooth animations without jank
|
||||||
|
- [ ] Clear visual feedback during dialogue
|
||||||
|
- [ ] Responsive interface
|
||||||
|
- [ ] Accessible text formatting
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
- Godot 4.x engine
|
||||||
|
- Standard Godot 2D node types (Node2D, Control, Label)
|
||||||
|
- AnimationPlayer or Tween for UI animations
|
||||||
|
- Timer for duration handling
|
||||||
|
|
||||||
|
## Acceptance Process
|
||||||
|
1. Review code implementation against these criteria
|
||||||
|
2. Run test scene to verify functionality
|
||||||
|
3. Confirm all acceptance tests pass
|
||||||
|
4. Validate API usability and documentation
|
||||||
|
5. Ensure no breaking changes to existing systems
|
||||||
93
architecture/dialogue_system_architecture.md
Normal file
93
architecture/dialogue_system_architecture.md
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
# Dialogue System Architecture
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TD
|
||||||
|
A[Base Character Scene] --> B(DialogueSystem)
|
||||||
|
B --> C(DialogueBox UI)
|
||||||
|
B --> D(TextRevealer)
|
||||||
|
B --> E(AnimationController)
|
||||||
|
B --> F(Timer)
|
||||||
|
|
||||||
|
C --> G[Visual Display]
|
||||||
|
D --> H[Character-by-Character Reveal]
|
||||||
|
E --> I[Show/Hide Animations]
|
||||||
|
F --> J[Duration Management]
|
||||||
|
|
||||||
|
subgraph "Dialogue Flow"
|
||||||
|
B --> K{Trigger Dialogue}
|
||||||
|
K -->|Text + Duration| L[Show Dialogue Box]
|
||||||
|
L --> M[Start Text Reveal]
|
||||||
|
M --> N[Wait for Duration]
|
||||||
|
N --> O[Hide Dialogue Box]
|
||||||
|
end
|
||||||
|
|
||||||
|
subgraph "Components"
|
||||||
|
C --> C1[White Background]
|
||||||
|
C --> C2[Positioning]
|
||||||
|
D --> D1[Character Timing]
|
||||||
|
D --> D2[Text Display]
|
||||||
|
E --> E1[Animation Playback]
|
||||||
|
F --> F1[Timer Management]
|
||||||
|
end
|
||||||
|
|
||||||
|
style A fill:#e1f5fe
|
||||||
|
style B fill:#f3e5f5
|
||||||
|
style C fill:#e8f5e9
|
||||||
|
style D fill:#fff3e0
|
||||||
|
style E fill:#fce4ec
|
||||||
|
style F fill:#f1f8e9
|
||||||
|
```
|
||||||
|
|
||||||
|
## Component Descriptions
|
||||||
|
|
||||||
|
### Base Character Scene (A)
|
||||||
|
- Contains the character sprite (Polygon2D)
|
||||||
|
- Acts as the entry point for dialogue triggering
|
||||||
|
- Manages the dialogue system interface
|
||||||
|
|
||||||
|
### DialogueSystem (B) - Main Controller
|
||||||
|
- Coordinates all dialogue functionality
|
||||||
|
- Interfaces with UI components
|
||||||
|
- Handles timing and state management
|
||||||
|
- Provides public API for triggering dialogue
|
||||||
|
|
||||||
|
### DialogueBox UI (C)
|
||||||
|
- Visual representation of dialogue
|
||||||
|
- White background container
|
||||||
|
- Proper positioning relative to character
|
||||||
|
- Handles visibility states
|
||||||
|
|
||||||
|
### TextRevealer (D)
|
||||||
|
- Manages character-by-character text display
|
||||||
|
- Controls reveal timing
|
||||||
|
- Updates text label content incrementally
|
||||||
|
- Handles text formatting and wrapping
|
||||||
|
|
||||||
|
### AnimationController (E)
|
||||||
|
- Manages show/hide animations
|
||||||
|
- Controls timing of UI transitions
|
||||||
|
- Ensures smooth visual experience
|
||||||
|
- Handles animation cleanup
|
||||||
|
|
||||||
|
### Timer (F)
|
||||||
|
- Manages dialogue duration
|
||||||
|
- Triggers automatic closure
|
||||||
|
- Provides timing feedback to system
|
||||||
|
- Handles edge cases (zero/negative durations)
|
||||||
|
|
||||||
|
## Flow Description
|
||||||
|
|
||||||
|
1. **Trigger**: Base character calls `trigger_dialogue(text, duration)`
|
||||||
|
2. **Show**: DialogueSystem initiates show animation for DialogueBox
|
||||||
|
3. **Reveal**: TextRevealer starts character-by-character text display
|
||||||
|
4. **Wait**: Timer waits for specified duration
|
||||||
|
5. **Hide**: AnimationController triggers hide animation
|
||||||
|
6. **Complete**: System returns to idle state
|
||||||
|
|
||||||
|
## Integration Points
|
||||||
|
|
||||||
|
- Base Character Scene: Public API interface
|
||||||
|
- DialogueBox UI: Visual rendering component
|
||||||
|
- TextRevealer: Text animation logic
|
||||||
|
- AnimationController: UI transition handling
|
||||||
|
- Timer: Duration management
|
||||||
3
main.tscn
Normal file
3
main.tscn
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[gd_scene format=3 uid="uid://dihuaoy6htse6"]
|
||||||
|
|
||||||
|
[node name="Node2D" type="Node2D"]
|
||||||
82
plans/base_character_dialogue_plan.md
Normal file
82
plans/base_character_dialogue_plan.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# Base Character Scene with Dialogue System Design Plan
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
Create a base character scene with:
|
||||||
|
1. A sprite/shape (using Polygon2D for now)
|
||||||
|
2. A dialogue entity that can be triggered programmatically
|
||||||
|
3. Visual dialogue box with animation and character-by-character text reveal
|
||||||
|
4. Test scene to demonstrate the behavior
|
||||||
|
|
||||||
|
## Implementation Steps
|
||||||
|
|
||||||
|
### 1. Base Character Scene Design
|
||||||
|
- Create a new scene file `scenes/base_character.tscn`
|
||||||
|
- Add a Polygon2D node as the character sprite
|
||||||
|
- Add necessary child nodes for dialogue system integration
|
||||||
|
- Set up proper positioning and scaling
|
||||||
|
|
||||||
|
### 2. Dialogue UI System
|
||||||
|
- Create dialogue box UI with:
|
||||||
|
- Background rectangle (white)
|
||||||
|
- Text display area
|
||||||
|
- Animation for showing/hiding
|
||||||
|
- Implement character-by-character text reveal
|
||||||
|
- Handle timing and duration logic
|
||||||
|
|
||||||
|
### 3. Dialogue Action Integration
|
||||||
|
- Extend or modify DialogueAction to use new UI system
|
||||||
|
- Ensure compatibility with existing cutscene manager
|
||||||
|
- Add proper signal handling for animation completion
|
||||||
|
|
||||||
|
### 4. Test Scene
|
||||||
|
- Create test scene `scenes/test_dialogue.tscn`
|
||||||
|
- Add base character instance
|
||||||
|
- Automatically trigger dialogue on scene load
|
||||||
|
- Demonstrate the complete functionality
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
|
||||||
|
### Base Character Scene Structure
|
||||||
|
```
|
||||||
|
Node2D (root)
|
||||||
|
├── Polygon2D (character sprite)
|
||||||
|
└── DialogueSystem (script for handling dialogue UI)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dialogue System Components
|
||||||
|
1. **DialogueBox**: Visual element that appears when dialogue is triggered
|
||||||
|
2. **TextRevealer**: Handles character-by-character text display
|
||||||
|
3. **AnimationController**: Manages show/hide animations
|
||||||
|
4. **Timer**: Controls duration of dialogue display
|
||||||
|
|
||||||
|
### DialogueAction Integration Points
|
||||||
|
- `start()` method should trigger UI display
|
||||||
|
- Text and duration parameters should be passed to UI system
|
||||||
|
- Completion signal should be properly emitted
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
```
|
||||||
|
scenes/
|
||||||
|
├── base_character.tscn
|
||||||
|
└── test_dialogue.tscn
|
||||||
|
|
||||||
|
scripts/
|
||||||
|
├── dialogue_system.gd
|
||||||
|
└── base_character.gd
|
||||||
|
|
||||||
|
cutscene/
|
||||||
|
└── actions/
|
||||||
|
└── DialogueAction.gd (modified)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Implementation Approach
|
||||||
|
1. First, create the base character scene with Polygon2D
|
||||||
|
2. Implement the dialogue UI system in a separate script
|
||||||
|
3. Modify DialogueAction to integrate with new UI system
|
||||||
|
4. Create test scene that demonstrates functionality
|
||||||
|
5. Ensure all components work together within existing cutscene framework
|
||||||
|
|
||||||
|
## Animation Requirements
|
||||||
|
- Dialogue box should animate in (fade/slide)
|
||||||
|
- Text should reveal character-by-character with delay
|
||||||
|
- Dialogue box should animate out after duration ends
|
||||||
10
scenes/base_character.tscn
Normal file
10
scenes/base_character.tscn
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[gd_scene format=3 uid="uid://basecharacter"]
|
||||||
|
|
||||||
|
[node name="BaseCharacter" type="Node2D"]
|
||||||
|
|
||||||
|
[node name="Sprite" type="Polygon2D" parent="."]
|
||||||
|
color = Color(0.2, 0.6, 1, 1)
|
||||||
|
antialiased = true
|
||||||
|
polygon = PackedVector2Array(10, -20, 20, 0, 10, 20, -10, 20, -20, 0, -10, -20)
|
||||||
|
|
||||||
|
[node name="DialogueSystem" type="Node" parent="."]
|
||||||
23
scenes/test_dialogue.tscn
Normal file
23
scenes/test_dialogue.tscn
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://testdialogue"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scripts/test_dialogue.gd" id="1_f305o"]
|
||||||
|
[ext_resource type="Script" path="res://scripts/base_character.gd" id="2_00bif"]
|
||||||
|
[ext_resource type="Script" path="res://scripts/dialogue_system.gd" id="3_11ynk"]
|
||||||
|
|
||||||
|
[node name="TestScene" type="Node2D"]
|
||||||
|
position = Vector2(-1, 0)
|
||||||
|
script = ExtResource("1_f305o")
|
||||||
|
|
||||||
|
[node name="Character" type="Node2D" parent="."]
|
||||||
|
position = Vector2(407, 206)
|
||||||
|
|
||||||
|
[node name="BaseCharacter" type="Node2D" parent="Character"]
|
||||||
|
script = ExtResource("2_00bif")
|
||||||
|
|
||||||
|
[node name="Sprite" type="Polygon2D" parent="Character/BaseCharacter"]
|
||||||
|
color = Color(0.2, 0.6, 1, 1)
|
||||||
|
antialiased = true
|
||||||
|
polygon = PackedVector2Array(10, -20, 20, 0, 10, 20, -10, 20, -20, 0, -10, -20)
|
||||||
|
|
||||||
|
[node name="DialogueSystem" type="Node2D" parent="Character/BaseCharacter"]
|
||||||
|
script = ExtResource("3_11ynk")
|
||||||
35
scripts/base_character.gd
Normal file
35
scripts/base_character.gd
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
extends Node2D
|
||||||
|
|
||||||
|
# Base character class that can display dialogue
|
||||||
|
# This extends Node2D to be compatible with Godot's scene system
|
||||||
|
|
||||||
|
# Reference to the dialogue system
|
||||||
|
var dialogue_system: Node = null
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
signal dialogue_started()
|
||||||
|
signal dialogue_completed()
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
# Find and setup dialogue system
|
||||||
|
dialogue_system = get_node_or_null("DialogueSystem")
|
||||||
|
if dialogue_system:
|
||||||
|
dialogue_system.connect("dialogue_started", self._on_dialogue_started)
|
||||||
|
dialogue_system.connect("dialogue_completed", self._on_dialogue_completed)
|
||||||
|
else:
|
||||||
|
print("Warning: No dialogue system found on character")
|
||||||
|
|
||||||
|
func trigger_dialogue(text: String, duration: float = 3.0) -> void:
|
||||||
|
"""Public method to trigger dialogue on this character"""
|
||||||
|
if dialogue_system:
|
||||||
|
dialogue_system.trigger_dialogue(text, duration)
|
||||||
|
else:
|
||||||
|
print("Warning: No dialogue system found on character")
|
||||||
|
|
||||||
|
func _on_dialogue_started():
|
||||||
|
"""Handle dialogue start signal"""
|
||||||
|
emit_signal("dialogue_started")
|
||||||
|
|
||||||
|
func _on_dialogue_completed():
|
||||||
|
"""Handle dialogue completion signal"""
|
||||||
|
emit_signal("dialogue_completed")
|
||||||
176
scripts/dialogue_system.gd
Normal file
176
scripts/dialogue_system.gd
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
extends Node2D
|
||||||
|
|
||||||
|
# Dialogue system for Godot 4.x
|
||||||
|
# Handles displaying dialogue with animations and text reveal
|
||||||
|
|
||||||
|
# Signals
|
||||||
|
signal dialogue_started()
|
||||||
|
signal dialogue_completed()
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
@export var text_reveal_speed: float = 0.05 # seconds per character
|
||||||
|
@export var show_animation_duration: float = 0.3 # seconds
|
||||||
|
@export var hide_animation_duration: float = 0.2 # seconds
|
||||||
|
|
||||||
|
# Private variables
|
||||||
|
var dialogue_box: Control = null
|
||||||
|
var text_label: Label = null
|
||||||
|
var timer: Timer = null
|
||||||
|
var current_text: String = ""
|
||||||
|
var current_duration: float = 0.0
|
||||||
|
var text_index: int = 0
|
||||||
|
var is_showing: bool = false
|
||||||
|
var is_revealing: bool = false
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
# Initialize the dialogue system
|
||||||
|
_create_dialogue_ui()
|
||||||
|
|
||||||
|
func _create_dialogue_ui():
|
||||||
|
# Create dialogue box UI
|
||||||
|
dialogue_box = Control.new()
|
||||||
|
dialogue_box.name = "DialogueBox"
|
||||||
|
|
||||||
|
# Create background
|
||||||
|
var background = ColorRect.new()
|
||||||
|
background.name = "Background"
|
||||||
|
background.color = Color(1, 1, 1, 1) # White background
|
||||||
|
background.size = Vector2(300, 80)
|
||||||
|
background.anchor_left = 0.5
|
||||||
|
background.anchor_top = 1.0
|
||||||
|
background.anchor_right = 0.5
|
||||||
|
background.anchor_bottom = 1.0
|
||||||
|
background.position = Vector2(-150, -40) # Positioned above character
|
||||||
|
background.pivot_offset = Vector2(150, 40) # Center pivot
|
||||||
|
|
||||||
|
# Create text label
|
||||||
|
text_label = Label.new()
|
||||||
|
text_label.name = "TextLabel"
|
||||||
|
text_label.text = ""
|
||||||
|
text_label.size = Vector2(280, 60)
|
||||||
|
text_label.anchor_left = 0.5
|
||||||
|
text_label.add_theme_color_override("font_color", Color.BLACK)
|
||||||
|
text_label.anchor_top = 0.5
|
||||||
|
text_label.anchor_right = 0.5
|
||||||
|
text_label.anchor_bottom = 0.5
|
||||||
|
text_label.position = Vector2(-140, -30) # Centered in background
|
||||||
|
text_label.pivot_offset = Vector2(140, 30) # Center pivot
|
||||||
|
text_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
|
||||||
|
text_label.vertical_alignment = VERTICAL_ALIGNMENT_TOP
|
||||||
|
text_label.autowrap_mode = 2 # TextServer.AUTOWRAP_WORD_SMART
|
||||||
|
#text_label.custom_styles.normal.font_size = 16
|
||||||
|
|
||||||
|
# Add to dialogue box
|
||||||
|
dialogue_box.add_child(background)
|
||||||
|
dialogue_box.add_child(text_label)
|
||||||
|
|
||||||
|
# Set initial state - hidden and transparent
|
||||||
|
dialogue_box.visible = false
|
||||||
|
dialogue_box.modulate.a = 0.0
|
||||||
|
|
||||||
|
# Add to scene tree (should be added to parent character)
|
||||||
|
add_child(dialogue_box)
|
||||||
|
|
||||||
|
# Position the dialogue box above the character
|
||||||
|
# This ensures it's positioned correctly relative to the character
|
||||||
|
if get_parent() != null:
|
||||||
|
var parent_pos = get_parent().position
|
||||||
|
dialogue_box.position = Vector2(parent_pos.x, parent_pos.y - 50) # Position above character
|
||||||
|
|
||||||
|
func trigger_dialogue(text: String, duration: float = 3.0) -> void:
|
||||||
|
"""Trigger dialogue with specified text and duration"""
|
||||||
|
if is_showing:
|
||||||
|
return
|
||||||
|
|
||||||
|
current_text = text
|
||||||
|
current_duration = duration
|
||||||
|
text_index = 0
|
||||||
|
is_showing = true
|
||||||
|
is_revealing = false
|
||||||
|
|
||||||
|
# Show the dialogue box with animation
|
||||||
|
show_dialogue_box()
|
||||||
|
|
||||||
|
# Start revealing text after a short delay to allow animation to complete
|
||||||
|
await get_tree().create_timer(show_animation_duration)
|
||||||
|
|
||||||
|
# Start revealing text immediately
|
||||||
|
start_text_reveal()
|
||||||
|
|
||||||
|
func show_dialogue_box():
|
||||||
|
"""Show dialogue box with animation"""
|
||||||
|
dialogue_box.visible = true
|
||||||
|
|
||||||
|
# Animate in using Tween
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.set_ease(Tween.EASE_OUT)
|
||||||
|
tween.set_trans(Tween.TRANS_SINE)
|
||||||
|
tween.tween_property(dialogue_box, "modulate:a", 1.0, show_animation_duration)
|
||||||
|
|
||||||
|
# Emit signal when animation completes
|
||||||
|
await tween.finished
|
||||||
|
emit_signal("dialogue_started")
|
||||||
|
|
||||||
|
func hide_dialogue_box():
|
||||||
|
"""Hide dialogue box with animation"""
|
||||||
|
# Animate out using Tween
|
||||||
|
var tween = create_tween()
|
||||||
|
tween.set_ease(Tween.EASE_IN)
|
||||||
|
tween.set_trans(Tween.TRANS_SINE)
|
||||||
|
tween.tween_property(dialogue_box, "modulate:a", 0.0, hide_animation_duration)
|
||||||
|
|
||||||
|
# Wait for animation to complete
|
||||||
|
await tween.finished
|
||||||
|
|
||||||
|
dialogue_box.visible = false
|
||||||
|
is_showing = false
|
||||||
|
is_revealing = false
|
||||||
|
emit_signal("dialogue_completed")
|
||||||
|
|
||||||
|
func start_text_reveal():
|
||||||
|
"""Start revealing text character by character"""
|
||||||
|
if is_revealing:
|
||||||
|
return
|
||||||
|
|
||||||
|
is_revealing = true
|
||||||
|
text_label.text = ""
|
||||||
|
text_index = 0
|
||||||
|
|
||||||
|
# If duration is 0 or negative, don't auto-hide
|
||||||
|
if current_duration <= 0:
|
||||||
|
# Just reveal all text immediately
|
||||||
|
text_label.text = current_text
|
||||||
|
is_revealing = false
|
||||||
|
return
|
||||||
|
|
||||||
|
# Start timer for automatic hiding
|
||||||
|
timer = Timer.new()
|
||||||
|
timer.wait_time = current_duration
|
||||||
|
timer.one_shot = true
|
||||||
|
|
||||||
|
timer.connect("timeout", self._on_dialogue_timeout)
|
||||||
|
add_child(timer)
|
||||||
|
timer.start()
|
||||||
|
|
||||||
|
# Start the character-by-character reveal
|
||||||
|
reveal_next_character()
|
||||||
|
|
||||||
|
func reveal_next_character():
|
||||||
|
"""Reveal the next character in the text"""
|
||||||
|
if text_index >= current_text.length():
|
||||||
|
# Finished revealing all characters
|
||||||
|
is_revealing = false
|
||||||
|
return
|
||||||
|
|
||||||
|
# Add the next character to the text label
|
||||||
|
text_label.text += current_text[text_index]
|
||||||
|
text_index += 1
|
||||||
|
|
||||||
|
# Schedule next character reveal
|
||||||
|
await get_tree().create_timer(text_reveal_speed)
|
||||||
|
reveal_next_character()
|
||||||
|
|
||||||
|
func _on_dialogue_timeout():
|
||||||
|
"""Handle dialogue timeout"""
|
||||||
|
if is_showing and not is_revealing:
|
||||||
|
hide_dialogue_box()
|
||||||
10
scripts/test_dialogue.gd
Normal file
10
scripts/test_dialogue.gd
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
extends Node2D
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
# Find the character and trigger dialogue after a short delay
|
||||||
|
var character = $Character/BaseCharacter
|
||||||
|
print("HELLO AND HERE")
|
||||||
|
if character:
|
||||||
|
# Wait a bit to let the scene load properly, then trigger dialogue
|
||||||
|
await get_tree().create_timer(1.0).timeout
|
||||||
|
character.trigger_dialogue("Hello! This is a test dialogue line that will reveal character by character.", 5.0)
|
||||||
Reference in New Issue
Block a user