Basic game template addon
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 6s
Create tag and build when new code gets to main / Export (push) Successful in 1m1s

This commit is contained in:
2026-01-30 19:45:56 +01:00
parent b923f6bec2
commit 44f251ed66
406 changed files with 12602 additions and 1 deletions

View File

@@ -0,0 +1,126 @@
extends Control
## Scene for displaying opening logos, placards, or other images before a game.
## Defines the path to the next scene.
@export_file("*.tscn") var next_scene_path : String
## The list of images to show in the opening sequence.
@export var images : Array[Texture2D]
@export_group("Animation")
## The time to fade-in the next image.
@export var fade_in_time : float = 0.2
## The time to fade-out the previous image.
@export var fade_out_time : float = 0.2
## The time to keep an image visible after fade-in and before fade-out.
@export var visible_time : float = 1.6
@export_group("Transition")
## The delay before starting the first fade-in animation once ready.
@export var start_delay : float = 0.5
## The delay after ending the last fade-in animation before loading the next scene.
@export var end_delay : float = 0.5
## If true, show a loading screen if the next scene is not yet ready.
## Requires Maaack's Scene Loader.
@export var show_loading_screen : bool = false
## If Maaack's Scene Loader is installed, then it will be used to change scenes.
@onready var scene_loader_node = get_tree().root.get_node_or_null(^"SceneLoader")
var tween : Tween
var next_image_index : int = 0
func get_next_scene_path() -> String:
return next_scene_path
func _on_scene_loaded() -> void:
scene_loader_node.change_scene_to_resource()
func _load_next_scene() -> void:
if scene_loader_node:
var status = scene_loader_node.get_status()
if status == ResourceLoader.THREAD_LOAD_LOADED:
_on_scene_loaded()
elif show_loading_screen:
scene_loader_node.change_scene_to_loading_screen()
elif not scene_loader_node.scene_loaded.is_connected(_on_scene_loaded):
scene_loader_node.scene_loaded.connect(_on_scene_loaded, CONNECT_ONE_SHOT)
else:
get_tree().change_scene_to_file(get_next_scene_path())
func _add_textures_to_container(textures : Array[Texture2D]) -> void:
for texture in textures:
var texture_rect : TextureRect = TextureRect.new()
texture_rect.texture = texture
texture_rect.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
texture_rect.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
texture_rect.modulate.a = 0.0
%ImagesContainer.call_deferred("add_child", texture_rect)
func _event_skips_image(event : InputEvent) -> bool:
return event.is_action_released(&"ui_accept") or event.is_action_released(&"ui_select")
func _event_skips_intro(event : InputEvent) -> bool:
return event.is_action_released(&"ui_cancel")
func _event_is_mouse_button_released(event : InputEvent) -> bool:
return event is InputEventMouseButton and not event.is_pressed()
func _unhandled_input(event : InputEvent) -> void:
if _event_skips_intro(event):
_load_next_scene()
elif _event_skips_image(event):
_show_next_image(false)
func _gui_input(event : InputEvent) -> void:
if _event_is_mouse_button_released(event):
_show_next_image(false)
func _transition_out() -> void:
await get_tree().create_timer(end_delay).timeout
_load_next_scene()
func _transition_in() -> void:
await get_tree().create_timer(start_delay).timeout
if next_image_index == 0:
_show_next_image()
func _wait_and_fade_out(texture_rect : TextureRect) -> void:
var _compare_next_index = next_image_index
await get_tree().create_timer(visible_time, false).timeout
if _compare_next_index != next_image_index : return
tween = create_tween()
tween.tween_property(texture_rect, "modulate:a", 0.0, fade_out_time)
await tween.finished
_show_next_image.call_deferred()
func _hide_previous_image() -> void:
if tween and tween.is_running():
tween.stop()
if %ImagesContainer.get_child_count() == 0:
return
var current_image = %ImagesContainer.get_child(next_image_index - 1)
if current_image:
current_image.modulate.a = 0.0
func _show_next_image(animated : bool = true) -> void:
_hide_previous_image()
if next_image_index >= %ImagesContainer.get_child_count():
if animated:
_transition_out()
else:
_load_next_scene()
return
var texture_rect = %ImagesContainer.get_child(next_image_index)
if animated:
tween = create_tween()
tween.tween_property(texture_rect, "modulate:a", 1.0, fade_in_time)
await tween.finished
else:
texture_rect.modulate.a = 1.0
next_image_index += 1
_wait_and_fade_out(texture_rect)
func _ready() -> void:
AppSettings.set_from_config_and_window(get_window())
if scene_loader_node:
scene_loader_node.load_scene(get_next_scene_path(), true)
_add_textures_to_container(images)
_transition_in()