From 582489fea7cce78d5f93d6081ca6ee4846b03bee Mon Sep 17 00:00:00 2001 From: veclav talica Date: Sat, 25 Nov 2023 18:27:41 +0500 Subject: [PATCH] base Context and Controller classes, generalization of context --- nodes/4WayController.gd | 22 ++++++++++++++ ...ridController.tscn => 4WayController.tscn} | 2 +- nodes/Context.gd | 17 +++++++++++ nodes/Controller.gd | 13 ++++++++ nodes/FittingSprite.gd | 9 +++++- nodes/GameObject.tscn | 3 ++ nodes/GridContext.gd | 13 ++++---- nodes/GridController.gd | 30 ------------------- nodes/singletons/Arithmetic.gd | 4 +-- nodes/singletons/InputUtils.gd | 14 ++++++++- project.godot | 28 ++++++++++++----- scenes/Game.tscn | 16 ++++++---- 12 files changed, 116 insertions(+), 55 deletions(-) create mode 100644 nodes/4WayController.gd rename nodes/{GridController.tscn => 4WayController.tscn} (63%) create mode 100644 nodes/Context.gd create mode 100644 nodes/Controller.gd create mode 100644 nodes/GameObject.tscn delete mode 100644 nodes/GridController.gd diff --git a/nodes/4WayController.gd b/nodes/4WayController.gd new file mode 100644 index 0000000..39ef18f --- /dev/null +++ b/nodes/4WayController.gd @@ -0,0 +1,22 @@ +extends TK_Controller +class_name TK_4WayController + +## Composable 4-way grid controller. +## Depends on placement below some Node2D below some GridContext. + +# todo: Network player aware. +# todo: AI aware. + +var _game_object: Node2D + +func _enter_tree() -> void: + _game_object = get_parent() + +func _input(p_event: InputEvent): + var direction := InputUtils.input_event_to_4way_direction(p_event) + if direction == Vector2.ZERO: + return + + var cell = _context.local_position_to_context_position(_game_object.position) + var new_cell = cell + direction + _context.try_moving(_game_object, cell, new_cell) diff --git a/nodes/GridController.tscn b/nodes/4WayController.tscn similarity index 63% rename from nodes/GridController.tscn rename to nodes/4WayController.tscn index 59c9e3f..a8be510 100644 --- a/nodes/GridController.tscn +++ b/nodes/4WayController.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=2 format=2] -[ext_resource path="res://nodes/GridController.gd" type="Script" id=1] +[ext_resource path="res://nodes/4WayController.gd" type="Script" id=1] [node name="GridController" type="Node"] script = ExtResource( 1 ) diff --git a/nodes/Context.gd b/nodes/Context.gd new file mode 100644 index 0000000..6d14606 --- /dev/null +++ b/nodes/Context.gd @@ -0,0 +1,17 @@ +extends Node2D +class_name TK_Context + +# todo: Abstract actions. +# todo: Signal registration of GameObject actions. + +func local_position_to_context_position(_p_position: Vector2) -> Vector2: + push_error("Abstract class method is unimplemented") + return Vector2.ZERO + +func is_path_traversible(_p_from: Vector2, _p_to: Vector2) -> bool: + push_error("Abstract class method is unimplemented") + return false + +func try_moving(_p_game_object: Node2D, _p_from: Vector2, _p_to: Vector2) -> bool: + push_error("Abstract class method is unimplemented") + return false diff --git a/nodes/Controller.gd b/nodes/Controller.gd new file mode 100644 index 0000000..adf1b1c --- /dev/null +++ b/nodes/Controller.gd @@ -0,0 +1,13 @@ +extends Node +class_name TK_Controller + +var _context: Node2D + +func _enter_tree() -> void: + _context = _get_context() + +func _get_context() -> Node: + var current := self.get_parent().get_parent() + while not current is TK_Context: + current = current.get_parent() + return current diff --git a/nodes/FittingSprite.gd b/nodes/FittingSprite.gd index 1cf264b..d513d34 100644 --- a/nodes/FittingSprite.gd +++ b/nodes/FittingSprite.gd @@ -4,7 +4,14 @@ class_name TK_FittingSprite ## A Sprite that is resized to absolute pixel size, no matter the texture. -export var target_size: Vector2 setget _set_target_size +const NO_SIZE_SENTINEL = Vector2(-1, -1) + +export var target_size: Vector2 = NO_SIZE_SENTINEL setget _set_target_size + +# todo: Ask context about preferred sizing if there's any. +func _enter_tree() -> void: + if target_size == NO_SIZE_SENTINEL: + self.target_size = texture.get_size() func _set_target_size(p_size: Vector2) -> void: target_size = p_size diff --git a/nodes/GameObject.tscn b/nodes/GameObject.tscn new file mode 100644 index 0000000..b89dd57 --- /dev/null +++ b/nodes/GameObject.tscn @@ -0,0 +1,3 @@ +[gd_scene format=2] + +[node name="GameObject" type="Node2D"] diff --git a/nodes/GridContext.gd b/nodes/GridContext.gd index 7c036bd..87bb432 100644 --- a/nodes/GridContext.gd +++ b/nodes/GridContext.gd @@ -1,4 +1,4 @@ -extends Node2D +extends TK_Context class_name TK_GridContext ## todo: Cell visualization. @@ -6,15 +6,16 @@ class_name TK_GridContext export var cell_size: Vector2 = Vector2(64, 64) -func position_to_cell_position(p_position: Vector2) -> Vector2: +func local_position_to_context_position(p_position: Vector2) -> Vector2: return p_position / cell_size -func is_cell_traversible(p_cell_position: Vector2) -> bool: +func is_path_traversible(p_from: Vector2, p_to: Vector2) -> bool: + # todo: return true -func try_moving(p_node: Node2D, p_cell_position: Vector2) -> bool: - if not is_cell_traversible(p_cell_position): +func try_moving(p_game_object: Node2D, p_from: Vector2, p_to: Vector2) -> bool: + if not is_path_traversible(p_from, p_to): return false - p_node.position = cell_size * p_cell_position + p_game_object.position = cell_size * p_to return true diff --git a/nodes/GridController.gd b/nodes/GridController.gd deleted file mode 100644 index a8358d4..0000000 --- a/nodes/GridController.gd +++ /dev/null @@ -1,30 +0,0 @@ -extends Node -class_name TK_GridController - -## Composable 4-way grid controller. -## Depends on placement below some Node2D below some GridContext. - -# todo: Turn-based logic context. - -signal moved(p_new_cell_position) - -var _grid_context_cache: Node2D - -func _enter_tree() -> void: - _grid_context_cache = _get_grid_context() - -func _input(p_event: InputEvent): - var direction := InputUtils.input_event_to_4way_direction(p_event) - if direction == Vector2.ZERO: - return - - var cell = _grid_context_cache.position_to_cell_position(get_parent().position) - var new_cell = cell + direction - if _grid_context_cache.try_moving(get_parent(), new_cell): - emit_signal("moved", new_cell) - -func _get_grid_context() -> Node: - var current := self.get_parent().get_parent() - while current.name != "GridContext": - current = current.get_parent() - return current diff --git a/nodes/singletons/Arithmetic.gd b/nodes/singletons/Arithmetic.gd index 5be6587..d4cf202 100644 --- a/nodes/singletons/Arithmetic.gd +++ b/nodes/singletons/Arithmetic.gd @@ -2,7 +2,7 @@ extends Node class_name TK_Arithmetic static func float_mod(p_a: float, p_b: float) -> float: - return p_a - (p_b * floor(p_a / p_b)) + return p_a - p_b * floor(p_a / p_b) static func vector2_mod(p_a: Vector2, p_b: Vector2) -> Vector2: - return p_a - (p_b * (p_a / p_b).floor()) + return p_a - p_b * (p_a / p_b).floor() diff --git a/nodes/singletons/InputUtils.gd b/nodes/singletons/InputUtils.gd index 06a5e1e..e2d4cff 100644 --- a/nodes/singletons/InputUtils.gd +++ b/nodes/singletons/InputUtils.gd @@ -1,6 +1,6 @@ extends Node -func input_event_to_4way_direction(p_event: InputEvent) -> Vector2: +func input_event_to_8way_direction(p_event: InputEvent) -> Vector2: var result := Vector2.ZERO if p_event.is_action_pressed("move_down"): result.y += 1 @@ -11,3 +11,15 @@ func input_event_to_4way_direction(p_event: InputEvent) -> Vector2: if p_event.is_action_pressed("move_left"): result.x -= 1 return result + +func input_event_to_4way_direction(p_event: InputEvent) -> Vector2: + if p_event.is_action_pressed("move_down") and not p_event.is_action_pressed("move_up"): + return Vector2.DOWN + elif p_event.is_action_pressed("move_up") and not p_event.is_action_pressed("move_down"): + return Vector2.UP + elif p_event.is_action_pressed("move_left") and not p_event.is_action_pressed("move_right"): + return Vector2.LEFT + elif p_event.is_action_pressed("move_right") and not p_event.is_action_pressed("move_left"): + return Vector2.RIGHT + else: + return Vector2.ZERO diff --git a/project.godot b/project.godot index 7062b5a..ab242f5 100644 --- a/project.godot +++ b/project.godot @@ -104,25 +104,35 @@ _global_script_classes=[ { "language": "GDScript", "path": "res://addons/Godoxel/Util.gd" }, { +"base": "TK_Controller", +"class": "TK_4WayController", +"language": "GDScript", +"path": "res://nodes/4WayController.gd" +}, { "base": "Node", "class": "TK_Arithmetic", "language": "GDScript", "path": "res://nodes/singletons/Arithmetic.gd" }, { +"base": "Node2D", +"class": "TK_Context", +"language": "GDScript", +"path": "res://nodes/Context.gd" +}, { +"base": "Node", +"class": "TK_Controller", +"language": "GDScript", +"path": "res://nodes/Controller.gd" +}, { "base": "Sprite", "class": "TK_FittingSprite", "language": "GDScript", "path": "res://nodes/FittingSprite.gd" }, { -"base": "Node2D", +"base": "TK_Context", "class": "TK_GridContext", "language": "GDScript", "path": "res://nodes/GridContext.gd" -}, { -"base": "Node", -"class": "TK_GridController", -"language": "GDScript", -"path": "res://nodes/GridController.gd" } ] _global_script_class_icons={ "BrushPrefabs": "", @@ -144,10 +154,12 @@ _global_script_class_icons={ "GERainbow": "", "GERect": "", "GEUtils": "", +"TK_4WayController": "", "TK_Arithmetic": "", +"TK_Context": "", +"TK_Controller": "", "TK_FittingSprite": "", -"TK_GridContext": "", -"TK_GridController": "" +"TK_GridContext": "" } [application] diff --git a/scenes/Game.tscn b/scenes/Game.tscn index a2fd1a4..708d9f5 100644 --- a/scenes/Game.tscn +++ b/scenes/Game.tscn @@ -1,21 +1,25 @@ -[gd_scene load_steps=5 format=2] +[gd_scene load_steps=6 format=2] [ext_resource path="res://nodes/FittingSprite.gd" type="Script" id=1] [ext_resource path="res://art/entities/fiend.png" type="Texture" id=2] -[ext_resource path="res://nodes/GridController.gd" type="Script" id=3] +[ext_resource path="res://nodes/4WayController.tscn" type="PackedScene" id=3] [ext_resource path="res://nodes/GridContext.tscn" type="PackedScene" id=4] +[ext_resource path="res://nodes/GameObject.tscn" type="PackedScene" id=5] [node name="Game" type="Node"] [node name="GridContext" parent="." instance=ExtResource( 4 )] -[node name="Fiend" type="Sprite" parent="GridContext"] -position = Vector2( 128, 128 ) +[node name="GameObject" parent="GridContext" instance=ExtResource( 5 )] + +[node name="Visual" type="Sprite" parent="GridContext/GameObject"] scale = Vector2( 4, 4 ) texture = ExtResource( 2 ) centered = false script = ExtResource( 1 ) target_size = Vector2( 64, 64 ) -[node name="GridController" type="Node" parent="GridContext/Fiend"] -script = ExtResource( 3 ) +[node name="4WayController" parent="GridContext/GameObject" instance=ExtResource( 3 )] + +[node name="Camera2D" type="Camera2D" parent="GridContext/GameObject"] +position = Vector2( 32, 32 )