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:
Hugo Locurcio
2024-06-01 12:12:18 +02:00
committed by GitHub
parent 8e9c180278
commit bac1e69164
498 changed files with 5218 additions and 4776 deletions

View File

@@ -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()

View File

@@ -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"

View File

@@ -1,5 +1,4 @@
extends Panel
func _on_goto_scene_pressed():
func _on_goto_scene_pressed() -> void:
global.goto_scene("res://scene_b.tscn")

View File

@@ -1,5 +1,4 @@
extends Panel
func _on_goto_scene_pressed():
func _on_goto_scene_pressed() -> void:
global.goto_scene("res://scene_a.tscn")

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -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")

View File

@@ -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)

View File

@@ -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

View File

@@ -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://"))

View File

@@ -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"):

View File

@@ -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"

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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"

View File

@@ -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():

View File

@@ -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