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,17 +1,16 @@
@tool
extends Node2D
# If the mouse is farther than this many pixels, it won't grab anything.
const DEADZONE_RADIUS: float = 20
const DEADZONE_RADIUS_SQ: float = DEADZONE_RADIUS * DEADZONE_RADIUS
const DEADZONE_RADIUS = 20.0
const DEADZONE_RADIUS_SQ = DEADZONE_RADIUS * DEADZONE_RADIUS
# Not pixel perfect for all axes in all modes, but works well enough.
# Rounding is not done until after the movement is finished.
const ROUGHLY_ROUND_TO_PIXELS = true
# Set when the node is created.
var node_25d: Node25D
var _spatial_node
var _spatial_node: Node3D
# Input from Viewport25D, represents if the mouse is clicked.
var wants_to_move = false

View File

@@ -17,10 +17,11 @@ var moving = false
@onready var gizmo_25d_scene = preload("res://addons/node25d/main_screen/gizmo_25d.tscn")
func _ready():
func _ready() -> void:
# Give Godot a chance to fully load the scene. Should take two frames.
await get_tree().process_frame
await get_tree().process_frame
for i in 2:
await get_tree().process_frame
var edited_scene_root = get_tree().edited_scene_root
if not edited_scene_root:
# Godot hasn't finished loading yet, so try loading the plugin again.
@@ -34,13 +35,13 @@ func _ready():
viewport_2d.world_2d = world_2d
func _process(_delta):
func _process(_delta: float) -> void:
if not editor_interface: # Something's not right... bail!
return
# View mode polling.
var view_mode_changed_this_frame = false
var new_view_mode = -1
var view_mode_changed_this_frame := false
var new_view_mode := -1
if view_mode_button_group.get_pressed_button():
new_view_mode = view_mode_button_group.get_pressed_button().get_index()
if view_mode_index != new_view_mode:
@@ -53,15 +54,15 @@ func _process(_delta):
zoom_level += 1
elif Input.is_mouse_button_pressed(MOUSE_BUTTON_WHEEL_DOWN):
zoom_level -= 1
var zoom = _get_zoom_amount()
var zoom := _get_zoom_amount()
# SubViewport size.
var vp_size = get_global_rect().size
var vp_size := get_global_rect().size
viewport_2d.size = vp_size
viewport_overlay.size = vp_size
# SubViewport transform.
var viewport_trans = Transform2D.IDENTITY
var viewport_trans := Transform2D.IDENTITY
viewport_trans.x *= zoom
viewport_trans.y *= zoom
viewport_trans.origin = viewport_trans.basis_xform(viewport_center) + size / 2
@@ -69,10 +70,10 @@ func _process(_delta):
viewport_overlay.canvas_transform = viewport_trans
# Delete unused gizmos.
var selection = editor_interface.get_selection().get_selected_nodes()
var gizmos = viewport_overlay.get_children()
var selection := editor_interface.get_selection().get_selected_nodes()
var gizmos := viewport_overlay.get_children()
for gizmo in gizmos:
var contains = false
var contains := false
for selected in selection:
if selected == gizmo.node_25d and not view_mode_changed_this_frame:
contains = true
@@ -98,7 +99,7 @@ func _ensure_node25d_has_gizmo(node: Node25D, gizmos: Array[Node]) -> void:
# This only accepts input when the mouse is inside of the 2.5D viewport.
func _gui_input(event):
func _gui_input(event: InputEvent) -> void:
if event is InputEventMouseButton:
if event.is_pressed():
if event.button_index == MOUSE_BUTTON_WHEEL_UP:
@@ -112,7 +113,7 @@ func _gui_input(event):
pan_center = viewport_center - event.position / _get_zoom_amount()
accept_event()
elif event.button_index == MOUSE_BUTTON_LEFT:
var overlay_children = viewport_overlay.get_children()
var overlay_children := viewport_overlay.get_children()
for overlay_child in overlay_children:
overlay_child.wants_to_move = true
accept_event()
@@ -120,7 +121,7 @@ func _gui_input(event):
is_panning = false
accept_event()
elif event.button_index == MOUSE_BUTTON_LEFT:
var overlay_children = viewport_overlay.get_children()
var overlay_children := viewport_overlay.get_children()
for overlay_child in overlay_children:
overlay_child.wants_to_move = false
accept_event()
@@ -130,28 +131,31 @@ func _gui_input(event):
accept_event()
func _recursive_change_view_mode(current_node):
func _recursive_change_view_mode(current_node: Node) -> void:
if not current_node:
return
if current_node.has_method("set_view_mode"):
current_node.set_view_mode(view_mode_index)
for child in current_node.get_children():
_recursive_change_view_mode(child)
func _get_zoom_amount():
var zoom_amount = pow(1.05476607648, zoom_level) # 13th root of 2
func _get_zoom_amount() -> float:
const THIRTEENTH_ROOT_OF_2 = 1.05476607648
var zoom_amount = pow(THIRTEENTH_ROOT_OF_2, zoom_level)
zoom_label.text = str(round(zoom_amount * 1000) / 10) + "%"
return zoom_amount
func _on_ZoomOut_pressed():
func _on_ZoomOut_pressed() -> void:
zoom_level -= 1
func _on_ZoomIn_pressed():
func _on_ZoomIn_pressed() -> void:
zoom_level += 1
func _on_ZoomReset_pressed():
func _on_ZoomReset_pressed() -> void:
zoom_level = 0

View File

@@ -3,10 +3,10 @@ extends EditorPlugin
const MainPanel = preload("res://addons/node25d/main_screen/main_screen_25d.tscn")
var main_panel_instance
var main_panel_instance: Panel
func _enter_tree():
func _enter_tree() -> void:
main_panel_instance = MainPanel.instantiate()
main_panel_instance.get_child(1).editor_interface = get_editor_interface()
@@ -21,7 +21,7 @@ func _enter_tree():
add_custom_type("ShadowMath25D", "CharacterBody3D", preload("shadow_math_25d.gd"), preload("icons/shadow_math_25d_icon.png"))
func _exit_tree():
func _exit_tree() -> void:
if main_panel_instance:
main_panel_instance.queue_free()
# When the plugin node exits the tree, remove the custom types.
@@ -30,11 +30,11 @@ func _exit_tree():
remove_custom_type("Node25D")
func _has_main_screen():
func _has_main_screen() -> bool:
return true
func _make_visible(visible):
func _make_visible(visible: bool) -> void:
if main_panel_instance:
if visible:
main_panel_instance.show()
@@ -42,11 +42,11 @@ func _make_visible(visible):
main_panel_instance.hide()
func _get_plugin_name():
func _get_plugin_name() -> String:
return "2.5D"
func _get_plugin_icon():
func _get_plugin_icon() -> Texture2D:
return preload("res://addons/node25d/icons/viewport_25d.svg")

View File

@@ -85,27 +85,27 @@ func set_spatial_position(value):
# This can be changed or removed in actual games where you only need one view mode.
func set_view_mode(view_mode_index):
match view_mode_index:
0: # 45 Degrees
0: # 45 Degrees
_basisX = SCALE * Vector2(1, 0)
_basisY = SCALE * Vector2(0, -0.70710678118)
_basisZ = SCALE * Vector2(0, 0.70710678118)
1: # Isometric
1: # Isometric
_basisX = SCALE * Vector2(0.86602540378, 0.5)
_basisY = SCALE * Vector2(0, -1)
_basisZ = SCALE * Vector2(-0.86602540378, 0.5)
2: # Top Down
2: # Top Down
_basisX = SCALE * Vector2(1, 0)
_basisY = SCALE * Vector2(0, 0)
_basisZ = SCALE * Vector2(0, 1)
3: # Front Side
3: # Front Side
_basisX = SCALE * Vector2(1, 0)
_basisY = SCALE * Vector2(0, -1)
_basisZ = SCALE * Vector2(0, 0)
4: # Oblique Y
4: # Oblique Y
_basisX = SCALE * Vector2(1, 0)
_basisY = SCALE * Vector2(-0.70710678118, -0.70710678118)
_basisZ = SCALE * Vector2(0, 1)
5: # Oblique Z
5: # Oblique Z
_basisX = SCALE * Vector2(1, 0)
_basisY = SCALE * Vector2(0, -1)
_basisZ = SCALE * Vector2(-0.70710678118, 0.70710678118)

View File

@@ -6,31 +6,34 @@
class_name ShadowMath25D
extends ShapeCast3D
var _shadow_root: Node25D
var _target_math: Node3D
func _ready():
func _ready() -> void:
_shadow_root = get_parent()
var index = _shadow_root.get_index()
if index > 0: # Else, Shadow is not in a valid place.
var index := _shadow_root.get_index()
if index > 0: # Else, shadow is not in a valid place.
var sibling_25d: Node = _shadow_root.get_parent().get_child(index - 1)
if sibling_25d.get_child_count() > 0:
var target = sibling_25d.get_child(0)
if target is Node3D:
_target_math = target
return
printerr("Shadow is not in the correct place, expected a previous sibling node with a 3D first child.")
push_error("Shadow is not in the correct place, expected a previous sibling node with a 3D first child.")
func _physics_process(_delta):
func _physics_process(_delta: float) -> void:
if _target_math == null:
if _shadow_root != null:
_shadow_root.visible = false
return # Shadow is not in a valid place or you're viewing the Shadow25D scene.
return # Shadow is not in a valid place or you're viewing the Shadow25D scene.
position = _target_math.position
force_shapecast_update()
if is_colliding():
global_position = get_collision_point(0)
_shadow_root.visible = true

View File

@@ -4,8 +4,8 @@
# sorting is delayed by one frame.
@tool
@icon("res://addons/node25d/icons/y_sort_25d_icon.png")
extends Node # Note: NOT Node2D, Node25D, or Node2D
class_name YSort25D
class_name Node # Note: NOT Node2D, Node25D, or Node2D
extends YSort25D
# Whether or not to automatically call sort() in _process().

View File

@@ -1,16 +1,17 @@
extends Node3D
@onready var _cube_point_scene: PackedScene = preload("res://assets/cube/cube_point.tscn")
@onready var _parent = get_parent()
var _is_parent_ready := false
var _cube_points_math = []
var _cube_math_spatials = []
var _cube_points_math: Array[Node3D] = []
var _cube_math_spatials: Array[Node3D] = []
func _ready():
@onready var _cube_point_scene: PackedScene = preload("res://assets/cube/cube_point.tscn")
@onready var _parent: Node = get_parent()
func _ready() -> void:
_parent = get_parent()
for i in range(27):
for i in 27:
@warning_ignore("integer_division")
var a: int = (i / 9) - 1
@warning_ignore("integer_division")
@@ -23,7 +24,7 @@ func _ready():
add_child(_cube_math_spatials[i])
func _process(delta):
func _process(delta: float) -> void:
if Input.is_action_pressed(&"exit"):
get_tree().quit()
@@ -38,13 +39,13 @@ func _process(delta):
rotate_x(delta * (Input.get_axis(&"move_forward", &"move_back")))
rotate_y(delta * (Input.get_axis(&"move_left", &"move_right")))
rotate_z(delta * (Input.get_axis(&"move_clockwise", &"move_counterclockwise")))
for i in range(27):
for i in 27:
_cube_points_math[i].global_transform = _cube_math_spatials[i].global_transform
else:
# This code block will be run only once. It's not in _ready() because the parent isn't set up there.
for i in range(27):
var my_cube_point_scene = _cube_point_scene.duplicate(true)
var cube_point = my_cube_point_scene.instantiate()
# This code block will be run only once. It's not in `_ready()` because the parent isn't set up there.
for i in 27:
var my_cube_point_scene := _cube_point_scene.duplicate(true)
var cube_point: Node = my_cube_point_scene.instantiate()
cube_point.name = "CubePoint #" + str(i)
_cube_points_math.append(cube_point.get_child(0))
_parent.add_child(cube_point)

View File

@@ -1,16 +1,12 @@
[gd_scene load_steps=4 format=2]
[gd_scene load_steps=3 format=3 uid="uid://dpm3nweqk8ws0"]
[ext_resource path="res://addons/node25d/node_25d.gd" type="Script" id=1]
[ext_resource path="res://addons/node25d/icons/node_25d_icon.png" type="Texture2D" id=2]
[ext_resource path="res://assets/cube/godot.png" type="Texture2D" id=3]
[ext_resource type="Script" path="res://addons/node25d/node_25d.gd" id="1"]
[ext_resource type="Texture2D" uid="uid://c5d2c7nxf1wbo" path="res://assets/cube/godot.png" id="3"]
[node name="CubePoint" type="Node2D"]
script = ExtResource( 1 )
__meta__ = {
"_editor_icon": ExtResource( 2 )
}
script = ExtResource("1")
[node name="CubePointMath" type="Node3D" parent="."]
[node name="CubePointSprite" type="Sprite2D" parent="."]
texture = ExtResource( 3 )
texture = ExtResource("3")

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=12 format=4 uid="uid://bc8akj25hcmiy"]
[gd_scene load_steps=12 format=3 uid="uid://bc8akj25hcmiy"]
[ext_resource type="PackedScene" uid="uid://6o8sm5bti8d1" path="res://assets/ui/overlay.tscn" id="1"]
[ext_resource type="PackedScene" uid="uid://bg27d8sfehmr4" path="res://assets/player/player_25d.tscn" id="2"]

View File

@@ -1,14 +1,14 @@
@tool
extends Sprite2D
@onready var _forty_five = preload("res://assets/platform/textures/forty_five.png")
@onready var _isometric = preload("res://assets/platform/textures/isometric.png")
@onready var _top_down = preload("res://assets/platform/textures/top_down.png")
@onready var _front_side = preload("res://assets/platform/textures/front_side.png")
@onready var _oblique_y = preload("res://assets/platform/textures/oblique_y.png")
@onready var _oblique_z = preload("res://assets/platform/textures/oblique_z.png")
@onready var _forty_five: Texture2D = preload("res://assets/platform/textures/forty_five.png")
@onready var _isometric: Texture2D = preload("res://assets/platform/textures/isometric.png")
@onready var _top_down: Texture2D = preload("res://assets/platform/textures/top_down.png")
@onready var _front_side: Texture2D = preload("res://assets/platform/textures/front_side.png")
@onready var _oblique_y: Texture2D = preload("res://assets/platform/textures/oblique_y.png")
@onready var _oblique_z: Texture2D = preload("res://assets/platform/textures/oblique_z.png")
func _process(_delta):
func _process(_delta: float) -> void:
if not Engine.is_editor_hint():
if Input.is_action_pressed(&"forty_five_mode"):
set_view_mode(0)
@@ -24,17 +24,17 @@ func _process(_delta):
set_view_mode(5)
func set_view_mode(view_mode_index):
func set_view_mode(view_mode_index: int) -> void:
match view_mode_index:
0: # 45 Degrees
0: # 45 Degrees
texture = _forty_five
1: # Isometric
1: # Isometric
texture = _isometric
2: # Top Down
2: # Top Down
texture = _top_down
3: # Front Side
3: # Front Side
texture = _front_side
4: # Oblique Y
4: # Oblique Y
texture = _oblique_y
5: # Oblique Z
5: # Oblique Z
texture = _oblique_z

View File

@@ -4,9 +4,11 @@ extends CharacterBody3D
var vertical_speed := 0.0
var isometric_controls := true
@onready var _parent_node25d: Node25D = get_parent()
func _physics_process(delta):
func _physics_process(delta: float) -> void:
if Input.is_action_pressed(&"exit"):
get_tree().quit()
@@ -26,17 +28,17 @@ func _physics_process(delta):
# Checks WASD and Shift for horizontal movement via move_and_slide.
func _horizontal_movement(delta):
var localX = Vector3.RIGHT
var localZ = Vector3.BACK
func _horizontal_movement(_delta: float) -> void:
var local_x := Vector3.RIGHT
var local_z := Vector3.BACK
if isometric_controls and is_equal_approx(Node25D.SCALE * 0.86602540378, _parent_node25d.get_basis()[0].x):
localX = Vector3(0.70710678118, 0, -0.70710678118)
localZ = Vector3(0.70710678118, 0, 0.70710678118)
local_x = Vector3(0.70710678118, 0, -0.70710678118)
local_z = Vector3(0.70710678118, 0, 0.70710678118)
# Gather player input and add directional movement to a Vector3 variable.
var movement_vec2 = Input.get_vector(&"move_left", &"move_right", &"move_forward", &"move_back")
var move_dir = localX * movement_vec2.x + localZ * movement_vec2.y
var movement_vec2 := Input.get_vector(&"move_left", &"move_right", &"move_forward", &"move_back")
var move_dir: Vector3 = local_x * movement_vec2.x + local_z * movement_vec2.y
velocity = move_dir * 10
if Input.is_action_pressed(&"movement_modifier"):
@@ -46,10 +48,12 @@ func _horizontal_movement(delta):
# Checks Jump and applies gravity and vertical speed via move_and_collide.
func _vertical_movement(delta):
func _vertical_movement(delta: float) -> void:
if Input.is_action_just_pressed(&"jump"):
vertical_speed = 60
vertical_speed -= delta * 240 # Gravity
var k = move_and_collide(Vector3.UP * vertical_speed * delta)
var k := move_and_collide(Vector3.UP * vertical_speed * delta)
if k != null:
vertical_speed = 0

View File

@@ -1,38 +1,38 @@
@tool
extends Sprite2D
@onready var _stand = preload("res://assets/player/textures/stand.png")
@onready var _jump = preload("res://assets/player/textures/jump.png")
@onready var _run = preload("res://assets/player/textures/run.png")
const FRAMERATE = 15
const ANIMATION_FRAMERATE = 15
var _direction := 0
var _progress := 0.0
var _parent_node25d: Node25D
var _parent_math: PlayerMath25D
func _ready():
@onready var _stand: Texture2D = preload("res://assets/player/textures/stand.png")
@onready var _jump: Texture2D = preload("res://assets/player/textures/jump.png")
@onready var _run: Texture2D = preload("res://assets/player/textures/run.png")
func _ready() -> void:
_parent_node25d = get_parent()
_parent_math = _parent_node25d.get_child(0)
func _process(delta):
func _process(delta: float) -> void:
if Engine.is_editor_hint():
return # Don't run this in the editor.
return # Don't run this in the editor.
_sprite_basis()
var movement = _check_movement() # Always run to get direction, but don't always use return bool.
var movement := _check_movement() # Always run to get direction, but don't always use return bool.
# Test-only move and collide, check if the player is on the ground.
var k = _parent_math.move_and_collide(Vector3.DOWN * 10 * delta, true, true, true)
var k := _parent_math.move_and_collide(Vector3.DOWN * 10 * delta, true, true, true)
if k != null:
if movement:
hframes = 6
texture = _run
if Input.is_action_pressed(&"movement_modifier"):
delta /= 2
_progress = fmod((_progress + FRAMERATE * delta), 6)
_progress = fmod((_progress + ANIMATION_FRAMERATE * delta), 6)
frame = _direction * 6 + int(_progress)
else:
hframes = 1
@@ -43,34 +43,34 @@ func _process(delta):
hframes = 2
texture = _jump
_progress = 0
var jumping = 1 if _parent_math.vertical_speed < 0 else 0
var jumping := 1 if _parent_math.vertical_speed < 0 else 0
frame = _direction * 2 + jumping
func set_view_mode(view_mode_index):
func set_view_mode(view_mode_index: int) -> void:
match view_mode_index:
0: # 45 Degrees
0: # 45 Degrees
transform.x = Vector2(1, 0)
transform.y = Vector2(0, 0.75)
1: # Isometric
1: # Isometric
transform.x = Vector2(1, 0)
transform.y = Vector2(0, 1)
2: # Top Down
2: # Top Down
transform.x = Vector2(1, 0)
transform.y = Vector2(0, 0.5)
3: # Front Side
3: # Front Side
transform.x = Vector2(1, 0)
transform.y = Vector2(0, 1)
4: # Oblique Y
4: # Oblique Y
transform.x = Vector2(1, 0)
transform.y = Vector2(0.75, 0.75)
5: # Oblique Z
5: # Oblique Z
transform.x = Vector2(1, 0.25)
transform.y = Vector2(0, 1)
# Change the 2D basis of the sprite to try and make it "fit" multiple view modes.
func _sprite_basis():
func _sprite_basis() -> void:
if not Engine.is_editor_hint():
if Input.is_action_pressed(&"forty_five_mode"):
set_view_mode(0)
@@ -116,7 +116,7 @@ func _check_movement() -> bool:
# Set the direction based on which inputs were pressed.
if x == 0:
if z == 0:
return false # No movement.
return false # No movement.
elif z > 0:
_direction = 0
else:
@@ -141,4 +141,5 @@ func _check_movement() -> bool:
else:
_direction = 3
flip_h = false
return true # There is movement.
return true # There is movement.

View File

@@ -1,14 +1,15 @@
@tool
extends Sprite2D
@onready var _forty_five = preload("res://assets/shadow/textures/forty_five.png")
@onready var _isometric = preload("res://assets/shadow/textures/isometric.png")
@onready var _top_down = preload("res://assets/shadow/textures/top_down.png")
@onready var _front_side = preload("res://assets/shadow/textures/front_side.png")
@onready var _oblique_y = preload("res://assets/shadow/textures/oblique_y.png")
@onready var _oblique_z = preload("res://assets/shadow/textures/oblique_z.png")
@onready var _forty_five: Texture2D = preload("res://assets/shadow/textures/forty_five.png")
@onready var _isometric: Texture2D = preload("res://assets/shadow/textures/isometric.png")
@onready var _top_down: Texture2D = preload("res://assets/shadow/textures/top_down.png")
@onready var _front_side: Texture2D = preload("res://assets/shadow/textures/front_side.png")
@onready var _oblique_y: Texture2D = preload("res://assets/shadow/textures/oblique_y.png")
@onready var _oblique_z: Texture2D = preload("res://assets/shadow/textures/oblique_z.png")
func _process(_delta):
func _process(_delta: float) -> void:
if not Engine.is_editor_hint():
if Input.is_action_pressed(&"forty_five_mode"):
set_view_mode(0)
@@ -24,17 +25,17 @@ func _process(_delta):
set_view_mode(5)
func set_view_mode(view_mode_index):
func set_view_mode(view_mode_index: int) -> void:
match view_mode_index:
0: # 45 Degrees
0: # 45 Degrees
texture = _forty_five
1: # Isometric
1: # Isometric
texture = _isometric
2: # Top Down
2: # Top Down
texture = _top_down
3: # Front Side
3: # Front Side
texture = _front_side
4: # Oblique Y
4: # Oblique Y
texture = _oblique_y
5: # Oblique Z
5: # Oblique Z
texture = _oblique_z

View File

@@ -1,5 +1,6 @@
extends Control
func _input(event: InputEvent) -> void:
if event.is_action_pressed(&"toggle_control_hints"):
visible = not visible

View File

@@ -19,6 +19,10 @@ run/main_scene="res://assets/demo_scene.tscn"
config/features=PackedStringArray("4.3")
config/icon="res://icon.webp"
[debug]
gdscript/warnings/untyped_declaration=1
[display]
window/size/viewport_width=1600

View File

@@ -1,6 +1,6 @@
extends Control
@export_file("*.glsl") var shader_file
@export_file("*.glsl") var shader_file: String
@export_range(128, 4096, 1, "exp") var dimension: int = 512
@onready var seed_input: SpinBox = $CenterContainer/VBoxContainer/PanelContainer/VBoxContainer/GridContainer/SeedInput
@@ -53,7 +53,7 @@ func _ready() -> void:
$CenterContainer/VBoxContainer/PanelContainer/VBoxContainer/HBoxContainer/CreateButtonCPU.text += "\n" + OS.get_processor_name()
func _notification(what):
func _notification(what: int) -> void:
# Object destructor, triggered before the engine deletes this Node.
if what == NOTIFICATION_PREDELETE:
cleanup_gpu()
@@ -66,13 +66,12 @@ func randomize_seed() -> void:
func prepare_image() -> Image:
start_time = Time.get_ticks_usec()
# Use the to_int() method on the String to convert to a valid seed.
noise.seed = seed_input.value
noise.seed = int(seed_input.value)
# Create image from noise.
var heightmap := noise.get_image(po2_dimensions, po2_dimensions, false, false)
# Create ImageTexture to display original on screen.
var clone = Image.new()
var clone := Image.new()
clone.copy_from(heightmap)
clone.resize(512, 512, Image.INTERPOLATE_NEAREST)
var clone_tex := ImageTexture.create_from_image(clone)
@@ -164,6 +163,7 @@ func compute_island_gpu(heightmap: Image) -> void:
rd.compute_list_bind_uniform_set(compute_list, uniform_set, 0)
# This is where the magic happens! As our shader has a work group size of 8x8x1, we dispatch
# one for every 8x8 block of pixels here. This ratio is highly tunable, and performance may vary.
@warning_ignore("integer_division")
rd.compute_list_dispatch(compute_list, po2_dimensions / 8, po2_dimensions / 8, 1)
rd.compute_list_end()
@@ -207,10 +207,10 @@ func cleanup_gpu() -> void:
# Import, compile and load shader, return reference.
func load_shader(rd: RenderingDevice, path: String) -> RID:
func load_shader(p_rd: RenderingDevice, path: String) -> RID:
var shader_file_data: RDShaderFile = load(path)
var shader_spirv: RDShaderSPIRV = shader_file_data.get_spirv()
return rd.shader_create_from_spirv(shader_spirv)
return p_rd.shader_create_from_spirv(shader_spirv)
func compute_island_cpu(heightmap: Image) -> void:
@@ -251,10 +251,10 @@ func _on_random_button_pressed() -> void:
func _on_create_button_gpu_pressed() -> void:
var heightmap = prepare_image()
var heightmap := prepare_image()
compute_island_gpu.call_deferred(heightmap)
func _on_create_button_cpu_pressed() -> void:
var heightmap = prepare_image()
var heightmap := prepare_image()
compute_island_cpu.call_deferred(heightmap)

View File

@@ -17,6 +17,10 @@ config/features=PackedStringArray("4.2")
run/low_processor_mode=true
config/icon="res://icon.webp"
[debug]
gdscript/warnings/untyped_declaration=1
[display]
window/stretch/mode="canvas_items"

View File

@@ -11,26 +11,26 @@ const DEADZONE = 0.2
const FONT_COLOR_DEFAULT = Color(1.0, 1.0, 1.0, 0.5)
const FONT_COLOR_ACTIVE = Color(0.2, 1.0, 0.2, 1.0)
var joy_num
var cur_joy = -1
var axis_value
var joy_num := 0
var cur_joy := -1
var axis_value := 0.0
@onready var axes = $Axes
@onready var button_grid = $Buttons/ButtonGrid
@onready var joypad_axes = $JoypadDiagram/Axes
@onready var joypad_buttons = $JoypadDiagram/Buttons
@onready var joypad_name = $DeviceInfo/JoyName
@onready var joypad_number = $DeviceInfo/JoyNumber
@onready var axes: VBoxContainer = $Axes
@onready var button_grid: GridContainer = $Buttons/ButtonGrid
@onready var joypad_axes: Node2D = $JoypadDiagram/Axes
@onready var joypad_buttons: Node2D = $JoypadDiagram/Buttons
@onready var joypad_name: RichTextLabel = $DeviceInfo/JoyName
@onready var joypad_number: SpinBox = $DeviceInfo/JoyNumber
func _ready():
func _ready() -> void:
Input.joy_connection_changed.connect(_on_joy_connection_changed)
for joypad in Input.get_connected_joypads():
print_rich("Found joypad #%d: [b]%s[/b] - %s" % [joypad, Input.get_joy_name(joypad), Input.get_joy_guid(joypad)])
func _process(_delta):
func _process(_delta: float) -> void:
# Get the joypad device number from the spinbox.
joy_num = joypad_number.value
joy_num = int(joypad_number.value)
# Display the name of the joypad if we haven't already.
if joy_num != cur_joy:
@@ -47,7 +47,7 @@ func _process(_delta):
axes.get_node("Axis" + str(axis) + "/ProgressBar").set_value(100 * axis_value)
axes.get_node("Axis" + str(axis) + "/ProgressBar/Value").set_text("[center][fade start=2 length=16]%s[/fade][/center]" % axis_value)
# Scaled value used for alpha channel using valid range rather than including unusable deadzone values.
var scaled_alpha_value = (abs(axis_value) - DEADZONE) / (1.0 - DEADZONE)
var scaled_alpha_value: float = (abs(axis_value) - DEADZONE) / (1.0 - DEADZONE)
# Show joypad direction indicators
if axis <= JOY_AXIS_RIGHT_Y:
if abs(axis_value) < DEADZONE:
@@ -89,11 +89,11 @@ func _process(_delta):
# Called whenever a joypad has been connected or disconnected.
func _on_joy_connection_changed(device_id, connected):
func _on_joy_connection_changed(device_id: int, connected: bool) -> void:
if connected:
print_rich("[color=green]Found newly connected joypad #%d: [b]%s[/b] - %s[/color]" % [device_id, Input.get_joy_name(device_id), Input.get_joy_guid(device_id)])
print_rich("[color=green][b]+[/b] Found newly connected joypad #%d: [b]%s[/b] - %s[/color]" % [device_id, Input.get_joy_name(device_id), Input.get_joy_guid(device_id)])
else:
print_rich("[color=red]Disconnected joypad #%d.[/color]" % device_id)
print_rich("[color=red][b]-[/b] Disconnected joypad #%d.[/color]" % device_id)
if device_id == cur_joy:
# Update current joypad label.
@@ -103,48 +103,49 @@ func _on_joy_connection_changed(device_id, connected):
clear_joypad_name()
func _on_start_vibration_pressed():
var weak = $Vibration/Weak/Value.get_value()
var strong = $Vibration/Strong/Value.get_value()
var duration = $Vibration/Duration/Value.get_value()
func _on_start_vibration_pressed() -> void:
var weak: float = $Vibration/Weak/Value.get_value()
var strong: float = $Vibration/Strong/Value.get_value()
var duration: float = $Vibration/Duration/Value.get_value()
Input.start_joy_vibration(cur_joy, weak, strong, duration)
func _on_stop_vibration_pressed():
func _on_stop_vibration_pressed() -> void:
Input.stop_joy_vibration(cur_joy)
func _on_Remap_pressed():
func _on_Remap_pressed() -> void:
$RemapWizard.start(cur_joy)
func _on_Clear_pressed():
var guid = Input.get_joy_guid(cur_joy)
func _on_Clear_pressed() -> void:
var guid := Input.get_joy_guid(cur_joy)
if guid.is_empty():
push_error("No gamepad selected.")
return
Input.remove_joy_mapping(guid)
func _on_Show_pressed():
func _on_Show_pressed() -> void:
$RemapWizard.show_map()
func _on_joy_name_meta_clicked(meta):
OS.shell_open(meta)
func _on_joy_name_meta_clicked(meta: Variant) -> void:
OS.shell_open(str(meta))
func set_joypad_name(joy_name, joy_guid):
func set_joypad_name(joy_name: String, joy_guid: String) -> void:
# Make the GUID clickable (and point to Godot's game controller database for easier lookup).
joypad_name.set_text("%s\n[color=#fff9][url=https://github.com/godotengine/godot/blob/master/core/input/gamecontrollerdb.txt]%s[/url][/color]" % [joy_name, joy_guid])
# Make the rest of the UI appear as enabled.
for node in [$JoypadDiagram, $Axes, $Buttons, $Vibration, $VBoxContainer]:
for node: CanvasItem in [$JoypadDiagram, $Axes, $Buttons, $Vibration, $VBoxContainer]:
node.modulate.a = 1.0
func clear_joypad_name():
func clear_joypad_name() -> void:
joypad_name.set_text("[i]No controller detected at ID %d.[/i]" % joypad_number.value)
# Make the rest of the UI appear as disabled.
for node in [$JoypadDiagram, $Axes, $Buttons, $Vibration, $VBoxContainer]:
for node: CanvasItem in [$JoypadDiagram, $Axes, $Buttons, $Vibration, $VBoxContainer]:
node.modulate.a = 0.5

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/size/viewport_width=600

View File

@@ -1,9 +1,17 @@
extends RefCounted
class_name JoyMapping
class_name RefCounted
extends JoyMapping
enum Type {
NONE,
BTN,
AXIS,
}
enum TYPE {NONE, BTN, AXIS}
enum AXIS {FULL, HALF_PLUS, HALF_MINUS}
enum Axis {
FULL,
HALF_PLUS,
HALF_MINUS,
}
const PLATFORMS = {
# From gamecontrollerdb
@@ -96,42 +104,46 @@ const XBOX_OSX = {
"righttrigger":"a5",
}
var type = TYPE.NONE
var idx = -1
var axis = AXIS.FULL
var inverted = false
var type := Type.NONE
var idx := -1
var axis := Axis.FULL
var inverted := false
func _init(p_type = TYPE.NONE, p_idx = -1, p_axis = AXIS.FULL):
func _init(p_type: Type = Type.NONE, p_idx: int = -1, p_axis: Axis = Axis.FULL) -> void:
type = p_type
idx = p_idx
axis = p_axis
func _to_string():
if type == TYPE.NONE:
func _to_string() -> String:
if type == Type.NONE:
return ""
var ts = "b" if type == TYPE.BTN else "a"
var prefix = ""
var suffix = "~" if inverted else ""
var ts := "b" if type == Type.BTN else "a"
var prefix := ""
var suffix := "~" if inverted else ""
match axis:
AXIS.HALF_PLUS:
Axis.HALF_PLUS:
prefix = "+"
AXIS.HALF_MINUS:
Axis.HALF_MINUS:
prefix = "-"
return "%s%s%d%s" % [prefix, ts, idx, suffix]
func to_human_string():
if type == TYPE.BTN:
func to_human_string() -> String:
if type == Type.BTN:
return "Button %d" % idx
if type == TYPE.AXIS:
var prefix = ""
if type == Type.AXIS:
var prefix := ""
match axis:
AXIS.HALF_PLUS:
Axis.HALF_PLUS:
prefix = "(+) "
AXIS.HALF_MINUS:
Axis.HALF_MINUS:
prefix = "(-) "
var suffix = " (inverted)" if inverted else ""
var suffix := " (inverted)" if inverted else ""
return "Axis %s%d%s" % [prefix, idx, suffix]
return ""

View File

@@ -1,6 +1,5 @@
extends Node
const DEADZONE = 0.3
var joy_index: int = -1
@@ -12,69 +11,74 @@ var cur_step: int = -1
var cur_mapping: Dictionary = {}
var last_mapping: String = ""
@onready var joy_buttons = $Mapping/Margin/VBox/SubViewportContainer/SubViewport/JoypadDiagram/Buttons
@onready var joy_axes = $Mapping/Margin/VBox/SubViewportContainer/SubViewport/JoypadDiagram/Axes
@onready var joy_mapping_text = $Mapping/Margin/VBox/Info/Text/Value
@onready var joy_mapping_full_axis = $Mapping/Margin/VBox/Info/Extra/FullAxis
@onready var joy_mapping_axis_invert = $Mapping/Margin/VBox/Info/Extra/InvertAxis
@onready var joy_buttons: Node2D = $Mapping/Margin/VBox/SubViewportContainer/SubViewport/JoypadDiagram/Buttons
@onready var joy_axes: Node2D = $Mapping/Margin/VBox/SubViewportContainer/SubViewport/JoypadDiagram/Axes
@onready var joy_mapping_text: Label = $Mapping/Margin/VBox/Info/Text/Value
@onready var joy_mapping_full_axis: CheckBox = $Mapping/Margin/VBox/Info/Extra/FullAxis
@onready var joy_mapping_axis_invert: CheckBox = $Mapping/Margin/VBox/Info/Extra/InvertAxis
# Connected to Mapping.window_input, otherwise no gamepad events
# will be received when the subwindow is focused.
func _input(event):
func _input(event: InputEvent) -> void:
if cur_step == -1:
return
# Ignore events not related to gamepads.
if not (event is InputEventJoypadButton or event is InputEventJoypadMotion):
return
# Ignore devices other than the one being remapped. Handles accidental input and analog drift.
if event.device != joy_index:
return
if event is InputEventJoypadMotion:
get_viewport().set_input_as_handled()
var motion = event as InputEventJoypadMotion
var motion := event as InputEventJoypadMotion
if abs(motion.axis_value) > DEADZONE:
var idx = motion.axis
var map = JoyMapping.new(JoyMapping.TYPE.AXIS, idx)
var idx := motion.axis
var map := JoyMapping.new(JoyMapping.Type.AXIS, idx)
map.inverted = joy_mapping_axis_invert.button_pressed
if joy_mapping_full_axis.button_pressed:
map.axis = JoyMapping.AXIS.FULL
map.axis = JoyMapping.Axis.FULL
elif motion.axis_value > 0:
map.axis = JoyMapping.AXIS.HALF_PLUS
map.axis = JoyMapping.Axis.HALF_PLUS
else:
map.axis = JoyMapping.AXIS.HALF_MINUS
map.axis = JoyMapping.Axis.HALF_MINUS
joy_mapping_text.text = map.to_human_string()
cur_mapping[steps[cur_step]] = map
elif event is InputEventJoypadButton and event.pressed:
get_viewport().set_input_as_handled()
var btn = event as InputEventJoypadButton
var map = JoyMapping.new(JoyMapping.TYPE.BTN, btn.button_index)
var btn := event as InputEventJoypadButton
var map := JoyMapping.new(JoyMapping.Type.BTN, btn.button_index)
joy_mapping_text.text = map.to_human_string()
cur_mapping[steps[cur_step]] = map
func create_mapping_string(mapping: Dictionary) -> String:
var string = "%s,%s," % [joy_guid, joy_name]
for k in mapping:
var m = mapping[k]
if typeof(m) == TYPE_OBJECT and m.type == JoyMapping.TYPE.NONE:
var string := "%s,%s," % [joy_guid, joy_name]
for k: String in mapping:
var m: Variant = mapping[k]
if typeof(m) == TYPE_OBJECT and m.type == JoyMapping.Type.NONE:
continue
string += "%s:%s," % [k, str(m)]
var platform = "Unknown"
var platform := "Unknown"
if JoyMapping.PLATFORMS.keys().has(OS.get_name()):
platform = JoyMapping.PLATFORMS[OS.get_name()]
return string + "platform:" + platform
func start(idx: int):
func start(idx: int) -> void:
joy_index = idx
joy_guid = Input.get_joy_guid(idx)
joy_name = Input.get_joy_name(idx)
if joy_guid.is_empty():
printerr("Unable to find controller")
push_error("Unable to find controller")
return
if OS.get_name() == "HTML5":
# Propose trying known mapping on HTML5.
if OS.has_feature("web"):
# Propose trying known mapping on Web.
$Start.window_title = "%s - %s" % [joy_guid, joy_name]
$Start.popup_centered()
else:
@@ -89,7 +93,7 @@ func remap_and_close(mapping: Dictionary) -> void:
show_map()
func reset():
func reset() -> void:
$Start.hide()
$Mapping.hide()
joy_guid = ""
@@ -98,7 +102,7 @@ func reset():
cur_step = -1
func step_next():
func step_next() -> void:
$Mapping.title = "Step: %d/%d" % [cur_step + 1, steps.size()]
joy_mapping_text.text = ""
if cur_step >= steps.size():
@@ -107,22 +111,22 @@ func step_next():
_update_step()
func show_map():
if OS.get_name() == "Web":
func show_map() -> void:
if OS.has_feature("web"):
JavaScriptBridge.eval("window.prompt('This is the resulting remap string', '%s')" % last_mapping)
else:
$MapWindow/Margin/VBoxContainer/TextEdit.text = last_mapping
$MapWindow.popup_centered()
func _update_step():
func _update_step() -> void:
$Mapping/Margin/VBox/Info/Buttons/Next.grab_focus()
for btn in joy_buttons.get_children():
btn.hide()
for axis in joy_axes.get_children():
axis.hide()
var key = steps[cur_step]
var idx = JoyMapping.BASE[key]
var key: String = steps[cur_step]
var idx: int = JoyMapping.BASE[key]
if key in ["leftx", "lefty", "rightx", "righty"]:
joy_axes.get_node(str(idx) + "+").show()
joy_axes.get_node(str(idx) + "-").show()
@@ -134,14 +138,14 @@ func _update_step():
joy_mapping_full_axis.button_pressed = key in ["leftx", "lefty", "rightx", "righty", "righttrigger", "lefttrigger"]
joy_mapping_axis_invert.button_pressed = false
if cur_mapping.has(key):
var cur = cur_mapping[steps[cur_step]]
var cur: JoyMapping = cur_mapping[steps[cur_step]]
joy_mapping_text.text = cur.to_human_string()
if cur.type == JoyMapping.TYPE.AXIS:
joy_mapping_full_axis.button_pressed = cur.axis == JoyMapping.AXIS.FULL
if cur.type == JoyMapping.Type.AXIS:
joy_mapping_full_axis.button_pressed = cur.axis == JoyMapping.Axis.FULL
joy_mapping_axis_invert.button_pressed = cur.inverted
func _on_Wizard_pressed():
func _on_Wizard_pressed() -> void:
Input.remove_joy_mapping(joy_guid)
$Start.hide()
$Mapping.popup_centered()
@@ -149,66 +153,69 @@ func _on_Wizard_pressed():
step_next()
func _on_Cancel_pressed():
func _on_Cancel_pressed() -> void:
reset()
func _on_xbox_pressed():
func _on_xbox_pressed() -> void:
remap_and_close(JoyMapping.XBOX)
func _on_xboxosx_pressed():
func _on_xboxosx_pressed() -> void:
remap_and_close(JoyMapping.XBOX_OSX)
func _on_Mapping_popup_hide():
func _on_Mapping_popup_hide() -> void:
reset()
func _on_Next_pressed():
func _on_Next_pressed() -> void:
cur_step += 1
step_next()
func _on_Prev_pressed():
func _on_Prev_pressed() -> void:
if cur_step > 0:
cur_step -= 1
step_next()
func _on_Skip_pressed():
var key = steps[cur_step]
func _on_Skip_pressed() -> void:
var key: String = steps[cur_step]
if cur_mapping.has(key):
cur_mapping.erase(key)
cur_step += 1
step_next()
func _on_FullAxis_toggled(button_pressed):
func _on_FullAxis_toggled(button_pressed: bool) -> void:
if cur_step == -1 or not button_pressed:
return
var key = steps[cur_step]
if cur_mapping.has(key) and cur_mapping[key].type == JoyMapping.TYPE.AXIS:
cur_mapping[key].axis = JoyMapping.AXIS.FULL
var key: String = steps[cur_step]
if cur_mapping.has(key) and cur_mapping[key].type == JoyMapping.Type.AXIS:
cur_mapping[key].axis = JoyMapping.Axis.FULL
joy_mapping_text.text = cur_mapping[key].to_human_string()
func _on_InvertAxis_toggled(button_pressed):
func _on_InvertAxis_toggled(button_pressed: bool) -> void:
if cur_step == -1:
return
var key = steps[cur_step]
if cur_mapping.has(key) and cur_mapping[key].type == JoyMapping.TYPE.AXIS:
var key: String = steps[cur_step]
if cur_mapping.has(key) and cur_mapping[key].type == JoyMapping.Type.AXIS:
cur_mapping[key].inverted = button_pressed
joy_mapping_text.text = cur_mapping[key].to_human_string()
func _on_start_close_requested():
func _on_start_close_requested() -> void:
$Start.hide()
func _on_mapping_close_requested():
func _on_mapping_close_requested() -> void:
$Mapping.hide()
func _on_map_window_close_requested():
func _on_map_window_close_requested() -> void:
$MapWindow.hide()

View File

@@ -21,75 +21,44 @@ grow_vertical = 2
[node name="Layout" type="VBoxContainer" parent="Start/Margin"]
layout_mode = 2
offset_right = 600.0
offset_bottom = 540.0
alignment = 1
[node name="HTML5" type="VBoxContainer" parent="Start/Margin/Layout"]
layout_mode = 2
offset_top = 207.0
offset_right = 600.0
offset_bottom = 268.0
[node name="Label" type="Label" parent="Start/Margin/Layout/HTML5"]
layout_mode = 2
offset_right = 600.0
offset_bottom = 26.0
text = "Try a common mapping:"
[node name="known" type="HBoxContainer" parent="Start/Margin/Layout/HTML5"]
layout_mode = 2
offset_top = 30.0
offset_right = 600.0
offset_bottom = 61.0
alignment = 1
[node name="Xbox" type="Button" parent="Start/Margin/Layout/HTML5/known"]
layout_mode = 2
offset_left = 228.0
offset_right = 275.0
offset_bottom = 31.0
text = "Xbox"
[node name="XboxOSX" type="Button" parent="Start/Margin/Layout/HTML5/known"]
layout_mode = 2
offset_left = 279.0
offset_right = 372.0
offset_bottom = 31.0
text = "Xbox (OSX)"
[node name="Label" type="Label" parent="Start/Margin/Layout"]
layout_mode = 2
offset_top = 272.0
offset_right = 600.0
offset_bottom = 298.0
text = "Or start the wizard"
[node name="Buttons" type="HBoxContainer" parent="Start/Margin/Layout"]
layout_mode = 2
offset_top = 302.0
offset_right = 600.0
offset_bottom = 333.0
[node name="Cancel" type="Button" parent="Start/Margin/Layout/Buttons"]
layout_mode = 2
offset_right = 60.0
offset_bottom = 31.0
text = "Cancel"
[node name="Control" type="Control" parent="Start/Margin/Layout/Buttons"]
layout_mode = 2
anchors_preset = 0
offset_left = 64.0
offset_right = 534.0
offset_bottom = 31.0
size_flags_horizontal = 3
[node name="Wizard" type="Button" parent="Start/Margin/Layout/Buttons"]
layout_mode = 2
offset_left = 538.0
offset_right = 600.0
offset_bottom = 31.0
text = "Wizard"
[node name="Mapping" type="Window" parent="."]
@@ -111,13 +80,10 @@ theme_override_constants/margin_bottom = 30
[node name="VBox" type="VBoxContainer" parent="Mapping/Margin"]
layout_mode = 2
offset_right = 600.0
offset_bottom = 540.0
[node name="SubViewportContainer" type="SubViewportContainer" parent="Mapping/Margin/VBox"]
custom_minimum_size = Vector2(0, 260)
layout_mode = 2
offset_right = 600.0
stretch = true
[node name="SubViewport" type="SubViewport" parent="Mapping/Margin/VBox/SubViewportContainer"]
@@ -129,91 +95,52 @@ render_target_update_mode = 0
position = Vector2(0, 0)
[node name="Camera2D" type="Camera2D" parent="Mapping/Margin/VBox/SubViewportContainer/SubViewport"]
current = true
[node name="Info" type="VBoxContainer" parent="Mapping/Margin/VBox"]
layout_mode = 2
offset_top = 4.0
offset_right = 600.0
offset_bottom = 100.0
[node name="Text" type="HBoxContainer" parent="Mapping/Margin/VBox/Info"]
layout_mode = 2
offset_right = 600.0
offset_bottom = 26.0
[node name="Text" type="Label" parent="Mapping/Margin/VBox/Info/Text"]
layout_mode = 2
offset_right = 150.0
offset_bottom = 26.0
text = "Currently selected: "
[node name="Value" type="Label" parent="Mapping/Margin/VBox/Info/Text"]
layout_mode = 2
offset_left = 154.0
offset_top = 1.0
offset_right = 155.0
offset_bottom = 24.0
[node name="Extra" type="HBoxContainer" parent="Mapping/Margin/VBox/Info"]
layout_mode = 2
offset_top = 30.0
offset_right = 600.0
offset_bottom = 61.0
[node name="FullAxis" type="CheckBox" parent="Mapping/Margin/VBox/Info/Extra"]
layout_mode = 2
offset_right = 91.0
offset_bottom = 31.0
text = "Full axis"
[node name="InvertAxis" type="CheckBox" parent="Mapping/Margin/VBox/Info/Extra"]
layout_mode = 2
offset_left = 95.0
offset_right = 205.0
offset_bottom = 31.0
text = "Invert Axis"
[node name="Buttons" type="HBoxContainer" parent="Mapping/Margin/VBox/Info"]
layout_mode = 2
offset_top = 65.0
offset_right = 600.0
offset_bottom = 96.0
[node name="Prev" type="Button" parent="Mapping/Margin/VBox/Info/Buttons"]
layout_mode = 2
offset_right = 75.0
offset_bottom = 31.0
text = "Previous"
[node name="Control" type="Control" parent="Mapping/Margin/VBox/Info/Buttons"]
layout_mode = 2
anchors_preset = 0
offset_left = 79.0
offset_right = 290.0
offset_bottom = 31.0
size_flags_horizontal = 3
[node name="Skip" type="Button" parent="Mapping/Margin/VBox/Info/Buttons"]
layout_mode = 2
offset_left = 294.0
offset_right = 335.0
offset_bottom = 31.0
text = "Skip"
[node name="Control2" type="Control" parent="Mapping/Margin/VBox/Info/Buttons"]
layout_mode = 2
anchors_preset = 0
offset_left = 339.0
offset_right = 551.0
offset_bottom = 31.0
size_flags_horizontal = 3
[node name="Next" type="Button" parent="Mapping/Margin/VBox/Info/Buttons"]
layout_mode = 2
offset_left = 555.0
offset_right = 600.0
offset_bottom = 31.0
text = "Next"
[node name="MapWindow" type="Window" parent="."]
@@ -231,20 +158,13 @@ grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="MapWindow/Margin"]
layout_mode = 2
offset_right = 600.0
offset_bottom = 540.0
[node name="Label" type="Label" parent="MapWindow/Margin/VBoxContainer"]
layout_mode = 2
offset_right = 600.0
offset_bottom = 26.0
text = "This is the resulting remap string:"
[node name="TextEdit" type="TextEdit" parent="MapWindow/Margin/VBoxContainer"]
layout_mode = 2
offset_top = 30.0
offset_right = 600.0
offset_bottom = 540.0
size_flags_vertical = 3
[connection signal="close_requested" from="Start" to="." method="_on_start_close_requested"]

View File

@@ -21,6 +21,7 @@ func _ready() -> void:
%HelpLabel.text = "Double precision is enabled in this engine build.\nNo shaking should occur at high coordinate levels\n(±65,536 or more on any axis)."
%HelpLabel.add_theme_color_override("font_color", Color(0.667, 1, 0.667))
func _process(delta: float) -> void:
%Coordinates.text = "X: [color=#fb9]%f[/color]\nY: [color=#bfa]%f[/color]\nZ: [color=#9cf]%f[/color]" % [node_to_move.position.x, node_to_move.position.y, node_to_move.position.z]
if %IncrementX.button_pressed:

View File

@@ -19,6 +19,10 @@ config/features=PackedStringArray("4.2")
run/low_processor_mode=true
config/icon="res://icon.webp"
[debug]
gdscript/warnings/untyped_declaration=1
[display]
window/stretch/mode="canvas_items"

View File

@@ -76,11 +76,11 @@ albedo_color = Color(0.0666667, 0.313726, 0.768627, 1)
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_r08do"]
emission_shape = 3
emission_box_extents = Vector3(8, 0, 8)
sub_emitter_mode = 3
sub_emitter_amount_at_collision = 1
collision_mode = 1
collision_friction = 0.0
collision_bounce = 0.2
sub_emitter_mode = 3
sub_emitter_amount_at_collision = 1
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_jmbue"]
shading_mode = 0
@@ -89,8 +89,8 @@ shading_mode = 0
material = SubResource("StandardMaterial3D_jmbue")
radius = 0.05
height = 0.1
radial_segments = 4
rings = 1
radial_segments = 8
rings = 4
[sub_resource type="Animation" id="Animation_c3rry"]
length = 0.001
@@ -249,7 +249,7 @@ local_coords = true
process_material = SubResource("ParticleProcessMaterial_r08do")
draw_pass_1 = SubResource("SphereMesh_f1qcl")
[node name="Controls" type="VBoxContainer" parent="." node_paths=PackedStringArray("camera", "camera_holder", "rotation_x", "node_to_move", "rigid_body")]
[node name="Controls" type="VBoxContainer" parent="." node_paths=PackedStringArray("camera", "camera_holder", "rotation_x", "node_to_move")]
offset_left = 16.0
offset_top = 16.0
offset_right = 350.0
@@ -260,7 +260,6 @@ camera = NodePath("../Move/CameraHolder/RotationX/Camera3D")
camera_holder = NodePath("../Move/CameraHolder")
rotation_x = NodePath("../Move/CameraHolder/RotationX")
node_to_move = NodePath("../Move")
rigid_body = NodePath("")
[node name="HelpLabel" type="Label" parent="Controls"]
unique_name_in_owner = true
@@ -362,10 +361,10 @@ layout_mode = 2
text = "10,000,000,000,000"
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
autoplay = "move_text_around"
libraries = {
"": SubResource("AnimationLibrary_2gye4")
}
autoplay = "move_text_around"
[connection signal="pressed" from="Controls/Button" to="Controls" method="_on_open_documentation_pressed"]
[connection signal="pressed" from="Controls/HFlowContainer/Button" to="Controls" method="_on_go_to_button_pressed" binds= [0]]

View File

@@ -4,9 +4,9 @@ class_name AxisMarker2D
extends Node2D
func _process(_delta):
func _process(_delta: float) -> void:
var line: Line2D = get_child(0).get_child(0)
var marker_parent = get_parent()
var marker_parent: Node = get_parent()
line.points[1] = transform.origin
if marker_parent as Node2D != null:

View File

@@ -4,7 +4,7 @@ class_name AxisMarker3D
extends Node3D
func _process(_delta):
func _process(_delta: float) -> void:
var holder: Node3D = get_child(0).get_child(0)
var cube: Node3D = holder.get_child(0)
# "Hide" the origin vector if the AxisMarker is at (0, 0, 0)

View File

@@ -21,6 +21,10 @@ run/main_scene="res://3D.tscn"
config/features=PackedStringArray("4.2")
config/icon="res://icon.webp"
[debug]
gdscript/warnings/untyped_declaration=1
[rendering]
renderer/rendering_method="gl_compatibility"

View File

@@ -4,12 +4,10 @@ extends Control
@onready var noise: FastNoiseLite = $SeamlessNoiseTexture.texture.noise
# Various noise parameters.
var min_noise = -1
var max_noise = 1
var min_noise := -1.0
var max_noise := 1.0
# Called when the node enters the scene tree for the first time.
func _ready():
func _ready() -> void:
# Set up noise with basic info.
$ParameterContainer/SeedSpinBox.value = noise.seed
$ParameterContainer/FrequencySpinBox.value = noise.frequency
@@ -21,48 +19,50 @@ func _ready():
_refresh_shader_params()
func _refresh_shader_params():
func _refresh_shader_params() -> void:
# Adjust min/max for shader.
var _min = (min_noise + 1) / 2
var _max = (max_noise + 1) / 2
var _material = $SeamlessNoiseTexture.material
@warning_ignore("integer_division")
var _min := (min_noise + 1) / 2
@warning_ignore("integer_division")
var _max := (max_noise + 1) / 2
var _material: ShaderMaterial = $SeamlessNoiseTexture.material
_material.set_shader_parameter("min_value", _min)
_material.set_shader_parameter("max_value", _max)
func _on_documentation_button_pressed():
func _on_documentation_button_pressed() -> void:
OS.shell_open("https://docs.godotengine.org/en/latest/classes/class_fastnoiselite.html")
func _on_random_seed_button_pressed():
func _on_random_seed_button_pressed() -> void:
$ParameterContainer/SeedSpinBox.value = floor(randf_range(-2147483648, 2147483648))
func _on_seed_spin_box_value_changed(value):
noise.seed = value
func _on_seed_spin_box_value_changed(value: float) -> void:
noise.seed = int(value)
func _on_frequency_spin_box_value_changed(value):
func _on_frequency_spin_box_value_changed(value: float) -> void:
noise.frequency = value
func _on_fractal_octaves_spin_box_value_changed(value):
noise.fractal_octaves = value
func _on_fractal_octaves_spin_box_value_changed(value: float) -> void:
noise.fractal_octaves = int(value)
func _on_fractal_gain_spin_box_value_changed(value):
func _on_fractal_gain_spin_box_value_changed(value: float) -> void:
noise.fractal_gain = value
func _on_fractal_lacunarity_spin_box_value_changed(value):
func _on_fractal_lacunarity_spin_box_value_changed(value: float) -> void:
noise.fractal_lacunarity = value
func _on_min_clip_spin_box_value_changed(value):
func _on_min_clip_spin_box_value_changed(value: float) -> void:
min_noise = value
_refresh_shader_params()
func _on_max_clip_spin_box_value_changed(value):
func _on_max_clip_spin_box_value_changed(value: float) -> void:
max_noise = value
_refresh_shader_params()

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/stretch/mode="canvas_items"

View File

@@ -1,12 +1,11 @@
extends Node
func _on_OpenShellWeb_pressed():
func _on_open_shell_web_pressed() -> void:
OS.shell_open("https://example.com")
func _on_OpenShellFolder_pressed():
var path = OS.get_environment("HOME")
func _on_open_shell_folder_pressed() -> void:
var path := OS.get_environment("HOME")
if path == "":
# Windows-specific.
path = OS.get_environment("USERPROFILE")
@@ -18,17 +17,21 @@ func _on_OpenShellFolder_pressed():
OS.shell_open(path)
func _on_ChangeWindowTitle_pressed():
func _on_change_window_title_pressed() -> void:
DisplayServer.window_set_title("Modified window title. Unicode characters for testing: é € × Ù ¨")
func _on_ChangeWindowIcon_pressed():
var image = Image.create(128, 128, false, Image.FORMAT_RGB8)
func _on_change_window_icon_pressed() -> void:
if not DisplayServer.has_feature(DisplayServer.FEATURE_ICON):
OS.alert("Changing the window icon is not supported by the current display server (%s)." % DisplayServer.get_name())
return
var image := Image.create(128, 128, false, Image.FORMAT_RGB8)
image.fill(Color(1, 0.6, 0.3))
DisplayServer.set_icon(image)
func _on_MoveWindowToForeground_pressed():
func _on_move_window_to_foreground_pressed() -> void:
DisplayServer.window_set_title("Will move window to foreground in 5 seconds, try unfocusing the window...")
await get_tree().create_timer(5).timeout
DisplayServer.window_move_to_foreground()
@@ -36,7 +39,7 @@ func _on_MoveWindowToForeground_pressed():
DisplayServer.window_set_title(ProjectSettings.get_setting("application/config/name"))
func _on_RequestAttention_pressed():
func _on_request_attention_pressed() -> void:
DisplayServer.window_set_title("Will request attention in 5 seconds, try unfocusing the window...")
await get_tree().create_timer(5).timeout
DisplayServer.window_request_attention()
@@ -44,36 +47,44 @@ func _on_RequestAttention_pressed():
DisplayServer.window_set_title(ProjectSettings.get_setting("application/config/name"))
func _on_VibrateDeviceShort_pressed():
func _on_vibrate_device_short_pressed() -> void:
Input.vibrate_handheld(200)
func _on_VibrateDeviceLong_pressed():
func _on_vibrate_device_long_pressed() -> void:
Input.vibrate_handheld(1000)
func _on_AddGlobalMenuItems_pressed():
func _on_add_global_menu_items_pressed() -> void:
if not DisplayServer.has_feature(DisplayServer.FEATURE_GLOBAL_MENU):
OS.alert("Global menus are not supported by the current display server (%s)." % DisplayServer.get_name())
return
# Add a menu to the main menu bar.
DisplayServer.global_menu_add_submenu_item("_main", "Hello", "_main/Hello")
DisplayServer.global_menu_add_item(
"_main/Hello",
"World",
func(tag): print("Clicked main 1 " + str(tag)),
func(tag): print("Key main 1 " + str(tag)),
func(tag: String) -> void: print("Clicked main 1 " + str(tag)),
func(tag: String) -> void: print("Key main 1 " + str(tag)),
null,
(KEY_MASK_META | KEY_1) as Key
)
DisplayServer.global_menu_add_separator("_main/Hello")
DisplayServer.global_menu_add_item("_main/Hello", "World2", func(tag): print("Clicked main 2 " + str(tag)))
DisplayServer.global_menu_add_item("_main/Hello", "World2", func(tag: String) -> void: print("Clicked main 2 " + str(tag)))
# Add a menu to the Dock context menu.
DisplayServer.global_menu_add_submenu_item("_dock", "Hello", "_dock/Hello")
DisplayServer.global_menu_add_item("_dock/Hello", "World", func(tag): print("Clicked dock 1 " + str(tag)))
DisplayServer.global_menu_add_item("_dock/Hello", "World", func(tag: String) -> void: print("Clicked dock 1 " + str(tag)))
DisplayServer.global_menu_add_separator("_dock/Hello")
DisplayServer.global_menu_add_item("_dock/Hello", "World2", func(tag): print("Clicked dock 2 " + str(tag)))
DisplayServer.global_menu_add_item("_dock/Hello", "World2", func(tag: String) -> void: print("Clicked dock 2 " + str(tag)))
func _on_RemoveGlobalMenuItem_pressed():
func _on_remove_global_menu_item_pressed() -> void:
if not DisplayServer.has_feature(DisplayServer.FEATURE_GLOBAL_MENU):
OS.alert("Global menus are not supported by the current display server (%s)." % DisplayServer.get_name())
return
DisplayServer.global_menu_remove_item("_main/Hello", 2)
DisplayServer.global_menu_remove_item("_main/Hello", 1)
DisplayServer.global_menu_remove_item("_main/Hello", 0)
@@ -85,17 +96,25 @@ func _on_RemoveGlobalMenuItem_pressed():
DisplayServer.global_menu_remove_item("_dock", 0)
func _on_GetClipboard_pressed():
func _on_get_clipboard_pressed() -> void:
if not DisplayServer.has_feature(DisplayServer.FEATURE_CLIPBOARD):
OS.alert("Clipboard I/O is not supported by the current display server (%s)." % DisplayServer.get_name())
return
OS.alert("Clipboard contents:\n\n%s" % DisplayServer.clipboard_get())
func _on_SetClipboard_pressed():
func _on_set_clipboard_pressed() -> void:
if not DisplayServer.has_feature(DisplayServer.FEATURE_CLIPBOARD):
OS.alert("Clipboard I/O is not supported by the current display server (%s)." % DisplayServer.get_name())
return
DisplayServer.clipboard_set("Modified clipboard contents. Unicode characters for testing: é € × Ù ¨")
func _on_DisplayAlert_pressed():
func _on_display_alert_pressed() -> void:
OS.alert("Hello from Godot! Close this dialog to resume the main window.")
func _on_KillCurrentProcess_pressed():
func _on_kill_current_process_pressed() -> void:
OS.kill(OS.get_process_id())

View File

@@ -1,11 +1,10 @@
extends Node
@onready var rtl = $HBoxContainer/Features
@onready var csharp_test = $CSharpTest
@onready var rtl: RichTextLabel = $HBoxContainer/Features
@onready var csharp_test: Node = $CSharpTest
# Returns a human-readable string from a date and time, date, or time dictionary.
func datetime_to_string(date):
func datetime_to_string(date: Dictionary) -> void:
if (
date.has("year")
and date.has("month")
@@ -39,27 +38,34 @@ func datetime_to_string(date):
})
func scan_midi_devices():
func scan_midi_devices() -> String:
OS.open_midi_inputs()
var devices = ", ".join(OS.get_connected_midi_inputs())
var devices := ", ".join(OS.get_connected_midi_inputs())
OS.close_midi_inputs()
return devices
func add_header(header):
func add_header(header: String) -> void:
rtl.append_text("\n[font_size=24][color=#6df]{header}[/color][/font_size]\n\n".format({
header = header,
}))
func add_line(key, value):
func add_line(key: String, value: Variant) -> void:
if typeof(value) == TYPE_BOOL:
# Colorize boolean values.
value = "[color=8f8]true[/color]" if value else "[color=#f88]false[/color]"
rtl.append_text("[color=#adf]{key}:[/color] {value}\n".format({
key = key,
value = value if str(value) != "" else "[color=#fff8](empty)[/color]",
}))
func _ready():
func _ready() -> void:
# Grab focus so that the list can be scrolled (for keyboard/controller-friendly navigation).
rtl.grab_focus()
add_header("Audio")
add_line("Mix rate", "%d Hz" % AudioServer.get_mix_rate())
add_line("Output latency", "%f ms" % (AudioServer.get_output_latency() * 1000))
@@ -115,7 +121,7 @@ func _ready():
add_header("Input")
add_line("Device has touch screen", DisplayServer.is_touchscreen_available())
var has_virtual_keyboard = DisplayServer.has_feature(DisplayServer.FEATURE_VIRTUAL_KEYBOARD)
var has_virtual_keyboard := DisplayServer.has_feature(DisplayServer.FEATURE_VIRTUAL_KEYBOARD)
add_line("Device has virtual keyboard", has_virtual_keyboard)
if has_virtual_keyboard:
add_line("Virtual keyboard height", DisplayServer.virtual_keyboard_get_height())
@@ -127,7 +133,7 @@ func _ready():
add_line("Granted permissions", OS.get_granted_permissions())
add_header(".NET (C#)")
var csharp_enabled = ResourceLoader.exists("res://CSharpTest.cs")
var csharp_enabled := ResourceLoader.exists("res://CSharpTest.cs")
add_line("Mono module enabled", "Yes" if csharp_enabled else "No")
if csharp_enabled:
csharp_test.set_script(load("res://CSharpTest.cs"))
@@ -163,7 +169,7 @@ func _ready():
][RenderingServer.get_video_adapter_type()])
add_line("Adapter graphics API version", RenderingServer.get_video_adapter_api_version())
var video_adapter_driver_info = OS.get_video_adapter_driver_info()
var video_adapter_driver_info := OS.get_video_adapter_driver_info()
if video_adapter_driver_info.size() > 0:
add_line("Adapter driver name", video_adapter_driver_info[0])
if video_adapter_driver_info.size() > 1:

View File

@@ -1,8 +1,10 @@
[gd_scene load_steps=3 format=3 uid="uid://ds1y65r8ld026"]
[gd_scene load_steps=4 format=3 uid="uid://ds1y65r8ld026"]
[ext_resource type="Script" path="res://os_test.gd" id="1"]
[ext_resource type="Script" path="res://actions.gd" id="4"]
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_dl4cr"]
[node name="OSTest" type="Panel"]
anchors_preset = 15
anchor_right = 1.0
@@ -28,6 +30,8 @@ theme_override_constants/separation = 10
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
focus_mode = 2
theme_override_styles/focus = SubResource("StyleBoxEmpty_dl4cr")
bbcode_enabled = true
[node name="Actions" type="VBoxContainer" parent="HBoxContainer"]
@@ -134,17 +138,17 @@ text = "Kill Current Process"
[node name="CSharpTest" type="Node" parent="."]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/OpenShellWeb" to="HBoxContainer/Actions" method="_on_OpenShellWeb_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/OpenShellFolder" to="HBoxContainer/Actions" method="_on_OpenShellFolder_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/ChangeWindowTitle" to="HBoxContainer/Actions" method="_on_ChangeWindowTitle_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/ChangeWindowIcon" to="HBoxContainer/Actions" method="_on_ChangeWindowIcon_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/MoveWindowToForeground" to="HBoxContainer/Actions" method="_on_MoveWindowToForeground_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/RequestAttention" to="HBoxContainer/Actions" method="_on_RequestAttention_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/VibrateDeviceShort" to="HBoxContainer/Actions" method="_on_VibrateDeviceShort_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/VibrateDeviceLong" to="HBoxContainer/Actions" method="_on_VibrateDeviceLong_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/AddGlobalMenuItems" to="HBoxContainer/Actions" method="_on_AddGlobalMenuItems_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/RemoveGlobalMenuItem" to="HBoxContainer/Actions" method="_on_RemoveGlobalMenuItem_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/GetClipboard" to="HBoxContainer/Actions" method="_on_GetClipboard_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/SetClipboard" to="HBoxContainer/Actions" method="_on_SetClipboard_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/DisplayAlert" to="HBoxContainer/Actions" method="_on_DisplayAlert_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/KillCurrentProcess" to="HBoxContainer/Actions" method="_on_KillCurrentProcess_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/OpenShellWeb" to="HBoxContainer/Actions" method="_on_open_shell_web_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/OpenShellFolder" to="HBoxContainer/Actions" method="_on_open_shell_folder_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/ChangeWindowTitle" to="HBoxContainer/Actions" method="_on_change_window_title_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/ChangeWindowIcon" to="HBoxContainer/Actions" method="_on_change_window_icon_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/MoveWindowToForeground" to="HBoxContainer/Actions" method="_on_move_window_to_foreground_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/RequestAttention" to="HBoxContainer/Actions" method="_on_request_attention_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/VibrateDeviceShort" to="HBoxContainer/Actions" method="_on_vibrate_device_short_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/VibrateDeviceLong" to="HBoxContainer/Actions" method="_on_vibrate_device_long_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/AddGlobalMenuItems" to="HBoxContainer/Actions" method="_on_add_global_menu_items_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/RemoveGlobalMenuItem" to="HBoxContainer/Actions" method="_on_remove_global_menu_item_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/GetClipboard" to="HBoxContainer/Actions" method="_on_get_clipboard_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/SetClipboard" to="HBoxContainer/Actions" method="_on_set_clipboard_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/DisplayAlert" to="HBoxContainer/Actions" method="_on_display_alert_pressed"]
[connection signal="pressed" from="HBoxContainer/Actions/GridContainer/KillCurrentProcess" to="HBoxContainer/Actions" method="_on_kill_current_process_pressed"]

View File

@@ -23,6 +23,11 @@ config/features=PackedStringArray("4.2")
run/low_processor_mode=true
config/icon="res://icon.webp"
[debug]
gdscript/warnings/untyped_declaration=1
gdscript/warnings/int_as_enum_without_match=0
[display]
window/stretch/mode="canvas_items"

View File

@@ -1,6 +1,6 @@
extends Button
func _ready():
func _ready() -> void:
# This ensures that this Node won't be paused, allowing it to
# process even when the SceneTree is paused. Without that it would
# not be able to unpause the game. Note that you can set this through
@@ -8,7 +8,7 @@ func _ready():
process_mode = Node.PROCESS_MODE_ALWAYS
func _toggled(is_button_pressed):
func _toggled(is_button_pressed: bool) -> void:
# Pause or unpause the SceneTree based on whether the button is
# toggled on or off.
get_tree().paused = is_button_pressed

View File

@@ -1,7 +1,7 @@
extends OptionButton
@onready var cube_animation = $"../../AnimationPlayer"
@onready var cube_animation: AnimationPlayer = $"../../AnimationPlayer"
func _on_option_button_item_selected(index):
cube_animation.process_mode = index
func _on_option_button_item_selected(index: int) -> void:
cube_animation.process_mode = index as ProcessMode

View File

@@ -17,6 +17,10 @@ run/main_scene="res://spinpause.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

@@ -1,10 +1,10 @@
extends Control
var mouse_position = Vector2()
var mouse_position := Vector2()
@onready var observer = $"../Observer"
@onready var observer: CharacterBody3D = $"../Observer"
func _ready():
func _ready() -> void:
if not check_wm_api():
set_physics_process(false)
set_process_input(false)
@@ -14,8 +14,8 @@ func _ready():
if DisplayServer.get_screen_count() > 1:
$Labels/Label_Screen1_RefreshRate.text = "Screen1 Refresh Rate: %.2f Hz" % DisplayServer.screen_get_refresh_rate(1)
func _physics_process(_delta):
var modetext = "Mode: "
func _physics_process(_delta: float) -> void:
var modetext := "Mode: "
if DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_FULLSCREEN:
modetext += "Fullscreen\n"
else:
@@ -68,33 +68,33 @@ func _physics_process(_delta):
$Buttons/Button_MouseModeCaptured.set_pressed(Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED)
func _input(event):
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
mouse_position = event.position
if event is InputEventKey:
if Input.is_action_pressed(&"mouse_mode_visible"):
observer.state = observer.STATE_MENU
_on_Button_MouseModeVisible_pressed()
observer.state = observer.State.MENU
_on_button_mouse_mode_visible_pressed()
if Input.is_action_pressed(&"mouse_mode_hidden"):
observer.state = observer.STATE_MENU
_on_Button_MouseModeHidden_pressed()
observer.state = observer.State.MENU
_on_button_mouse_mode_hidden_pressed()
if Input.is_action_pressed(&"mouse_mode_captured"):
_on_Button_MouseModeCaptured_pressed()
_on_button_mouse_mode_captured_pressed()
if Input.is_action_pressed(&"mouse_mode_confined"):
observer.state = observer.STATE_MENU
_on_Button_MouseModeConfined_pressed()
observer.state = observer.State.MENU
_on_button_mouse_mode_confined_pressed()
if Input.is_action_pressed(&"mouse_mode_confined_hidden"):
observer.state = observer.STATE_MENU
_on_Button_MouseModeConfinedHidden_pressed()
observer.state = observer.State.MENU
_on_button_mouse_mode_confined_hidden_pressed()
func check_wm_api():
var s = ""
func check_wm_api() -> bool:
var s := ""
if not DisplayServer.has_method("get_screen_count"):
s += " - get_screen_count()\n"
if not DisplayServer.has_method("window_get_current_screen"):
@@ -139,65 +139,65 @@ func check_wm_api():
return false
func _on_Button_MoveTo_pressed():
func _on_button_move_to_pressed() -> void:
DisplayServer.window_set_position(Vector2(100, 100))
func _on_Button_Resize_pressed():
func _on_button_resize_pressed() -> void:
DisplayServer.window_set_size(Vector2(1280, 720))
func _on_Button_Screen0_pressed():
func _on_button_screen_0_pressed() -> void:
DisplayServer.window_set_current_screen(0)
func _on_Button_Screen1_pressed():
func _on_button_screen_1_pressed() -> void:
DisplayServer.window_set_current_screen(1)
func _on_Button_Fullscreen_pressed():
func _on_button_fullscreen_pressed() -> void:
if DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_FULLSCREEN:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
else:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)
func _on_Button_FixedSize_pressed():
func _on_button_fixed_size_pressed() -> void:
if DisplayServer.window_get_flag(DisplayServer.WINDOW_FLAG_RESIZE_DISABLED):
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_RESIZE_DISABLED, false)
else:
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_RESIZE_DISABLED, true)
func _on_Button_Minimized_pressed():
func _on_button_minimized_pressed() -> void:
if DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_MINIMIZED:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
else:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MINIMIZED)
func _on_Button_Maximized_pressed():
func _on_button_maximized_pressed() -> void:
if DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_MAXIMIZED:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MINIMIZED)
else:
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MAXIMIZED)
func _on_Button_MouseModeVisible_pressed():
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
func _on_button_mouse_mode_visible_pressed() -> void:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
func _on_Button_MouseModeHidden_pressed():
Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN)
func _on_button_mouse_mode_hidden_pressed() -> void:
Input.mouse_mode = Input.MOUSE_MODE_HIDDEN
func _on_Button_MouseModeCaptured_pressed():
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
observer.state = observer.STATE_GRAB
func _on_button_mouse_mode_captured_pressed() -> void:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
observer.state = observer.State.GRAB
func _on_Button_MouseModeConfined_pressed():
Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED)
func _on_button_mouse_mode_confined_pressed() -> void:
Input.mouse_mode = Input.MOUSE_MODE_CONFINED
func _on_Button_MouseModeConfinedHidden_pressed():
Input.set_mouse_mode(Input.MOUSE_MODE_CONFINED_HIDDEN)
func _on_button_mouse_mode_confined_hidden_pressed() -> void:
Input.mouse_mode = Input.MOUSE_MODE_CONFINED_HIDDEN

View File

@@ -1,51 +1,59 @@
extends CharacterBody3D
const STATE_MENU = 0
const STATE_GRAB = 1
enum State {
MENU,
GRAB,
}
var r_pos = Vector2()
var state = STATE_MENU
var r_pos := Vector2()
var state := State.MENU
var initial_viewport_height = ProjectSettings.get_setting("display/window/size/viewport_height")
var initial_viewport_height := int(ProjectSettings.get_setting("display/window/size/viewport_height"))
@onready var camera = $Camera3D
@onready var camera: Camera3D = $Camera3D
func _process(delta):
if state != STATE_GRAB:
func _process(delta: float) -> void:
if state != State.GRAB:
return
var x_movement = Input.get_axis(&"move_left", &"move_right")
var z_movement = Input.get_axis(&"move_forward", &"move_backwards")
var dir = direction(Vector3(x_movement, 0, z_movement))
var x_movement := Input.get_axis(&"move_left", &"move_right")
var z_movement := Input.get_axis(&"move_forward", &"move_backwards")
var dir := direction(Vector3(x_movement, 0, z_movement))
transform.origin += dir * 10 * delta
var d = delta * 0.1 # Scale the input, easiest to do by scaling the delta.
rotate(Vector3.UP, d * r_pos.x) # Yaw
camera.transform = camera.transform.rotated(Vector3.RIGHT, d * r_pos.y) # Pitch
# Scale the input, easiest to do by scaling the delta.
var d := delta * 0.1
rotate(Vector3.UP, d * r_pos.x) # Yaw
camera.transform = camera.transform.rotated(Vector3.RIGHT, d * r_pos.y) # Pitch
r_pos = Vector2.ZERO # We've dealt with all the input, so set it to zero.
# We've dealt with all the input, so set it to zero.
r_pos = Vector2.ZERO
func _input(event):
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion:
# Scale mouse sensitivity according to resolution, so that effective mouse sensitivity
# doesn't change depending on the viewport size.
r_pos = -event.relative * (get_viewport().size.y / initial_viewport_height)
if event.is_action("ui_cancel") and event.is_pressed() and not event.is_echo():
if state == STATE_GRAB:
if state == State.GRAB:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
state = STATE_MENU
state = State.MENU
else:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
state = STATE_GRAB
state = State.GRAB
func direction(vector):
var v = camera.get_global_transform().basis * vector
func direction(vector: Vector3) -> Vector3:
var v := camera.get_global_transform().basis * vector
return v.normalized()
func _on_transparent_check_button_toggled(button_pressed):
func _on_transparent_check_button_toggled(button_pressed: bool) -> void:
if not DisplayServer.has_feature(DisplayServer.FEATURE_WINDOW_TRANSPARENCY):
OS.alert("Window transparency is not supported by the current display server (%s)." % DisplayServer.get_name())
return
get_viewport().transparent_bg = button_pressed
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_TRANSPARENT, button_pressed)

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/stretch/mode="canvas_items"

View File

@@ -355,17 +355,17 @@ grow_horizontal = 0
grow_vertical = 0
text = "Transparent"
[connection signal="pressed" from="Control/Buttons/Button_Fullscreen" to="Control" method="_on_Button_Fullscreen_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_FixedSize" to="Control" method="_on_Button_FixedSize_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Minimized" to="Control" method="_on_Button_Minimized_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Maximized" to="Control" method="_on_Button_Maximized_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MoveTo" to="Control" method="_on_Button_MoveTo_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Resize" to="Control" method="_on_Button_Resize_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Screen0" to="Control" method="_on_Button_Screen0_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Screen1" to="Control" method="_on_Button_Screen1_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MouseModeVisible" to="Control" method="_on_Button_MouseModeVisible_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MouseModeHidden" to="Control" method="_on_Button_MouseModeHidden_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MouseModeCaptured" to="Control" method="_on_Button_MouseModeCaptured_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MouseModeConfined" to="Control" method="_on_Button_MouseModeConfined_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MouseModeConfinedHidden" to="Control" method="_on_Button_MouseModeConfinedHidden_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Fullscreen" to="Control" method="_on_button_fullscreen_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_FixedSize" to="Control" method="_on_button_fixed_size_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Minimized" to="Control" method="_on_button_minimized_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Maximized" to="Control" method="_on_button_maximized_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MoveTo" to="Control" method="_on_button_move_to_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Resize" to="Control" method="_on_button_resize_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Screen0" to="Control" method="_on_button_screen_0_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_Screen1" to="Control" method="_on_button_screen_1_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MouseModeVisible" to="Control" method="_on_button_mouse_mode_visible_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MouseModeHidden" to="Control" method="_on_button_mouse_mode_hidden_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MouseModeCaptured" to="Control" method="_on_button_mouse_mode_captured_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MouseModeConfined" to="Control" method="_on_button_mouse_mode_confined_pressed"]
[connection signal="pressed" from="Control/Buttons/Button_MouseModeConfinedHidden" to="Control" method="_on_button_mouse_mode_confined_hidden_pressed"]
[connection signal="toggled" from="Control/CheckButton" to="Observer" method="_on_transparent_check_button_toggled"]