contextual collisions, tilemap support for collision of tiles

This commit is contained in:
veclav talica 2023-11-26 05:17:35 +05:00
parent 184e24365f
commit ec1c99ebb4
5 changed files with 41 additions and 9 deletions

View File

@ -9,7 +9,7 @@ func local_position_to_context_position(_p_position: Vector2) -> Vector2:
push_error("Abstract class method is unimplemented") push_error("Abstract class method is unimplemented")
return Vector2.ZERO return Vector2.ZERO
func is_path_traversible(_p_from: Vector2, _p_to: Vector2) -> bool: func is_path_traversible(_p_game_object: Node2D, _p_from: Vector2, _p_to: Vector2) -> bool:
push_error("Abstract class method is unimplemented") push_error("Abstract class method is unimplemented")
return false return false

View File

@ -9,20 +9,34 @@ export var cell_size: Vector2 = Vector2(64, 64) setget _set_cell_size
signal cell_size_changed(p_old_cell_size, p_new_cell_size) signal cell_size_changed(p_old_cell_size, p_new_cell_size)
var _colliders: Dictionary # Node to null (set)
func local_position_to_context_position(p_position: Vector2) -> Vector2: func local_position_to_context_position(p_position: Vector2) -> Vector2:
return p_position / cell_size return p_position / cell_size
func is_path_traversible(p_from: Vector2, p_to: Vector2) -> bool: func is_path_traversible(p_game_object: Node2D, p_from: Vector2, p_to: Vector2) -> bool:
# todo: for collider in _colliders:
if not collider.is_path_traversible(p_game_object, p_from, p_to):
return false
return true return true
# todo: Effectful traversal.
func try_moving(p_game_object: Node2D, p_from: Vector2, p_to: Vector2) -> bool: func try_moving(p_game_object: Node2D, p_from: Vector2, p_to: Vector2) -> bool:
if not is_path_traversible(p_from, p_to): if not is_path_traversible(p_game_object, p_from, p_to):
return false return false
p_game_object.position = cell_size * p_to p_game_object.position = cell_size * p_to
return true return true
func register_collider(p_collider: Node) -> void:
_colliders[p_collider] = null
if p_collider.connect("child_exiting_tree", self, "_on_collider_exiting_tree") != OK:
assert(false)
func _on_collider_exiting_tree(p_collider) -> void:
if not _colliders.erase(p_collider):
pass
func _set_cell_size(p_new_cell_size: Vector2) -> void: func _set_cell_size(p_new_cell_size: Vector2) -> void:
if p_new_cell_size.x == 0 or p_new_cell_size.y == 0: if p_new_cell_size.x == 0 or p_new_cell_size.y == 0:
push_error("Cell size cannot be zero") push_error("Cell size cannot be zero")

View File

@ -7,6 +7,7 @@ extends TileMap
export var expose_collisions: bool = true export var expose_collisions: bool = true
var _descriptor_name_to_id: Dictionary # String to int var _descriptor_name_to_id: Dictionary # String to int
var _id_to_descriptor_name: Dictionary # int to String
func change_tile_texture(p_tile: String, p_texture: Texture) -> void: func change_tile_texture(p_tile: String, p_texture: Texture) -> void:
if not p_tile in _descriptor_name_to_id: if not p_tile in _descriptor_name_to_id:
@ -16,8 +17,19 @@ func change_tile_texture(p_tile: String, p_texture: Texture) -> void:
var id := _descriptor_name_to_id[p_tile] as int var id := _descriptor_name_to_id[p_tile] as int
tile_set.tile_set_texture(id, p_texture) tile_set.tile_set_texture(id, p_texture)
func is_path_traversible(p_game_object: Node2D, p_from: Vector2, p_to: Vector2) -> bool:
if p_from.distance_squared_to(p_to) == 1:
var id := get_cell(int(p_to.x), int(p_to.y))
if id == -1: return true
var descriptor = _id_to_descriptor_name[id] as String
return get_node(descriptor).is_traversible_for(p_game_object)
else:
print_debug("Unimplemented")
return false
func _enter_tree() -> void: func _enter_tree() -> void:
tile_set = TileSet.new() tile_set = TileSet.new()
get_parent().register_collider(self)
# It's okay to fail here for non-grid contexts. # It's okay to fail here for non-grid contexts.
if get_parent().connect("cell_size_changed", self, "_update_cell_size"): if get_parent().connect("cell_size_changed", self, "_update_cell_size"):
@ -41,6 +53,7 @@ func _update_cell_size(_p_old_cell_size: Vector2, p_new_cell_size: Vector2) -> v
func _on_child_entered_tree(p_node: Node) -> void: func _on_child_entered_tree(p_node: Node) -> void:
var id := tile_set.get_last_unused_tile_id() var id := tile_set.get_last_unused_tile_id()
_descriptor_name_to_id[p_node.name] = id _descriptor_name_to_id[p_node.name] = id
_id_to_descriptor_name[id] = p_node.name
tile_set.create_tile(id) tile_set.create_tile(id)
tile_set.tile_set_texture(id, p_node.texture) tile_set.tile_set_texture(id, p_node.texture)
@ -51,3 +64,5 @@ func _on_child_exiting_tree(p_node: Node) -> void:
tile_set.remove_tile(id) tile_set.remove_tile(id)
if not _descriptor_name_to_id.erase(p_node.name): if not _descriptor_name_to_id.erase(p_node.name):
assert(false) assert(false)
if not _id_to_descriptor_name.erase(id):
assert(false)

View File

@ -7,6 +7,9 @@ export var texture: Texture setget _set_texture
# todo: More layer customizeability. # todo: More layer customizeability.
export var is_solid: bool export var is_solid: bool
func is_traversible_for(_p_game_object: Node2D) -> bool:
return not is_solid
func _set_texture(p_texture: Texture) -> void: func _set_texture(p_texture: Texture) -> void:
texture = p_texture texture = p_texture
if is_inside_tree(): if is_inside_tree():

View File

@ -40,10 +40,10 @@ script = ExtResource( 7 )
[node name="Brickwall" parent="GridContext/TileMapObject" instance=ExtResource( 8 )] [node name="Brickwall" parent="GridContext/TileMapObject" instance=ExtResource( 8 )]
[node name="GameObject" parent="GridContext" instance=ExtResource( 5 )] [node name="Player" parent="GridContext" instance=ExtResource( 5 )]
position = Vector2( 384, 128 ) position = Vector2( 384, 128 )
[node name="Visual" type="Sprite" parent="GridContext/GameObject"] [node name="Visual" type="Sprite" parent="GridContext/Player"]
scale = Vector2( 4, 4 ) scale = Vector2( 4, 4 )
texture = ExtResource( 2 ) texture = ExtResource( 2 )
centered = false centered = false
@ -53,9 +53,9 @@ __meta__ = {
} }
target_size = Vector2( 64, 64 ) target_size = Vector2( 64, 64 )
[node name="4WayController" parent="GridContext/GameObject" instance=ExtResource( 3 )] [node name="4WayController" parent="GridContext/Player" instance=ExtResource( 3 )]
[node name="Camera2D" type="Camera2D" parent="GridContext/GameObject"] [node name="Camera2D" type="Camera2D" parent="GridContext/Player"]
position = Vector2( 32, 32 ) position = Vector2( 32, 32 )
__meta__ = { __meta__ = {
"_edit_lock_": true "_edit_lock_": true