mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2025-12-31 09:49:06 +03:00
Use static typing in all demos (#1063)
This leads to code that is easier to understand and runs faster thanks to GDScript's typed instructions. The untyped declaration warning is now enabled on all projects where type hints were added. All projects currently run without any untyped declration warnings. Dodge the Creeps and Squash the Creeps demos intentionally don't use type hints to match the documentation, where type hints haven't been adopted yet (given its beginner focus).
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
extends Node
|
||||
# Changing scenes is most easily done using the functions change_scene_to_file
|
||||
# and change_scene_to_packed of the SceneTree. This script demonstrates how to
|
||||
# change scenes without those helpers.
|
||||
# Changing scenes is most easily done using the `change_scene_to_file()` and
|
||||
# `change_scene_to_packed()` methods of SceneTree. This script demonstrates
|
||||
# how to change scenes without those helpers.
|
||||
|
||||
|
||||
func goto_scene(path: String):
|
||||
func goto_scene(path: String) -> void:
|
||||
# This function will usually be called from a signal callback,
|
||||
# or some other function from the running scene.
|
||||
# Deleting the current scene at this point might be
|
||||
@@ -16,12 +16,12 @@ func goto_scene(path: String):
|
||||
_deferred_goto_scene.call_deferred(path)
|
||||
|
||||
|
||||
func _deferred_goto_scene(path: String):
|
||||
func _deferred_goto_scene(path: String) -> void:
|
||||
# Immediately free the current scene. There is no risk here because the
|
||||
# call to this method is already deferred.
|
||||
get_tree().current_scene.free()
|
||||
|
||||
var packed_scene := ResourceLoader.load(path) as PackedScene
|
||||
var packed_scene: PackedScene = ResourceLoader.load(path)
|
||||
|
||||
var instanced_scene := packed_scene.instantiate()
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ config/icon="res://icon.webp"
|
||||
|
||||
global="*res://global.gd"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
extends Panel
|
||||
|
||||
|
||||
func _on_goto_scene_pressed():
|
||||
func _on_goto_scene_pressed() -> void:
|
||||
global.goto_scene("res://scene_b.tscn")
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
extends Panel
|
||||
|
||||
|
||||
func _on_goto_scene_pressed():
|
||||
func _on_goto_scene_pressed() -> void:
|
||||
global.goto_scene("res://scene_a.tscn")
|
||||
|
||||
@@ -1,42 +1,41 @@
|
||||
extends VBoxContainer
|
||||
|
||||
|
||||
func _on_start_loading_pressed():
|
||||
func _on_start_loading_pressed() -> void:
|
||||
ResourceLoader.load_threaded_request("res://paintings/painting_babel.jpg")
|
||||
ResourceLoader.load_threaded_request("res://paintings/painting_las_meninas.png")
|
||||
ResourceLoader.load_threaded_request("res://paintings/painting_mona_lisa.jpg")
|
||||
ResourceLoader.load_threaded_request("res://paintings/painting_old_guitarist.jpg")
|
||||
ResourceLoader.load_threaded_request("res://paintings/painting_parasol.jpg")
|
||||
ResourceLoader.load_threaded_request("res://paintings/painting_the_swing.jpg")
|
||||
for current_button in $GetLoaded.get_children():
|
||||
for current_button: Button in $GetLoaded.get_children():
|
||||
current_button.disabled = false
|
||||
|
||||
|
||||
func _on_babel_pressed():
|
||||
func _on_babel_pressed() -> void:
|
||||
$Paintings/Babel.texture = ResourceLoader.load_threaded_get("res://paintings/painting_babel.jpg")
|
||||
$GetLoaded/Babel.disabled = true
|
||||
|
||||
|
||||
func _on_las_meninas_pressed():
|
||||
func _on_las_meninas_pressed() -> void:
|
||||
$Paintings/LasMeninas.texture = ResourceLoader.load_threaded_get("res://paintings/painting_las_meninas.png")
|
||||
$GetLoaded/LasMeninas.disabled = true
|
||||
|
||||
|
||||
func _on_mona_lisa_pressed():
|
||||
func _on_mona_lisa_pressed() -> void:
|
||||
$Paintings/MonaLisa.texture = ResourceLoader.load_threaded_get("res://paintings/painting_mona_lisa.jpg")
|
||||
$GetLoaded/MonaLisa.disabled = true
|
||||
|
||||
|
||||
func _on_old_guitarist_pressed():
|
||||
func _on_old_guitarist_pressed() -> void:
|
||||
$Paintings/OldGuitarist.texture = ResourceLoader.load_threaded_get("res://paintings/painting_old_guitarist.jpg")
|
||||
$GetLoaded/OldGuitarist.disabled = true
|
||||
|
||||
|
||||
func _on_parasol_pressed():
|
||||
func _on_parasol_pressed() -> void:
|
||||
$Paintings/Parasol.texture = ResourceLoader.load_threaded_get("res://paintings/painting_parasol.jpg")
|
||||
$GetLoaded/Parasol.disabled = true
|
||||
|
||||
|
||||
func _on_swing_pressed():
|
||||
func _on_swing_pressed() -> void:
|
||||
$Paintings/Swing.texture = ResourceLoader.load_threaded_get("res://paintings/painting_the_swing.jpg")
|
||||
$GetLoaded/Swing.disabled = true
|
||||
|
||||
@@ -18,6 +18,10 @@ config/features=PackedStringArray("4.2")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/vsync/vsync_mode=0
|
||||
|
||||
@@ -23,6 +23,10 @@ config/features=PackedStringArray("4.2")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -18,6 +18,10 @@ config/features=PackedStringArray("4.2")
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
extends Panel
|
||||
|
||||
|
||||
func _on_goto_scene_pressed():
|
||||
func _on_goto_scene_pressed() -> void:
|
||||
# Change the scene to the one located at the given path.
|
||||
get_tree().change_scene_to_file("res://scene_b.tscn")
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
extends Panel
|
||||
|
||||
|
||||
func _on_goto_scene_pressed():
|
||||
func _on_goto_scene_pressed() -> void:
|
||||
# Change the scene to the given PackedScene.
|
||||
# Though it usually takes more code, this can have advantages, such as letting you load the
|
||||
# scene in another thread, or use a scene that isn't saved to a file.
|
||||
var scene := load("res://scene_a.tscn") as PackedScene
|
||||
var scene: PackedScene = load("res://scene_a.tscn")
|
||||
get_tree().change_scene_to_packed(scene)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class_name Enemy extends Node2D
|
||||
|
||||
class_name Enemy
|
||||
extends Node2D
|
||||
|
||||
## Movement speed in pixels per second.
|
||||
const MOVEMENT_SPEED = 75.0
|
||||
@@ -9,8 +9,7 @@ const DAMAGE_PER_SECOND = 15.0
|
||||
## If [code]null[/code], nobody is in range to attack.
|
||||
var attacking: Player = null
|
||||
|
||||
|
||||
func _process(delta: float):
|
||||
func _process(delta: float) -> void:
|
||||
if is_instance_valid(attacking):
|
||||
attacking.health -= delta * DAMAGE_PER_SECOND
|
||||
|
||||
@@ -21,10 +20,10 @@ func _process(delta: float):
|
||||
position.x = -32
|
||||
|
||||
|
||||
func _on_attack_area_body_entered(body: PhysicsBody2D):
|
||||
func _on_attack_area_body_entered(body: PhysicsBody2D) -> void:
|
||||
if body is Player:
|
||||
attacking = body
|
||||
|
||||
|
||||
func _on_attack_area_body_exited(_body: PhysicsBody2D):
|
||||
func _on_attack_area_body_exited(_body: PhysicsBody2D) -> void:
|
||||
attacking = null
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
extends VBoxContainer
|
||||
|
||||
|
||||
func _ready():
|
||||
func _ready() -> void:
|
||||
# Don't allow loading files that don't exist yet.
|
||||
($SaveLoad/LoadConfigFile as Button).disabled = not FileAccess.file_exists("user://save_config_file.ini")
|
||||
($SaveLoad/LoadJSON as Button).disabled = not FileAccess.file_exists("user://save_json.json")
|
||||
|
||||
|
||||
func _on_open_user_data_folder_pressed():
|
||||
func _on_open_user_data_folder_pressed() -> void:
|
||||
OS.shell_open(ProjectSettings.globalize_path("user://"))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class_name Player extends CharacterBody2D
|
||||
|
||||
class_name Player
|
||||
extends CharacterBody2D
|
||||
|
||||
## Movement speed in pixels per second.
|
||||
const MOVEMENT_SPEED = 240.0
|
||||
@@ -18,8 +18,7 @@ var motion := Vector2()
|
||||
@onready var progress_bar := $ProgressBar as ProgressBar
|
||||
@onready var sprite := $Sprite2D as Sprite2D
|
||||
|
||||
|
||||
func _process(_delta: float):
|
||||
func _process(_delta: float) -> void:
|
||||
velocity = Input.get_vector(&"move_left", &"move_right", &"move_up", &"move_down")
|
||||
if velocity.length_squared() > 1.0:
|
||||
velocity = velocity.normalized()
|
||||
@@ -27,7 +26,7 @@ func _process(_delta: float):
|
||||
move_and_slide()
|
||||
|
||||
|
||||
func _input(event: InputEvent):
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed(&"move_left"):
|
||||
sprite.rotation = PI / 2
|
||||
elif event.is_action_pressed(&"move_right"):
|
||||
|
||||
@@ -21,6 +21,10 @@ run/main_scene="res://save_load.tscn"
|
||||
config/features=PackedStringArray("4.2")
|
||||
config/icon="res://icon.webp"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -44,12 +44,12 @@ texture = ExtResource("2_g2wd8")
|
||||
|
||||
[node name="ProgressBar" type="ProgressBar" parent="Game/Player"]
|
||||
offset_left = -32.0
|
||||
offset_top = -50.0
|
||||
offset_top = -52.0
|
||||
offset_right = 32.0
|
||||
offset_bottom = -33.0
|
||||
offset_bottom = -32.0
|
||||
theme_override_colors/font_outline_color = Color(0.152941, 0.152941, 0.152941, 1)
|
||||
theme_override_constants/outline_size = 6
|
||||
theme_override_font_sizes/font_size = 13
|
||||
theme_override_constants/outline_size = 8
|
||||
theme_override_font_sizes/font_size = 14
|
||||
theme_override_styles/background = SubResource("StyleBoxFlat_lkphp")
|
||||
theme_override_styles/fill = SubResource("StyleBoxFlat_smouc")
|
||||
value = 100.0
|
||||
|
||||
@@ -4,7 +4,6 @@ extends Button
|
||||
# It can even store Objects, but be extra careful where you deserialize them
|
||||
# from, because they can include (potentially malicious) scripts.
|
||||
|
||||
|
||||
const SAVE_PATH = "user://save_config_file.ini"
|
||||
|
||||
## The root game node (so we can get and instance enemies).
|
||||
@@ -13,7 +12,7 @@ const SAVE_PATH = "user://save_config_file.ini"
|
||||
@export var player_node: NodePath
|
||||
|
||||
|
||||
func save_game():
|
||||
func save_game() -> void:
|
||||
var config := ConfigFile.new()
|
||||
|
||||
var player := get_node(player_node) as Player
|
||||
@@ -30,10 +29,10 @@ func save_game():
|
||||
|
||||
config.save(SAVE_PATH)
|
||||
|
||||
(get_node(^"../LoadConfigFile") as Button).disabled = false
|
||||
($"../LoadConfigFile" as Button).disabled = false
|
||||
|
||||
|
||||
func load_game():
|
||||
func load_game() -> void:
|
||||
var config := ConfigFile.new()
|
||||
config.load(SAVE_PATH)
|
||||
|
||||
@@ -45,10 +44,10 @@ func load_game():
|
||||
# Remove existing enemies before adding new ones.
|
||||
get_tree().call_group("enemy", "queue_free")
|
||||
|
||||
var enemies = config.get_value("enemies", "enemies")
|
||||
var game = get_node(game_node)
|
||||
var enemies: Array = config.get_value("enemies", "enemies")
|
||||
var game := get_node(game_node)
|
||||
|
||||
for enemy_config in enemies:
|
||||
for enemy_config: Dictionary in enemies:
|
||||
var enemy := preload("res://enemy.tscn").instantiate() as Enemy
|
||||
enemy.position = enemy_config.position
|
||||
game.add_child(enemy)
|
||||
|
||||
@@ -5,7 +5,6 @@ extends Button
|
||||
# and to store Vector2 and other non-JSON types you need to convert
|
||||
# them, such as to a String using var_to_str.
|
||||
|
||||
|
||||
## The root game node (so we can get and instance enemies).
|
||||
@export var game_node: NodePath
|
||||
## The player node (so we can set/get its health and position).
|
||||
@@ -13,20 +12,19 @@ extends Button
|
||||
|
||||
const SAVE_PATH = "user://save_json.json"
|
||||
|
||||
|
||||
func save_game():
|
||||
func save_game() -> void:
|
||||
var file := FileAccess.open(SAVE_PATH, FileAccess.WRITE)
|
||||
|
||||
var player = get_node(player_node)
|
||||
var player := get_node(player_node)
|
||||
# JSON doesn't support many of Godot's types such as Vector2.
|
||||
# var_to_str can be used to convert any Variant to a String.
|
||||
var save_dict = {
|
||||
var save_dict := {
|
||||
player = {
|
||||
position = var_to_str(player.position),
|
||||
health = var_to_str(player.health),
|
||||
rotation = var_to_str(player.sprite.rotation)
|
||||
rotation = var_to_str(player.sprite.rotation),
|
||||
},
|
||||
enemies = []
|
||||
enemies = [],
|
||||
}
|
||||
|
||||
for enemy in get_tree().get_nodes_in_group(&"enemy"):
|
||||
@@ -39,7 +37,7 @@ func save_game():
|
||||
get_node(^"../LoadJSON").disabled = false
|
||||
|
||||
|
||||
func load_game():
|
||||
func load_game() -> void:
|
||||
var file := FileAccess.open(SAVE_PATH, FileAccess.READ)
|
||||
var json := JSON.new()
|
||||
json.parse(file.get_line())
|
||||
@@ -58,7 +56,7 @@ func load_game():
|
||||
# Ensure the node structure is the same when loading.
|
||||
var game := get_node(game_node)
|
||||
|
||||
for enemy_config in save_dict.enemies:
|
||||
var enemy = preload("res://enemy.tscn").instantiate()
|
||||
for enemy_config: Dictionary in save_dict.enemies:
|
||||
var enemy: Enemy = preload("res://enemy.tscn").instantiate()
|
||||
enemy.position = str_to_var(enemy_config.position)
|
||||
game.add_child(enemy)
|
||||
|
||||
@@ -20,6 +20,10 @@ config/icon="res://icon.webp"
|
||||
run/stretch/aspect="expand"
|
||||
run/stretch/mode="canvas_items"
|
||||
|
||||
[debug]
|
||||
|
||||
gdscript/warnings/untyped_declaration=1
|
||||
|
||||
[display]
|
||||
|
||||
window/stretch/mode="canvas_items"
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
extends Control
|
||||
|
||||
|
||||
var thread: Thread
|
||||
|
||||
|
||||
func _on_load_pressed():
|
||||
func _on_load_pressed() -> void:
|
||||
if is_instance_valid(thread) and thread.is_started():
|
||||
# If a thread is already running, let it finish before we start another.
|
||||
thread.wait_to_finish()
|
||||
thread = Thread.new()
|
||||
print("START THREAD!")
|
||||
print_rich("[b]Starting thread.")
|
||||
# Our method needs an argument, so we pass it using bind().
|
||||
thread.start(_bg_load.bind("res://mona.png"))
|
||||
|
||||
|
||||
func _bg_load(path: String):
|
||||
print("THREAD FUNC!")
|
||||
var tex = load(path)
|
||||
func _bg_load(path: String) -> Texture2D:
|
||||
print("Calling thread function.")
|
||||
var tex := load(path)
|
||||
# call_deferred() tells the main thread to call a method during idle time.
|
||||
# Our method operates on nodes currently in the tree, so it isn't safe to
|
||||
# call directly from another thread.
|
||||
@@ -24,16 +22,17 @@ func _bg_load(path: String):
|
||||
return tex
|
||||
|
||||
|
||||
func _bg_load_done():
|
||||
func _bg_load_done() -> void:
|
||||
# Wait for the thread to complete, and get the returned value.
|
||||
var tex = thread.wait_to_finish()
|
||||
print("THREAD FINISHED!")
|
||||
var tex: Texture2D = thread.wait_to_finish()
|
||||
print_rich("[b][i]Thread finished.\n")
|
||||
$TextureRect.texture = tex
|
||||
# We're done with the thread now, so we can free it.
|
||||
thread = null # Threads are reference counted, so this is how we free them.
|
||||
# Threads are reference counted, so this is how we free them.
|
||||
thread = null
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
func _exit_tree() -> void:
|
||||
# You should always wait for a thread to finish before letting it get freed!
|
||||
# It might not clean up correctly if you don't.
|
||||
if is_instance_valid(thread) and thread.is_started():
|
||||
|
||||
@@ -13,25 +13,35 @@ script = ExtResource("1")
|
||||
|
||||
[node name="Load" type="Button" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -115.0
|
||||
offset_top = 96.0
|
||||
offset_top = -227.5
|
||||
offset_right = 115.0
|
||||
offset_bottom = 151.0
|
||||
offset_bottom = -172.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 2
|
||||
size_flags_vertical = 2
|
||||
theme_override_font_sizes/font_size = 24
|
||||
text = "Load in Thread"
|
||||
|
||||
[node name="ColorRect" type="Panel" parent="."]
|
||||
layout_mode = 0
|
||||
offset_left = 461.0
|
||||
offset_top = 160.0
|
||||
offset_right = 692.0
|
||||
offset_bottom = 489.0
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -115.5
|
||||
offset_top = -164.5
|
||||
offset_right = 115.5
|
||||
offset_bottom = 164.5
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
layout_mode = 1
|
||||
|
||||
Reference in New Issue
Block a user