7.7 KiB
7.7 KiB
Sample Cutscene Example
Overview
This document provides a complete example of how to use the cutscene system to create a complex sequence as described in the requirements.
Example Scenario
The example implements this sequence:
- Character1 moves to position (234, 591)
- At the same time, Character2 moves to position (912, 235)
- When both arrive, Character2 turns to face Character1
- Character2 says a dialogue line to Character1
- A special animation (shocked) is played for Character1
Sample Implementation
# Sample cutscene implementation
extends Node2D
# Character nodes (would be set in the editor or loaded)
var character1: Node2D
var character2: Node2D
# Cutscene manager
var cutscene_manager: CutsceneManager
func _ready() -> void:
# Initialize the cutscene system
setup_cutscene()
# Start the cutscene
cutscene_manager.start()
func setup_cutscene() -> void:
# Create the cutscene manager
cutscene_manager = CutsceneManager.new()
add_child(cutscene_manager)
# Create the action sequence as described in requirements
# 1. & 2. Characters move simultaneously
var parallel_moves = [
MoveAction.new(character1, Vector2(234, 591), 150.0), # Character1 moves
MoveAction.new(character2, Vector2(912, 235), 150.0) # Character2 moves
]
cutscene_manager.add_parallel_actions(parallel_moves)
# 3. Character2 turns to face Character1
var turn_action = TurnAction.new(character2, character1, 3.0)
cutscene_manager.add_action(turn_action)
# 4. Character2 says dialogue
var dialogue_action = DialogueAction.new(character2, "Hello there, friend!", 2.0)
cutscene_manager.add_action(dialogue_action)
# 5. Character1 plays shocked animation
var animation_action = AnimationAction.new(character1, "shocked", false)
cutscene_manager.add_action(animation_action)
# Set up cutscene callbacks
cutscene_manager.on_completed = func():
print("Cutscene completed!")
# Return to gameplay or next scene
# Alternative implementation with more complex chaining
func setup_advanced_cutscene() -> void:
cutscene_manager = CutsceneManager.new()
add_child(cutscene_manager)
# Create actions
var move1 = MoveAction.new(character1, Vector2(234, 591), 150.0)
var move2 = MoveAction.new(character2, Vector2(912, 235), 150.0)
var turn = TurnAction.new(character2, character1, 3.0)
var dialogue = DialogueAction.new(character2, "Hello there, friend!", 2.0)
var animation = AnimationAction.new(character1, "shocked", false)
# Add parallel actions
cutscene_manager.add_parallel_actions([move1, move2])
# Add sequential actions
cutscene_manager.add_action(turn)
cutscene_manager.add_action(dialogue)
cutscene_manager.add_action(animation)
# Set completion callback
cutscene_manager.on_completed = _on_cutscene_finished
}
func _on_cutscene_finished() -> void:
print("The cutscene has finished playing")
# Handle post-cutscene logic here
# For example, transition to gameplay state
More Complex Example with Conditional Logic
# Advanced example with conditional actions
func setup_conditional_cutscene() -> void:
cutscene_manager = CutsceneManager.new()
add_child(cutscene_manager)
# Move characters into position
var move_group = [
MoveAction.new(character1, Vector2(300, 400)),
MoveAction.new(character2, Vector2(500, 400))
]
cutscene_manager.add_parallel_actions(move_group)
# Conditional dialogue based on game state
var dialogue_action = DialogueAction.new(
character1,
get_dialogue_text(),
3.0
)
cutscene_manager.add_action(dialogue_action)
# Play different animation based on dialogue response
var animation_action = AnimationAction.new(
character2,
get_reaction_animation(),
false
)
cutscene_manager.add_action(animation_action)
# Wait for a moment
cutscene_manager.add_action(WaitAction.new(1.0))
# Final action
var final_dialogue = DialogueAction.new(
character2,
"That was interesting!",
2.0
)
cutscene_manager.add_action(final_dialogue)
func get_dialogue_text() -> String:
# This could be based on game state, player choices, etc.
return "What do you think about this situation?"
func get_reaction_animation() -> String:
# This could be based on game state, player choices, etc.
return "thoughtful"
Integration with Game Systems
# Example of integrating with a game state manager
class_name GameCutsceneManager
extends Node
var cutscene_manager: CutsceneManager
var game_state: GameStateManager
func play_story_cutscene(story_key: String) -> void:
# Pause gameplay
game_state.set_state(GameState.CUTSCENE)
# Create cutscene based on story key
var cutscene_data = load_cutscene_data(story_key)
cutscene_manager = create_cutscene_from_data(cutscene_data)
# Set up completion callback to resume gameplay
cutscene_manager.on_completed = func():
game_state.set_state(GameState.PLAYING)
# Clean up
cutscene_manager.queue_free()
cutscene_manager = null
# Start the cutscene
cutscene_manager.start()
func load_cutscene_data(key: String) -> Dictionary:
# Load cutscene data from a file or database
# This could be JSON, CSV, or custom format
return {
"actions": [
{"type": "move", "character": "player", "position": [100, 200]},
{"type": "dialogue", "character": "npc", "text": "Hello!"},
{"type": "animation", "character": "player", "name": "wave"}
]
}
func create_cutscene_from_data(data: Dictionary) -> CutsceneManager:
var manager = CutsceneManager.new()
add_child(manager)
# Convert data to actions
for action_data in data["actions"]:
var action = create_action_from_data(action_data)
if action:
manager.add_action(action)
return manager
func create_action_from_data(data: Dictionary) -> Action:
match data["type"]:
"move":
var character = get_character_by_name(data["character"])
var position = Vector2(data["position"][0], data["position"][1])
return MoveAction.new(character, position)
"dialogue":
var character = get_character_by_name(data["character"])
return DialogueAction.new(character, data["text"])
"animation":
var character = get_character_by_name(data["character"])
return AnimationAction.new(character, data["name"])
_:
return null
Performance Considerations
# Example of optimizing cutscene performance
func setup_optimized_cutscene() -> void:
cutscene_manager = CutsceneManager.new()
add_child(cutscene_manager)
# Pre-load any resources needed for actions
preload_animations()
preload_dialogue_textures()
# Use object pooling for frequently created actions
var move_action_pool = []
for i in range(10):
move_action_pool.append(MoveAction.new(null, Vector2.ZERO))
# Reuse actions when possible
var action1 = get_pooled_move_action(character1, Vector2(100, 100))
var action2 = get_pooled_move_action(character2, Vector2(200, 200))
cutscene_manager.add_parallel_actions([action1, action2])
# Clean up when done
cutscene_manager.on_completed = func():
release_pooled_actions()
# Other cleanup
This sample demonstrates how to use the cutscene system to create complex, dynamic sequences that can handle both sequential and parallel actions while maintaining clean, readable code.