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,14 +1,14 @@
extends Area2D
const DEFAULT_SPEED = 100
const DEFAULT_SPEED = 100.0
var direction = Vector2.LEFT
var stopped = false
var _speed = DEFAULT_SPEED
var direction := Vector2.LEFT
var stopped := false
var _speed := DEFAULT_SPEED
@onready var _screen_size = get_viewport_rect().size
@onready var _screen_size := get_viewport_rect().size
func _process(delta):
func _process(delta: float) -> void:
_speed += delta
# Ball will move normally for both players,
# even if it's sightly out of sync between them,
@@ -17,24 +17,24 @@ func _process(delta):
translate(_speed * delta * direction)
# Check screen bounds to make ball bounce.
var ball_pos = position
var ball_pos := position
if (ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > _screen_size.y and direction.y > 0):
direction.y = -direction.y
if is_multiplayer_authority():
# Only the master will decide when the ball is out in
# the left side (it's own side). This makes the game
# the left side (its own side). This makes the game
# playable even if latency is high and ball is going
# fast. Otherwise ball might be out in the other
# fast. Otherwise, the ball might be out in the other
# player's screen but not this one.
if ball_pos.x < 0:
get_parent().update_score.rpc(false)
_reset_ball.rpc(false)
else:
# Only the puppet will decide when the ball is out in
# the right side, which is it's own side. This makes
# the right side, which is its own side. This makes
# the game playable even if latency is high and ball
# is going fast. Otherwise ball might be out in the
# is going fast. Otherwise, the ball might be out in the
# other player's screen but not this one.
if ball_pos.x > _screen_size.x:
get_parent().update_score.rpc(true)
@@ -42,7 +42,7 @@ func _process(delta):
@rpc("any_peer", "call_local")
func bounce(left, random):
func bounce(left: bool, random: float) -> void:
# Using sync because both players can make it bounce.
if left:
direction.x = abs(direction.x)
@@ -55,12 +55,12 @@ func bounce(left, random):
@rpc("any_peer", "call_local")
func stop():
func stop() -> void:
stopped = true
@rpc("any_peer", "call_local")
func _reset_ball(for_left):
func _reset_ball(for_left: float) -> void:
position = _screen_size / 2
if for_left:
direction = Vector2.LEFT

View File

@@ -1,21 +1,21 @@
extends Control
# Default game server port. Can be any number between 1024 and 49151.
# Not present on the list of registered or common ports as of December 2022:
# Not present on the list of registered or common ports as of May 2024:
# https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers
const DEFAULT_PORT = 8910
@onready var address = $Address
@onready var host_button = $HostButton
@onready var join_button = $JoinButton
@onready var status_ok = $StatusOk
@onready var status_fail = $StatusFail
@onready var port_forward_label = $PortForward
@onready var find_public_ip_button = $FindPublicIP
@onready var address: LineEdit = $Address
@onready var host_button: Button = $HostButton
@onready var join_button: Button = $JoinButton
@onready var status_ok: Label = $StatusOk
@onready var status_fail: Label = $StatusFail
@onready var port_forward_label: Label = $PortForward
@onready var find_public_ip_button: LinkButton = $FindPublicIP
var peer = null
var peer: ENetMultiplayerPeer
func _ready():
func _ready() -> void:
# Connect all the callbacks related to networking.
multiplayer.peer_connected.connect(_player_connected)
multiplayer.peer_disconnected.connect(_player_disconnected)
@@ -23,12 +23,11 @@ func _ready():
multiplayer.connection_failed.connect(_connected_fail)
multiplayer.server_disconnected.connect(_server_disconnected)
#### Network callbacks from SceneTree ####
#region Network callbacks from SceneTree
# Callback from SceneTree.
func _player_connected(_id):
func _player_connected(_id: int) -> void:
# Someone connected, start the game!
var pong = load("res://pong.tscn").instantiate()
var pong: Node2D = load("res://pong.tscn").instantiate()
# Connect deferred so we can safely erase it from the callback.
pong.game_finished.connect(_end_game, CONNECT_DEFERRED)
@@ -36,49 +35,49 @@ func _player_connected(_id):
hide()
func _player_disconnected(_id):
func _player_disconnected(_id: int) -> void:
if multiplayer.is_server():
_end_game("Client disconnected")
_end_game("Client disconnected.")
else:
_end_game("Server disconnected")
_end_game("Server disconnected.")
# Callback from SceneTree, only for clients (not server).
func _connected_ok():
func _connected_ok() -> void:
pass # This function is not needed for this project.
# Callback from SceneTree, only for clients (not server).
func _connected_fail():
func _connected_fail() -> void:
_set_status("Couldn't connect.", false)
multiplayer.set_multiplayer_peer(null) # Remove peer.
multiplayer.set_multiplayer_peer(null) # Remove peer.
host_button.set_disabled(false)
join_button.set_disabled(false)
func _server_disconnected():
func _server_disconnected() -> void:
_end_game("Server disconnected.")
#endregion
##### Game creation functions ######
func _end_game(with_error = ""):
#region Game creation methods
func _end_game(with_error: String = "") -> void:
if has_node("/root/Pong"):
# Erase immediately, otherwise network might show
# errors (this is why we connected deferred above).
get_node(^"/root/Pong").free()
show()
multiplayer.set_multiplayer_peer(null) # Remove peer.
multiplayer.set_multiplayer_peer(null) # Remove peer.
host_button.set_disabled(false)
join_button.set_disabled(false)
_set_status(with_error, false)
func _set_status(text, isok):
func _set_status(text: String, is_ok: bool) -> void:
# Simple way to show status.
if isok:
if is_ok:
status_ok.set_text(text)
status_fail.set_text("")
else:
@@ -86,9 +85,10 @@ func _set_status(text, isok):
status_fail.set_text(text)
func _on_host_pressed():
func _on_host_pressed() -> void:
peer = ENetMultiplayerPeer.new()
var err = peer.create_server(DEFAULT_PORT, 1) # Maximum of 1 peer, since it's a 2-player game.
# Set a maximum of 1 peer, since Pong is a 2-player game.
var err := peer.create_server(DEFAULT_PORT, 1)
if err != OK:
# Is another server running?
_set_status("Can't host, address in use.",false)
@@ -99,14 +99,15 @@ func _on_host_pressed():
host_button.set_disabled(true)
join_button.set_disabled(true)
_set_status("Waiting for player...", true)
get_window().title = ProjectSettings.get_setting("application/config/name") + ": Server"
# Only show hosting instructions when relevant.
port_forward_label.visible = true
find_public_ip_button.visible = true
func _on_join_pressed():
var ip = address.get_text()
func _on_join_pressed() -> void:
var ip := address.get_text()
if not ip.is_valid_ip_address():
_set_status("IP address is invalid.", false)
return
@@ -117,7 +118,8 @@ func _on_join_pressed():
multiplayer.set_multiplayer_peer(peer)
_set_status("Connecting...", true)
get_window().title = ProjectSettings.get_setting("application/config/name") + ": Client"
#endregion
func _on_find_public_ip_pressed():
func _on_find_public_ip_pressed() -> void:
OS.shell_open("https://icanhazip.com/")

View File

@@ -2,14 +2,14 @@ extends Area2D
const MOTION_SPEED = 150
@export var left = false
@export var left := false
var _motion = 0
var _you_hidden = false
var _motion := 0.0
var _you_hidden := false
@onready var _screen_size_y = get_viewport_rect().size.y
@onready var _screen_size_y := get_viewport_rect().size.y
func _process(delta):
func _process(delta: float) -> void:
# Is the master of the paddle.
if is_multiplayer_authority():
_motion = Input.get_axis(&"move_up", &"move_down")
@@ -26,25 +26,25 @@ func _process(delta):
if not _you_hidden:
_hide_you_label()
translate(Vector2(0, _motion * delta))
translate(Vector2(0.0, _motion * delta))
# Set screen limits.
position.y = clamp(position.y, 16, _screen_size_y - 16)
position.y = clampf(position.y, 16, _screen_size_y - 16)
# Synchronize position and speed to the other peers.
@rpc("unreliable")
func set_pos_and_motion(pos, motion):
func set_pos_and_motion(pos: Vector2, motion: float) -> void:
position = pos
_motion = motion
func _hide_you_label():
func _hide_you_label() -> void:
_you_hidden = true
get_node(^"You").hide()
$You.hide()
func _on_paddle_area_enter(area):
func _on_paddle_area_enter(area: Area2D) -> void:
if is_multiplayer_authority():
# Random for new direction generated checked each peer.
area.bounce.rpc(left, randf())

View File

@@ -4,16 +4,16 @@ signal game_finished()
const SCORE_TO_WIN = 10
var score_left = 0
var score_right = 0
var score_left := 0
var score_right := 0
@onready var player2 = $Player2
@onready var score_left_node = $ScoreLeft
@onready var score_right_node = $ScoreRight
@onready var winner_left = $WinnerLeft
@onready var winner_right = $WinnerRight
@onready var player2: Area2D = $Player2
@onready var score_left_node: Label = $ScoreLeft
@onready var score_right_node: Label = $ScoreRight
@onready var winner_left: Label = $WinnerLeft
@onready var winner_right: Label = $WinnerRight
func _ready():
func _ready() -> void:
# By default, all nodes in server inherit from master,
# while all nodes in clients inherit from puppet.
# set_multiplayer_authority is tree-recursive by default.
@@ -28,7 +28,7 @@ func _ready():
@rpc("any_peer", "call_local")
func update_score(add_to_left):
func update_score(add_to_left: int) -> void:
if add_to_left:
score_left += 1
score_left_node.set_text(str(score_left))
@@ -36,7 +36,7 @@ func update_score(add_to_left):
score_right += 1
score_right_node.set_text(str(score_right))
var game_ended = false
var game_ended := false
if score_left == SCORE_TO_WIN:
winner_left.show()
game_ended = true
@@ -49,5 +49,5 @@ func update_score(add_to_left):
$Ball.stop.rpc()
func _on_exit_game_pressed():
func _on_exit_game_pressed() -> void:
game_finished.emit()

View File

@@ -81,7 +81,6 @@ text = "Exit Game"
[node name="Camera2D" type="Camera2D" parent="."]
offset = Vector2(320, 200)
current = true
[connection signal="pressed" from="ExitGame" to="." method="_on_exit_game_pressed"]

View File

@@ -19,35 +19,38 @@ run/main_scene="res://lobby.tscn"
config/features=PackedStringArray("4.2")
config/icon="res://icon.webp"
[debug]
gdscript/warnings/untyped_declaration=1
[display]
window/size/viewport_width=640
window/size/viewport_height=400
window/stretch/mode="canvas_items"
window/stretch/aspect="expand"
window/stretch/scale_mode="integer"
[input]
move_down={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":16777234,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":90,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":83,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
]
}
move_up={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":16777232,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":65,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":87,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null)
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":122,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null)
]
}
move_down={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"echo":false,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null)
]
}
[rendering]
textures/canvas_textures/default_texture_filter=0
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"