base Context and Controller classes, generalization of context

This commit is contained in:
veclav talica
2023-11-25 18:27:41 +05:00
parent 29d68068ac
commit 582489fea7
12 changed files with 116 additions and 55 deletions

22
nodes/4WayController.gd Normal file
View File

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

View File

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

17
nodes/Context.gd Normal file
View File

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

13
nodes/Controller.gd Normal file
View File

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

View File

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

3
nodes/GameObject.tscn Normal file
View File

@ -0,0 +1,3 @@
[gd_scene format=2]
[node name="GameObject" type="Node2D"]

View File

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

View File

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

View File

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

View File

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