242 lines
7.7 KiB
Markdown
242 lines
7.7 KiB
Markdown
# 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:
|
|
1. Character1 moves to position (234, 591)
|
|
2. At the same time, Character2 moves to position (912, 235)
|
|
3. When both arrive, Character2 turns to face Character1
|
|
4. Character2 says a dialogue line to Character1
|
|
5. A special animation (shocked) is played for Character1
|
|
|
|
## Sample Implementation
|
|
|
|
```gdscript
|
|
# 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
|
|
|
|
```gdscript
|
|
# 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
|
|
|
|
```gdscript
|
|
# 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
|
|
|
|
```gdscript
|
|
# 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. |