Compare commits

..

4 Commits

7 changed files with 162 additions and 48 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

@ -1,6 +1,6 @@
tool tool
extends TK_Context extends TK_Context
class_name TK_GridContext class_name n_parent
## todo: Cell visualization. ## todo: Cell visualization.
## todo: Integration of TileMap. ## todo: Integration of TileMap.
@ -9,20 +9,35 @@ 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 not p_collider.is_connected("child_exiting_tree", self, "_on_collider_exiting_tree") and \
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

@ -1,17 +1,83 @@
tool tool
extends TileMap extends TileMap
# todo: Give care about descriptor swaps being loseless / non introducing artifacts.
# todo: Prevent user from deleting or editing tile_set property.
# todo: Update it when changed.
## Dictates whether tileset collision information should be exposed to game context. ## Dictates whether tileset collision information should be exposed to game context.
export var expose_collisions: bool = true export var expose_collisions: bool = true
# todo: Use Node identity instead of name.
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:
if not p_tile in _descriptor_name_to_id:
push_error("Invalid tile name")
return
var id := _descriptor_name_to_id[p_tile] as int
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()
var n_parent := get_parent()
if not n_parent is TK_Context:
return
n_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 not n_parent.is_connected("cell_size_changed", self, "_update_cell_size") and \
_update_cell_size(get_parent().cell_size, get_parent().cell_size) n_parent.connect("cell_size_changed", self, "_update_cell_size") != OK:
assert(false)
_update_cell_size(n_parent.cell_size, n_parent.cell_size)
if not is_connected("child_entered_tree", self, "_on_child_entered_tree") and \
connect("child_entered_tree", self, "_on_child_entered_tree") != OK:
assert(false)
if not is_connected("child_exiting_tree", self, "_on_child_exiting_tree") and \
connect("child_exiting_tree", self, "_on_child_exiting_tree") != OK:
assert(false)
func _update_cell_size(_p_old_cell_size: Vector2, p_new_cell_size: Vector2) -> void: func _update_cell_size(_p_old_cell_size: Vector2, p_new_cell_size: Vector2) -> void:
# We're assuming that all tile textures are of same dimensions. # We're assuming that all tile textures are of same dimensions.
# todo: Diagnose mismatch by walking over all textures? # todo: Diagnose mismatch by walking over all textures?
if tile_set.get_tiles_ids().size() == 0:
return
var tileset_texture_size := tile_set.tile_get_texture(0).get_size() var tileset_texture_size := tile_set.tile_get_texture(0).get_size()
scale = p_new_cell_size / tileset_texture_size scale = p_new_cell_size / tileset_texture_size
cell_size = p_new_cell_size / scale cell_size = p_new_cell_size / scale
func _on_child_entered_tree(p_node: Node) -> void:
var id := tile_set.get_last_unused_tile_id()
_descriptor_name_to_id[p_node.name] = id
_id_to_descriptor_name[id] = p_node.name
tile_set.create_tile(id)
tile_set.tile_set_texture(id, p_node.texture)
if not p_node.id.empty():
tile_set.tile_set_name(id, p_node.id)
func _on_child_exiting_tree(p_node: Node) -> void:
var id := _descriptor_name_to_id[p_node.name] as int
for cell in get_used_cells_by_id(id):
set_cellv(cell, -1)
tile_set.remove_tile(id)
if not _descriptor_name_to_id.erase(p_node.name):
assert(false)
if not _id_to_descriptor_name.erase(id):
assert(false)

View File

@ -0,0 +1,20 @@
tool
extends Node
class_name TK_TileMapTileDescriptor
export var texture: Texture setget _set_texture
# todo: More layer customizeability.
export var is_solid: bool
# todo: Update TileMapObject in editor when it's changed.
export var id: String = ""
# todo: Should work for non-grid objects.
func is_traversible_for(_p_game_object: Node2D) -> bool:
return not is_solid
func _set_texture(p_texture: Texture) -> void:
texture = p_texture
if is_inside_tree():
get_parent().change_tile_texture(name, p_texture)

View File

@ -134,8 +134,13 @@ _global_script_classes=[ {
"language": "GDScript", "language": "GDScript",
"path": "res://nodes/GameObject.gd" "path": "res://nodes/GameObject.gd"
}, { }, {
"base": "Node",
"class": "TK_TileMapTileDescriptor",
"language": "GDScript",
"path": "res://nodes/TileMapTileDescriptor.gd"
}, {
"base": "TK_Context", "base": "TK_Context",
"class": "TK_GridContext", "class": "n_parent",
"language": "GDScript", "language": "GDScript",
"path": "res://nodes/GridContext.gd" "path": "res://nodes/GridContext.gd"
} ] } ]
@ -165,13 +170,15 @@ _global_script_class_icons={
"TK_Controller": "", "TK_Controller": "",
"TK_FittingSprite": "", "TK_FittingSprite": "",
"TK_GameObject": "", "TK_GameObject": "",
"TK_GridContext": "" "TK_TileMapTileDescriptor": "",
"n_parent": ""
} }
[application] [application]
config/name="TochieKit" config/name="TochieKit"
run/main_scene="res://scenes/Game.tscn" run/main_scene="res://scenes/Game.tscn"
run/low_processor_mode=true
config/icon="res://icon.png" config/icon="res://icon.png"
[autoload] [autoload]
@ -220,6 +227,15 @@ move_left={
] ]
} }
[input_devices]
buffering/agile_event_flushing=true
pointing/emulate_touch_from_mouse=true
[node]
name_num_separator=3
[physics] [physics]
common/enable_pause_aware_picking=true common/enable_pause_aware_picking=true
@ -227,8 +243,18 @@ common/enable_pause_aware_picking=true
[rendering] [rendering]
quality/driver/driver_name="GLES2" quality/driver/driver_name="GLES2"
quality/intended_usage/framebuffer_allocation=1
quality/intended_usage/framebuffer_allocation.mobile=1
2d/snapping/use_gpu_pixel_snap=true 2d/snapping/use_gpu_pixel_snap=true
threads/thread_model=2
vram_compression/import_etc=true vram_compression/import_etc=true
vram_compression/import_etc2=false vram_compression/import_etc2=false
quality/reflections/texture_array_reflections=false
quality/shading/force_vertex_shading=true
quality/shading/force_lambert_over_burley=true
quality/shading/force_blinn_over_ggx=true
quality/filters/use_nearest_mipmap_filter=true
batching/options/single_rect_fallback=true
quality/lightmapping/use_bicubic_sampling=false
environment/default_clear_color=Color( 0.00784314, 0, 0.117647, 1 ) environment/default_clear_color=Color( 0.00784314, 0, 0.117647, 1 )
environment/default_environment="res://default_env.tres" environment/default_environment="res://default_env.tres"

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=12 format=2] [gd_scene load_steps=10 format=2]
[ext_resource path="res://nodes/FittingSprite.gd" type="Script" id=1] [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://art/entities/fiend.png" type="Texture" id=2]
@ -6,64 +6,41 @@
[ext_resource path="res://nodes/GridContext.tscn" type="PackedScene" id=4] [ext_resource path="res://nodes/GridContext.tscn" type="PackedScene" id=4]
[ext_resource path="res://nodes/GameObject.tscn" type="PackedScene" id=5] [ext_resource path="res://nodes/GameObject.tscn" type="PackedScene" id=5]
[ext_resource path="res://art/tiles/brickwall.png" type="Texture" id=6] [ext_resource path="res://art/tiles/brickwall.png" type="Texture" id=6]
[ext_resource path="res://nodes/TileMapObject.gd" type="Script" id=7] [ext_resource path="res://nodes/TileMapObject.tscn" type="PackedScene" id=7]
[ext_resource path="res://scenes/tiles/Brickwall.tscn" type="PackedScene" id=8]
[sub_resource type="OccluderPolygon2D" id=2]
polygon = PoolVector2Array( 16, 16, 0, 16, 0, 0, 16, 0 )
[sub_resource type="ConvexPolygonShape2D" id=3]
points = PoolVector2Array( 16, 16, 0, 16, 0, 16, 16, 16 )
[sub_resource type="ConvexPolygonShape2D" id=4]
points = PoolVector2Array( 16, 16, 0, 16, 0, 0, 16, 0 )
[sub_resource type="TileSet" id=1] [sub_resource type="TileSet" id=1]
0/name = "brickwall.png 0" 0/name = "tk.Brickwall"
0/texture = ExtResource( 6 ) 0/texture = ExtResource( 6 )
0/tex_offset = Vector2( 0, 0 ) 0/tex_offset = Vector2( 0, 0 )
0/modulate = Color( 1, 1, 1, 1 ) 0/modulate = Color( 1, 1, 1, 1 )
0/region = Rect2( 0, 0, 16, 16 ) 0/region = Rect2( 0, 0, 0, 0 )
0/tile_mode = 0 0/tile_mode = 0
0/occluder_offset = Vector2( 0, 0 ) 0/occluder_offset = Vector2( 0, 0 )
0/occluder = SubResource( 2 )
0/navigation_offset = Vector2( 0, 0 ) 0/navigation_offset = Vector2( 0, 0 )
0/shape_offset = Vector2( 0, 0 ) 0/shape_offset = Vector2( 0, 0 )
0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) 0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 )
0/shape = SubResource( 3 )
0/shape_one_way = false 0/shape_one_way = false
0/shape_one_way_margin = 1.0 0/shape_one_way_margin = 0.0
0/shapes = [ { 0/shapes = [ ]
"autotile_coord": Vector2( 0, 0 ),
"one_way": false,
"one_way_margin": 1.0,
"shape": SubResource( 3 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
}, {
"autotile_coord": Vector2( 0, 0 ),
"one_way": false,
"one_way_margin": 1.0,
"shape": SubResource( 4 ),
"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 )
} ]
0/z_index = 0 0/z_index = 0
[node name="Gauntlet" type="Node"] [node name="Gauntlet" type="Node"]
[node name="GridContext" parent="." instance=ExtResource( 4 )] [node name="GridContext" parent="." instance=ExtResource( 4 )]
[node name="TileMap" type="TileMap" parent="GridContext"] [node name="TileMapObject" parent="GridContext" instance=ExtResource( 7 )]
scale = Vector2( 4, 4 ) scale = Vector2( 4, 4 )
tile_set = SubResource( 1 ) tile_set = SubResource( 1 )
cell_size = Vector2( 16, 16 ) cell_size = Vector2( 16, 16 )
bake_navigation = true tile_data = PoolIntArray( 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0, 5, 0, 0, 6, 0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 0, 10, 0, 0, 11, 0, 0, 12, 0, 0, 13, 0, 0, 14, 0, 0, 15, 0, 0, 65536, 0, 0, 65551, 0, 0, 131072, 0, 0, 131087, 0, 0, 196608, 0, 0, 196623, 0, 0, 262144, 0, 0, 262159, 0, 0, 327680, 0, 0, 327695, 0, 0, 393216, 0, 0, 393231, 0, 0, 458752, 0, 0, 458767, 0, 0, 524288, 0, 0, 524289, 0, 0, 524290, 0, 0, 524291, 0, 0, 524292, 0, 0, 524293, 0, 0, 524294, 0, 0, 524295, 0, 0, 524296, 0, 0, 524297, 0, 0, 524298, 0, 0, 524299, 0, 0, 524300, 0, 0, 524301, 0, 0, 524302, 0, 0, 524303, 0, 0 )
format = 1
tile_data = PoolIntArray( 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0, 5, 0, 0, 6, 0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 0, 10, 0, 0, 11, 0, 0, 12, 0, 0, 13, 0, 0, 14, 0, 0, 15, 0, 0, 65536, 0, 0, 65542, 0, 0, 65551, 0, 0, 131072, 0, 0, 131082, 0, 0, 131087, 0, 0, 196608, 0, 0, 196618, 0, 0, 196623, 0, 0, 262144, 0, 0, 262145, 0, 0, 262146, 0, 0, 262147, 0, 0, 262148, 0, 0, 262149, 0, 0, 262150, 0, 0, 262151, 0, 0, 262152, 0, 0, 262153, 0, 0, 262154, 0, 0, 262156, 0, 0, 262157, 0, 0, 262158, 0, 0, 262159, 0, 0, 327680, 0, 0, 327683, 0, 0, 327695, 0, 0, 393216, 0, 0, 393226, 0, 0, 393227, 0, 0, 393229, 0, 0, 393231, 0, 0, 458752, 0, 0, 458761, 0, 0, 458762, 0, 0, 458767, 0, 0, 524288, 0, 0, 524289, 0, 0, 524290, 0, 0, 524291, 0, 0, 524292, 0, 0, 524293, 0, 0, 524294, 0, 0, 524295, 0, 0, 524296, 0, 0, 524297, 0, 0, 524298, 0, 0, 524299, 0, 0, 524300, 0, 0, 524301, 0, 0, 524302, 0, 0, 524303, 0, 0 )
script = ExtResource( 7 )
[node name="GameObject" parent="GridContext" instance=ExtResource( 5 )] [node name="Brickwall" parent="GridContext/TileMapObject" instance=ExtResource( 8 )]
[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
@ -73,9 +50,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

View File

@ -0,0 +1,10 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://art/tiles/brickwall.png" type="Texture" id=1]
[ext_resource path="res://nodes/TileMapTileDescriptor.gd" type="Script" id=2]
[node name="Brickwall" type="Node"]
script = ExtResource( 2 )
texture = ExtResource( 1 )
is_solid = true
id = "tk.Brickwall"