improvements

This commit is contained in:
2025-08-01 20:07:40 -07:00
parent cfb4aa874b
commit 5cde8be9a7
9 changed files with 581 additions and 0 deletions

35
scripts/base_character.gd Normal file
View 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
View 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
View 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)