From 5f6ba4078707544495e5a8c5c8afc55a7fbddfa6 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Fri, 13 Mar 2026 11:24:59 +0000 Subject: [PATCH 1/5] WIP: In-game push blocks --- in_game_sokoban_test.tscn | 112 ++++++++++++++++++ push_block.gd | 31 +++++ push_block.gd.uid | 1 + push_block.tscn | 36 ++++++ .../characters/player/components/player.gd | 31 +++++ 5 files changed, 211 insertions(+) create mode 100644 in_game_sokoban_test.tscn create mode 100644 push_block.gd create mode 100644 push_block.gd.uid create mode 100644 push_block.tscn diff --git a/in_game_sokoban_test.tscn b/in_game_sokoban_test.tscn new file mode 100644 index 000000000..063d4cc80 --- /dev/null +++ b/in_game_sokoban_test.tscn @@ -0,0 +1,112 @@ +[gd_scene format=4 uid="uid://dkydtkbd0k1nj"] + +[ext_resource type="PackedScene" uid="uid://iu2q66clupc6" path="res://scenes/game_elements/characters/player/player.tscn" id="1_b58vp"] +[ext_resource type="Texture2D" uid="uid://doc4qg7e3kgs" path="res://assets/third_party/tiny-swords/Terrain/Water/Water.png" id="1_u248t"] +[ext_resource type="TileSet" uid="uid://b8qnr0owsbhhn" path="res://tiles/exterior_floors.tres" id="2_6jm70"] +[ext_resource type="TileSet" uid="uid://b778cuoftt88r" path="res://tiles/elevation_2.tres" id="3_ko04g"] +[ext_resource type="TileSet" uid="uid://bjx3gvah0ycl1" path="res://tiles/foam_2.tres" id="3_vlvpl"] +[ext_resource type="SpriteFrames" uid="uid://dtoylirwywk0j" path="res://scenes/game_elements/characters/components/sprite_frames/storyweaver_blue.tres" id="4_ko04g"] +[ext_resource type="Texture2D" uid="uid://c86ayucyybr2t" path="res://scenes/eternal_loom_sokoban/components/wall/walls.png" id="5_6jm70"] +[ext_resource type="PackedScene" uid="uid://040geb1h683b" path="res://push_block.tscn" id="6_ko04g"] +[ext_resource type="PackedScene" uid="uid://fuhl3l6gxq5k" path="res://scenes/game_elements/props/collectible_item/collectible_item.tscn" id="7_jh3jm"] +[ext_resource type="Script" uid="uid://bgmwplmj3bfls" path="res://scenes/globals/game_state/inventory/inventory_item.gd" id="8_cqfek"] + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_o8ekb"] +texture = ExtResource("1_u248t") +texture_region_size = Vector2i(64, 64) +0:0/next_alternative_id = 3 +0:0/0 = 0 +0:0/0/physics_layer_2/polygon_0/points = PackedVector2Array(-32, -32, 32, -32, 32, 32, -32, 32) +0:0/2 = 2 +0:0/2/physics_layer_2/polygon_0/points = PackedVector2Array(-32, 3.85675, 32, 4.40771, 32, 32, -32, 32) +0:0/1 = 1 + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_csc7u"] +texture = ExtResource("5_6jm70") +texture_region_size = Vector2i(64, 64) +0:0/0 = 0 +1:0/0 = 0 + +[sub_resource type="TileSet" id="TileSet_ix036"] +tile_size = Vector2i(64, 64) +occlusion_layer_0/light_mask = 1 +physics_layer_0/collision_layer = 16 +physics_layer_0/collision_mask = 0 +physics_layer_0/collision_priority = 100.0 +physics_layer_1/collision_layer = 8 +physics_layer_1/collision_mask = 0 +physics_layer_2/collision_layer = 512 +physics_layer_2/collision_mask = 0 +sources/0 = SubResource("TileSetAtlasSource_o8ekb") +sources/2 = SubResource("TileSetAtlasSource_csc7u") + +[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_u248t"] +texture = ExtResource("5_6jm70") +texture_region_size = Vector2i(64, 64) +0:0/0 = 0 +1:0/0 = 0 + +[sub_resource type="TileSet" id="TileSet_vlvpl"] +tile_size = Vector2i(64, 64) +sources/0 = SubResource("TileSetAtlasSource_u248t") + +[sub_resource type="Resource" id="Resource_ctuqu"] +script = ExtResource("8_cqfek") +metadata/_custom_type_script = "uid://bgmwplmj3bfls" + +[node name="InGameSokobanTest" type="Node2D" unique_id=414935997] +metadata/_edit_horizontal_guides_ = [1413.0, -146.0] + +[node name="TileMapLayers" type="Node2D" parent="." unique_id=724875691] + +[node name="Water" type="TileMapLayer" parent="TileMapLayers" unique_id=1525083400] +tile_map_data = PackedByteArray("AAADAAQAAAAAAAAAAAADAAUAAAAAAAAAAAADAAYAAAAAAAAAAAAEAAQAAAAAAAAAAAAEAAUAAAAAAAAAAAAEAAYAAAAAAAAAAAAFAAQAAAAAAAAAAAAFAAUAAAAAAAAAAAAFAAYAAAAAAAAAAAAGAAQAAAAAAAAAAAAGAAUAAAAAAAAAAAAGAAYAAAAAAAAAAAAHAAQAAAAAAAAAAAAHAAUAAAAAAAAAAAAHAAYAAAAAAAAAAAAIAAQAAAAAAAAAAAAIAAUAAAAAAAAAAAAIAAYAAAAAAAAAAAAJAAQAAAAAAAAAAAAJAAUAAAAAAAAAAAAJAAYAAAAAAAAAAAAKAAQAAAAAAAAAAAAKAAUAAAAAAAAAAAAKAAYAAAAAAAAAAAALAAQAAAAAAAAAAAALAAUAAAAAAAAAAAALAAYAAAAAAAAAAAAMAAQAAAAAAAAAAAAMAAUAAAAAAAAAAAAMAAYAAAAAAAAAAAANAAQAAAAAAAAAAAANAAUAAAAAAAAAAAANAAYAAAAAAAAAAAAOAAQAAAAAAAAAAAAOAAUAAAAAAAAAAAAOAAYAAAAAAAAAAAAPAAQAAAAAAAAAAAAPAAUAAAAAAAAAAAAPAAYAAAAAAAAAAAAQAAQAAAAAAAAAAAAQAAUAAAAAAAAAAAAQAAYAAAAAAAAAAAARAAQAAAAAAAAAAAARAAUAAAAAAAAAAAARAAYAAAAAAAAAAAASAAQAAAAAAAAAAAASAAUAAAAAAAAAAAASAAYAAAAAAAAAAAATAAQAAAAAAAAAAAATAAUAAAAAAAAAAAATAAYAAAAAAAAAAAAUAAQAAAAAAAAAAAAUAAUAAAAAAAAAAAAUAAYAAAAAAAAAAAAVAAQAAAAAAAAAAAAVAAUAAAAAAAAAAAAVAAYAAAAAAAAAAAAWAAQAAAAAAAAAAAAWAAUAAAAAAAAAAAAWAAYAAAAAAAAAAAAXAAQAAAAAAAAAAAAXAAUAAAAAAAAAAAAXAAYAAAAAAAAAAAAYAAQAAAAAAAAAAAAYAAUAAAAAAAAAAAAYAAYAAAAAAAAAAAAZAAQAAAAAAAAAAAAZAAUAAAAAAAAAAAAZAAYAAAAAAAAAAAAaAAQAAAAAAAAAAAAaAAUAAAAAAAAAAAAaAAYAAAAAAAAAAAAaAAcAAAAAAAAAAAAaAAgAAAAAAAAAAAAaAAkAAAAAAAAAAAAaAAoAAAAAAAAAAAAaAAsAAAAAAAAAAAAaAAwAAAAAAAAAAAAaAA0AAAAAAAAAAAAaAA4AAAAAAAAAAAAaAA8AAAAAAAAAAAAaABAAAAAAAAAAAAAaABEAAAAAAAAAAAAaABIAAAAAAAAAAAAaABMAAAAAAAAAAAAaABQAAAAAAAAAAAAaABUAAAAAAAAAAAAbAAUAAAAAAAAAAAAbAAYAAAAAAAAAAAAbAAcAAAAAAAAAAAAbAAgAAAAAAAAAAAAbAAkAAAAAAAAAAAAbAAoAAAAAAAAAAAAbAAsAAAAAAAAAAAAbAAwAAAAAAAAAAAAbAA0AAAAAAAAAAAAbAA4AAAAAAAAAAAAbAA8AAAAAAAAAAAAbABAAAAAAAAAAAAAbABEAAAAAAAAAAAAbABIAAAAAAAAAAAAbABMAAAAAAAAAAAAbABQAAAAAAAAAAAAbABUAAAAAAAAAAAADABUAAAAAAAAAAAADABYAAAAAAAAAAAAEABUAAAAAAAAAAAAEABYAAAAAAAAAAAAFABUAAAAAAAAAAAAFABYAAAAAAAAAAAAGABUAAAAAAAAAAAAGABYAAAAAAAAAAAAHABUAAAAAAAAAAAAHABYAAAAAAAAAAAAIABUAAAAAAAAAAAAIABYAAAAAAAAAAAAJABUAAAAAAAAAAAAJABYAAAAAAAAAAAAKABUAAAAAAAAAAAAKABYAAAAAAAAAAAALABUAAAAAAAAAAAALABYAAAAAAAAAAAAMABUAAAAAAAAAAAAMABYAAAAAAAAAAAANABUAAAAAAAAAAAANABYAAAAAAAAAAAAOABUAAAAAAAAAAAAOABYAAAAAAAAAAAAPABUAAAAAAAAAAAAPABYAAAAAAAAAAAAQABUAAAAAAAAAAAAQABYAAAAAAAAAAAARABUAAAAAAAAAAAARABYAAAAAAAAAAAASABUAAAAAAAAAAAASABYAAAAAAAAAAAATABUAAAAAAAAAAAATABYAAAAAAAAAAAAUABUAAAAAAAAAAAAUABYAAAAAAAAAAAAVABUAAAAAAAAAAAAVABYAAAAAAAAAAAAWABUAAAAAAAAAAAAWABYAAAAAAAAAAAAXABUAAAAAAAAAAAAXABYAAAAAAAAAAAAYABUAAAAAAAAAAAAYABYAAAAAAAAAAAAZABUAAAAAAAAAAAAZABYAAAAAAAAAAAAaABYAAAAAAAAAAAAbABYAAAAAAAAAAAADAAcAAAAAAAAAAAADAAgAAAAAAAAAAAADAAkAAAAAAAAAAAADAAoAAAAAAAAAAAADAAsAAAAAAAAAAAADAAwAAAAAAAAAAAADAA0AAAAAAAAAAAADAA4AAAAAAAAAAAADAA8AAAAAAAAAAAADABAAAAAAAAAAAAADABEAAAAAAAAAAAADABIAAAAAAAAAAAADABMAAAAAAAAAAAADABQAAAAAAAAAAAAEAAcAAAAAAAAAAAAEAAgAAAAAAAAAAAAEAAkAAAAAAAAAAAAEAAoAAAAAAAAAAAAEAAsAAAAAAAAAAAAEAAwAAAAAAAAAAAAEAA0AAAAAAAAAAAAEAA4AAAAAAAAAAAAEAA8AAAAAAAAAAAAEABAAAAAAAAAAAAAEABEAAAAAAAAAAAAEABIAAAAAAAAAAAAEABMAAAAAAAAAAAAEABQAAAAAAAAAAAATAAcAAAAAAAAAAAATAAgAAAAAAAAAAAATAAkAAAAAAAAAAAATAAoAAAAAAAAAAAATAAsAAAAAAAAAAAATAAwAAAAAAAAAAAATAA0AAAAAAAAAAAATAA4AAAAAAAAAAAATAA8AAAAAAAAAAAATABAAAAAAAAAAAAATABEAAAAAAAAAAAATABIAAAAAAAAAAAATABMAAAAAAAAAAAATABQAAAAAAAAAAAAUAAcAAAAAAAAAAAAUAAgAAAAAAAAAAAAUAAkAAAAAAAAAAAAUAAoAAAAAAAAAAAAUAAsAAAAAAAAAAAAUAAwAAAAAAAAAAAAUAA0AAAAAAAAAAAAUAA4AAAAAAAAAAAAUAA8AAAAAAAAAAAAUABAAAAAAAAAAAAAUABEAAAAAAAAAAAAUABIAAAAAAAAAAAAUABMAAAAAAAAAAAAUABQAAAAAAAAAAAA=") +tile_set = SubResource("TileSet_ix036") +physics_quadrant_size = 1 + +[node name="Foam" type="TileMapLayer" parent="TileMapLayers" unique_id=988001185] +tile_map_data = PackedByteArray("AAAFAAcAAgAAAAAAAAAGAAcAAgAAAAAAAAAHAAcAAgAAAAAAAAAIAAcAAgAAAAAAAAAJAAcAAgAAAAAAAAAKAAcAAgAAAAAAAAALAAcAAgAAAAAAAAAMAAcAAgAAAAAAAAANAAcAAgAAAAAAAAAOAAcAAgAAAAAAAAAPAAcAAgAAAAAAAAAQAAcAAgAAAAAAAAARAAcAAgAAAAAAAAASAAcAAgAAAAAAAAASAAgAAgAAAAAAAAASAAkAAgAAAAAAAAASAAoAAgAAAAAAAAASAAsAAgAAAAAAAAASAAwAAgAAAAAAAAASAA0AAgAAAAAAAAASAA4AAgAAAAAAAAASAA8AAgAAAAAAAAASABAAAgAAAAAAAAASABEAAgAAAAAAAAASABIAAgAAAAAAAAASABMAAgAAAAAAAAASABQAAgAAAAAAAAAFABQAAgAAAAAAAAAGABQAAgAAAAAAAAAHABQAAgAAAAAAAAAIABQAAgAAAAAAAAAJABQAAgAAAAAAAAAKABQAAgAAAAAAAAALABQAAgAAAAAAAAAMABQAAgAAAAAAAAANABQAAgAAAAAAAAAOABQAAgAAAAAAAAAPABQAAgAAAAAAAAAQABQAAgAAAAAAAAARABQAAgAAAAAAAAAFAAgAAgAAAAAAAAAFAAkAAgAAAAAAAAAFAAoAAgAAAAAAAAAFAAsAAgAAAAAAAAAFAAwAAgAAAAAAAAAFAA0AAgAAAAAAAAAFAA4AAgAAAAAAAAAFAA8AAgAAAAAAAAAFABAAAgAAAAAAAAAFABEAAgAAAAAAAAAFABIAAgAAAAAAAAAFABMAAgAAAAAAAAAVAAcAAgAAAAAAAAAWAAcAAgAAAAAAAAAXAAcAAgAAAAAAAAAYAAcAAgAAAAAAAAAZAAcAAgAAAAAAAAAZAAgAAgAAAAAAAAAZAAkAAgAAAAAAAAAZAAoAAgAAAAAAAAAZAAsAAgAAAAAAAAAZAAwAAgAAAAAAAAAZAA0AAgAAAAAAAAAZAA4AAgAAAAAAAAAZAA8AAgAAAAAAAAAZABAAAgAAAAAAAAAZABEAAgAAAAAAAAAZABIAAgAAAAAAAAAZABMAAgAAAAAAAAAZABQAAgAAAAAAAAAVABQAAgAAAAAAAAAWABQAAgAAAAAAAAAXABQAAgAAAAAAAAAYABQAAgAAAAAAAAAVAAgAAgAAAAAAAAAVAAkAAgAAAAAAAAAVAAoAAgAAAAAAAAAVAAsAAgAAAAAAAAAVAAwAAgAAAAAAAAAVAA0AAgAAAAAAAAAVAA4AAgAAAAAAAAAVAA8AAgAAAAAAAAAVABAAAgAAAAAAAAAVABEAAgAAAAAAAAAVABIAAgAAAAAAAAAVABMAAgAAAAAAAAA=") +tile_set = ExtResource("3_vlvpl") + +[node name="SubmergedBlocks" type="TileMapLayer" parent="TileMapLayers" unique_id=441634037] +tile_set = SubResource("TileSet_vlvpl") + +[node name="Grass" type="TileMapLayer" parent="TileMapLayers" unique_id=1539200401] +tile_map_data = PackedByteArray("AAAZABQAAQACAAIAAAAZABMAAQACAAEAAAAZABIAAQACAAEAAAAZABEAAQACAAEAAAAZABAAAQACAAEAAAAZAA8AAQACAAEAAAAZAA4AAQACAAEAAAAZAA0AAQACAAEAAAAZAAwAAQACAAEAAAAZAAsAAQACAAEAAAAZAAoAAQACAAEAAAAZAAkAAQACAAEAAAAZAAgAAQACAAEAAAAZAAcAAQACAAAAAAAYABQAAQABAAIAAAAYABMAAQABAAEAAAAYABIAAQABAAEAAAAYABEAAQABAAEAAAAYABAAAQABAAEAAAAYAA8AAQABAAEAAAAYAA4AAQABAAEAAAAYAA0AAQABAAEAAAAYAAwAAQABAAEAAAAYAAsAAQABAAEAAAAYAAoAAQABAAEAAAAYAAkAAQABAAEAAAAYAAgAAQABAAEAAAAYAAcAAQABAAAAAAAXABQAAQABAAIAAAAXABMAAQABAAEAAAAXABIAAQABAAEAAAAXABEAAQABAAEAAAAXABAAAQABAAEAAAAXAA8AAQABAAEAAAAXAA4AAQABAAEAAAAXAA0AAQABAAEAAAAXAAwAAQABAAEAAAAXAAsAAQABAAEAAAAXAAoAAQABAAEAAAAXAAkAAQABAAEAAAAXAAgAAQABAAEAAAAXAAcAAQABAAAAAAAWABQAAQABAAIAAAAWABMAAQABAAEAAAAWABIAAQABAAEAAAAWABEAAQABAAEAAAAWABAAAQABAAEAAAAWAA8AAQABAAEAAAAWAA4AAQABAAEAAAAWAA0AAQABAAEAAAAWAAwAAQABAAEAAAAWAAsAAQABAAEAAAAWAAoAAQABAAEAAAAWAAkAAQABAAEAAAAWAAgAAQABAAEAAAAWAAcAAQABAAAAAAAVABQAAQAAAAIAAAAVABMAAQAAAAEAAAAVABIAAQAAAAEAAAAVABEAAQAAAAEAAAAVABAAAQAAAAEAAAAVAA8AAQAAAAEAAAAVAA4AAQAAAAEAAAAVAA0AAQAAAAEAAAAVAAwAAQAAAAEAAAAVAAsAAQAAAAEAAAAVAAoAAQAAAAEAAAAVAAkAAQAAAAEAAAAVAAgAAQAAAAEAAAAVAAcAAQAAAAAAAAASABQAAQACAAIAAAASABMAAQACAAEAAAASABIAAQACAAEAAAASABEAAQACAAEAAAASABAAAQACAAEAAAASAA8AAQACAAEAAAASAA4AAQACAAEAAAASAA0AAQACAAEAAAASAAwAAQACAAEAAAASAAsAAQACAAEAAAASAAoAAQACAAEAAAASAAkAAQACAAEAAAASAAgAAQACAAEAAAASAAcAAQACAAAAAAARABQAAQABAAIAAAARABMAAQABAAEAAAARABIAAQABAAEAAAARABEAAQABAAEAAAARABAAAQABAAEAAAARAA8AAQABAAEAAAARAA4AAQABAAEAAAARAA0AAQABAAEAAAARAAwAAQABAAEAAAARAAsAAQABAAEAAAARAAoAAQABAAEAAAARAAkAAQABAAEAAAARAAgAAQABAAEAAAARAAcAAQABAAAAAAAQABQAAQABAAIAAAAQABMAAQABAAEAAAAQABIAAQABAAEAAAAQABEAAQABAAEAAAAQABAAAQABAAEAAAAQAA8AAQABAAEAAAAQAA4AAQABAAEAAAAQAA0AAQABAAEAAAAQAAwAAQABAAEAAAAQAAsAAQABAAEAAAAQAAoAAQABAAEAAAAQAAkAAQABAAEAAAAQAAgAAQABAAEAAAAQAAcAAQABAAAAAAAPABQAAQABAAIAAAAPABMAAQABAAEAAAAPABIAAQABAAEAAAAPABEAAQABAAEAAAAPABAAAQABAAEAAAAPAA8AAQABAAEAAAAPAA4AAQABAAEAAAAPAA0AAQABAAEAAAAPAAwAAQABAAEAAAAPAAsAAQABAAEAAAAPAAoAAQABAAEAAAAPAAkAAQABAAEAAAAPAAgAAQABAAEAAAAPAAcAAQABAAAAAAAOABQAAQABAAIAAAAOABMAAQABAAEAAAAOABIAAQABAAEAAAAOABEAAQABAAEAAAAOABAAAQABAAEAAAAOAA8AAQABAAEAAAAOAA4AAQABAAEAAAAOAA0AAQABAAEAAAAOAAwAAQABAAEAAAAOAAsAAQABAAEAAAAOAAoAAQABAAEAAAAOAAkAAQABAAEAAAAOAAgAAQABAAEAAAAOAAcAAQABAAAAAAANABQAAQABAAIAAAANABMAAQABAAEAAAANABIAAQABAAEAAAANABEAAQABAAEAAAANABAAAQABAAEAAAANAA8AAQABAAEAAAANAA4AAQABAAEAAAANAA0AAQABAAEAAAANAAwAAQABAAEAAAANAAsAAQABAAEAAAANAAoAAQABAAEAAAANAAkAAQABAAEAAAANAAgAAQABAAEAAAANAAcAAQABAAAAAAAMABQAAQABAAIAAAAMABMAAQABAAEAAAAMABIAAQABAAEAAAAMABEAAQABAAEAAAAMABAAAQABAAEAAAAMAA8AAQABAAEAAAAMAA4AAQABAAEAAAAMAA0AAQABAAEAAAAMAAwAAQABAAEAAAAMAAsAAQABAAEAAAAMAAoAAQABAAEAAAAMAAkAAQABAAEAAAAMAAgAAQABAAEAAAAMAAcAAQABAAAAAAALABQAAQABAAIAAAALABMAAQABAAEAAAALABIAAQABAAEAAAALABEAAQABAAEAAAALABAAAQABAAEAAAALAA8AAQABAAEAAAALAA4AAQABAAEAAAALAA0AAQABAAEAAAALAAwAAQABAAEAAAALAAsAAQABAAEAAAALAAoAAQABAAEAAAALAAkAAQABAAEAAAALAAgAAQABAAEAAAALAAcAAQABAAAAAAAKABQAAQABAAIAAAAKABMAAQABAAEAAAAKABIAAQABAAEAAAAKABEAAQABAAEAAAAKABAAAQABAAEAAAAKAA8AAQABAAEAAAAKAA4AAQABAAEAAAAKAA0AAQABAAEAAAAKAAwAAQABAAEAAAAKAAsAAQABAAEAAAAKAAoAAQABAAEAAAAKAAkAAQABAAEAAAAKAAgAAQABAAEAAAAKAAcAAQABAAAAAAAJABQAAQABAAIAAAAJABMAAQABAAEAAAAJABIAAQABAAEAAAAJABEAAQABAAEAAAAJABAAAQABAAEAAAAJAA8AAQABAAEAAAAJAA4AAQABAAEAAAAJAA0AAQABAAEAAAAJAAwAAQABAAEAAAAJAAsAAQABAAEAAAAJAAoAAQABAAEAAAAJAAkAAQABAAEAAAAJAAgAAQABAAEAAAAJAAcAAQABAAAAAAAIABQAAQABAAIAAAAIABMAAQABAAEAAAAIABIAAQABAAEAAAAIABEAAQABAAEAAAAIABAAAQABAAEAAAAIAA8AAQABAAEAAAAIAA4AAQABAAEAAAAIAA0AAQABAAEAAAAIAAwAAQABAAEAAAAIAAsAAQABAAEAAAAIAAoAAQABAAEAAAAIAAkAAQABAAEAAAAIAAgAAQABAAEAAAAIAAcAAQABAAAAAAAHABQAAQABAAIAAAAHABMAAQABAAEAAAAHABIAAQABAAEAAAAHABEAAQABAAEAAAAHABAAAQABAAEAAAAHAA8AAQABAAEAAAAHAA4AAQABAAEAAAAHAA0AAQABAAEAAAAHAAwAAQABAAEAAAAHAAsAAQABAAEAAAAHAAoAAQABAAEAAAAHAAkAAQABAAEAAAAHAAgAAQABAAEAAAAHAAcAAQABAAAAAAAGABQAAQABAAIAAAAGABMAAQABAAEAAAAGABIAAQABAAEAAAAGABEAAQABAAEAAAAGABAAAQABAAEAAAAGAA8AAQABAAEAAAAGAA4AAQABAAEAAAAGAA0AAQABAAEAAAAGAAwAAQABAAEAAAAGAAsAAQABAAEAAAAGAAoAAQABAAEAAAAGAAkAAQABAAEAAAAGAAgAAQABAAEAAAAGAAcAAQABAAAAAAAFABQAAQAAAAIAAAAFABMAAQAAAAEAAAAFABIAAQAAAAEAAAAFABEAAQAAAAEAAAAFABAAAQAAAAEAAAAFAA8AAQAAAAEAAAAFAA4AAQAAAAEAAAAFAA0AAQAAAAEAAAAFAAwAAQAAAAEAAAAFAAsAAQAAAAEAAAAFAAoAAQAAAAEAAAAFAAkAAQAAAAEAAAAFAAgAAQAAAAEAAAAFAAcAAQAAAAAAAAA=") +tile_set = ExtResource("2_6jm70") + +[node name="Cliffs" type="TileMapLayer" parent="TileMapLayers" unique_id=20831420] +tile_map_data = PackedByteArray("AAARAA0ABAABAAIAAAARAAwABAACAAAAAAAQAA0ABAABAAIAAAAQAAwABAABAAAAAAAPAA0ABAAAAAIAAAAPAAwABAAAAAAAAAARABMABAABAAIAAAARABIABAABAAEAAAARABEABAABAAAAAAAQABMABAABAAIAAAAQABIABAABAAEAAAAQABEABAABAAAAAAAPABMABAAAAAIAAAAPABIABAAAAAEAAAAPABEABAABAAAAAAAOABEABAABAAQAAAANABEABAABAAQAAAAMABEABAAAAAQAAAASABMABAACAAIAAAASABIABAACAAEAAAASABEABAACAAAAAAASAA0ABAACAAQAAAA=") +tile_set = ExtResource("3_ko04g") + +[node name="OnTheGround" type="Node2D" parent="." unique_id=719461425] +y_sort_enabled = true + +[node name="Player" parent="OnTheGround" unique_id=296354958 instance=ExtResource("1_b58vp")] +position = Vector2(715, 831) +player_name = "StoryWeaver" +sprite_frames = ExtResource("4_ko04g") + +[node name="Camera2D" type="Camera2D" parent="OnTheGround/Player" unique_id=1941828126] +limit_left = 262 +limit_top = 400 +limit_right = 1700 +limit_bottom = 1400 +editor_draw_limits = true + +[node name="PushBlock" parent="OnTheGround" unique_id=1349233887 node_paths=PackedStringArray("foam", "submerged_blocks") instance=ExtResource("6_ko04g")] +position = Vector2(882, 894) +foam = NodePath("../../TileMapLayers/Foam") +submerged_blocks = NodePath("../../TileMapLayers/SubmergedBlocks") + +[node name="PushBlock2" parent="OnTheGround" unique_id=357032112 node_paths=PackedStringArray("foam", "submerged_blocks") instance=ExtResource("6_ko04g")] +position = Vector2(720, 958) +collision_mask = 275 +foam = NodePath("../../TileMapLayers/Foam") +submerged_blocks = NodePath("../../TileMapLayers/SubmergedBlocks") + +[node name="CollectibleItem" parent="OnTheGround" unique_id=327991066 instance=ExtResource("7_jh3jm")] +position = Vector2(1499, 1008) +item = SubResource("Resource_ctuqu") + +[node name="ScreenOverlay" type="CanvasLayer" parent="." unique_id=1967906375] diff --git a/push_block.gd b/push_block.gd new file mode 100644 index 000000000..7376b2914 --- /dev/null +++ b/push_block.gd @@ -0,0 +1,31 @@ +extends CharacterBody2D + +@export var foam: TileMapLayer +@export var submerged_blocks: TileMapLayer + + +func _on_area_2d_body_shape_entered( + body_rid: RID, + body: Node2D, + _body_shape_index: int, + _local_shape_index: int, +) -> void: + var tile_map := body as TileMapLayer + if not tile_map: + return + + # For this to work, the water layer's physics quadrant size has to be set to + # 1, i.e. no chunking of water physics - probably bad for performance... + var coords := tile_map.get_coords_for_body_rid(body_rid) + # This doesn't work because at the point when the 1×1px area in the centre of a block travelling rightwards touches a block of water at (x, y), its centre is still in tile (x - 1, y). + # var coords := tile_map.local_to_map(tile_map.to_local(global_position)) + # Erase the water + tile_map.set_cell(coords, -1) + # Add foam + foam.set_cell(coords, 2, Vector2i(0, 0)) + # Put a static copy of this block into the water + submerged_blocks.set_cell(coords, 0, Vector2i(1, 0)) + # Free the physical block + queue_free() + # TODO: sound-effect + # TODO: do this more convincingly! diff --git a/push_block.gd.uid b/push_block.gd.uid new file mode 100644 index 000000000..8ebdf8b49 --- /dev/null +++ b/push_block.gd.uid @@ -0,0 +1 @@ +uid://bxulfsreyu63i diff --git a/push_block.tscn b/push_block.tscn new file mode 100644 index 000000000..fd2b1b369 --- /dev/null +++ b/push_block.tscn @@ -0,0 +1,36 @@ +[gd_scene format=3 uid="uid://040geb1h683b"] + +[ext_resource type="Script" uid="uid://bxulfsreyu63i" path="res://push_block.gd" id="1_jmvaw"] +[ext_resource type="Texture2D" uid="uid://c86ayucyybr2t" path="res://scenes/eternal_loom_sokoban/components/wall/walls.png" id="2_byqtm"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_ko04g"] +atlas = ExtResource("2_byqtm") +region = Rect2(64, 0, 64, 64) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_6jm70"] +size = Vector2(64, 64) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_cqfek"] +size = Vector2(1, 1) + +[node name="PushBlock" type="CharacterBody2D" unique_id=1349233887] +collision_mask = 274 +motion_mode = 1 +script = ExtResource("1_jmvaw") + +[node name="Sprite2D" type="Sprite2D" parent="." unique_id=448744553] +texture = SubResource("AtlasTexture_ko04g") +metadata/_edit_lock_ = true + +[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1387816029] +shape = SubResource("RectangleShape2D_6jm70") +metadata/_edit_lock_ = true + +[node name="WaterDetector" type="Area2D" parent="." unique_id=222932605] +collision_layer = 0 +collision_mask = 512 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="WaterDetector" unique_id=1457035837] +shape = SubResource("RectangleShape2D_cqfek") + +[connection signal="body_shape_entered" from="WaterDetector" to="." method="_on_area_2d_body_shape_entered"] diff --git a/scenes/game_elements/characters/player/components/player.gd b/scenes/game_elements/characters/player/components/player.gd index fb1bf2384..6c808f6fb 100644 --- a/scenes/game_elements/characters/player/components/player.gd +++ b/scenes/game_elements/characters/player/components/player.gd @@ -74,6 +74,14 @@ const DEFAULT_SPRITE_FRAME: SpriteFrames = preload("uid://vwf8e1v8brdp") var input_vector: Vector2 +# Storing this is cribbed from top_down_push_ship_player_2d.gd in GDQuest's Node +# Essentials course. TODO: I don't understand why this is necessary, and in my +# implementation the player "sticks" to the block for 1 frame when they walk +# away, dragging the block with them. +var _pushing_block: CharacterBody2D +var _pushing_direction: Vector2 +var _detach_distance: float + @onready var player_interaction: PlayerInteraction = %PlayerInteraction @onready var player_fighting: Node2D = %PlayerFighting @onready var player_hook: PlayerHook = %PlayerHook @@ -201,8 +209,31 @@ func _physics_process(delta: float) -> void: ) velocity = velocity.move_toward(input_vector, step * delta) + if is_instance_valid(_pushing_block): + _pushing_block.velocity = velocity + _pushing_block.move_and_slide() + move_and_slide() + _push_block() + + +func _push_block() -> void: + for i: int in get_slide_collision_count(): + var collision := get_slide_collision(i) + var collider := collision.get_collider() as CharacterBody2D + if collider: + _pushing_block = collider + # TODO: quantize to cardinal direction? + _pushing_direction = input_vector + _detach_distance = global_position.distance_to(collider.global_position) + 1.0 + break + + if _pushing_block: + var distance := global_position.distance_to(_pushing_block.global_position) + if input_vector != _pushing_direction or distance > _detach_distance: + _pushing_block = null + func teleport_to( tele_position: Vector2, From b21e6e486010f11dc901e68090186fb921af1baa Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Fri, 13 Mar 2026 12:03:25 +0000 Subject: [PATCH 2/5] It's a tree --- in_game_sokoban_test.tscn | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/in_game_sokoban_test.tscn b/in_game_sokoban_test.tscn index 063d4cc80..b05b3161a 100644 --- a/in_game_sokoban_test.tscn +++ b/in_game_sokoban_test.tscn @@ -10,6 +10,7 @@ [ext_resource type="PackedScene" uid="uid://040geb1h683b" path="res://push_block.tscn" id="6_ko04g"] [ext_resource type="PackedScene" uid="uid://fuhl3l6gxq5k" path="res://scenes/game_elements/props/collectible_item/collectible_item.tscn" id="7_jh3jm"] [ext_resource type="Script" uid="uid://bgmwplmj3bfls" path="res://scenes/globals/game_state/inventory/inventory_item.gd" id="8_cqfek"] +[ext_resource type="PackedScene" uid="uid://7873qa54birk" path="res://scenes/game_elements/props/tree/tree.tscn" id="11_vlvpl"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_o8ekb"] texture = ExtResource("1_u248t") @@ -109,4 +110,8 @@ submerged_blocks = NodePath("../../TileMapLayers/SubmergedBlocks") position = Vector2(1499, 1008) item = SubResource("Resource_ctuqu") +[node name="Tree" parent="OnTheGround" unique_id=1182216860 instance=ExtResource("11_vlvpl")] +position = Vector2(878.00006, 767) +scale = Vector2(0.90073115, 0.98537934) + [node name="ScreenOverlay" type="CanvasLayer" parent="." unique_id=1967906375] From 0d46b22f52f64c4434e0267068c657156f9b2c25 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Fri, 13 Mar 2026 12:04:53 +0000 Subject: [PATCH 3/5] Place blocks with TileSet --- in_game_sokoban_test.tscn | 24 ++++++++++-------------- push_block.gd | 7 +++++++ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/in_game_sokoban_test.tscn b/in_game_sokoban_test.tscn index b05b3161a..1f0ee222d 100644 --- a/in_game_sokoban_test.tscn +++ b/in_game_sokoban_test.tscn @@ -42,14 +42,20 @@ sources/0 = SubResource("TileSetAtlasSource_o8ekb") sources/2 = SubResource("TileSetAtlasSource_csc7u") [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_u248t"] +resource_name = "Submerged Blocks" texture = ExtResource("5_6jm70") texture_region_size = Vector2i(64, 64) 0:0/0 = 0 1:0/0 = 0 +[sub_resource type="TileSetScenesCollectionSource" id="TileSetScenesCollectionSource_vlvpl"] +resource_name = "Pushable Blocks" +scenes/1/scene = ExtResource("6_ko04g") + [sub_resource type="TileSet" id="TileSet_vlvpl"] tile_size = Vector2i(64, 64) sources/0 = SubResource("TileSetAtlasSource_u248t") +sources/1 = SubResource("TileSetScenesCollectionSource_vlvpl") [sub_resource type="Resource" id="Resource_ctuqu"] script = ExtResource("8_cqfek") @@ -69,13 +75,14 @@ physics_quadrant_size = 1 tile_map_data = PackedByteArray("AAAFAAcAAgAAAAAAAAAGAAcAAgAAAAAAAAAHAAcAAgAAAAAAAAAIAAcAAgAAAAAAAAAJAAcAAgAAAAAAAAAKAAcAAgAAAAAAAAALAAcAAgAAAAAAAAAMAAcAAgAAAAAAAAANAAcAAgAAAAAAAAAOAAcAAgAAAAAAAAAPAAcAAgAAAAAAAAAQAAcAAgAAAAAAAAARAAcAAgAAAAAAAAASAAcAAgAAAAAAAAASAAgAAgAAAAAAAAASAAkAAgAAAAAAAAASAAoAAgAAAAAAAAASAAsAAgAAAAAAAAASAAwAAgAAAAAAAAASAA0AAgAAAAAAAAASAA4AAgAAAAAAAAASAA8AAgAAAAAAAAASABAAAgAAAAAAAAASABEAAgAAAAAAAAASABIAAgAAAAAAAAASABMAAgAAAAAAAAASABQAAgAAAAAAAAAFABQAAgAAAAAAAAAGABQAAgAAAAAAAAAHABQAAgAAAAAAAAAIABQAAgAAAAAAAAAJABQAAgAAAAAAAAAKABQAAgAAAAAAAAALABQAAgAAAAAAAAAMABQAAgAAAAAAAAANABQAAgAAAAAAAAAOABQAAgAAAAAAAAAPABQAAgAAAAAAAAAQABQAAgAAAAAAAAARABQAAgAAAAAAAAAFAAgAAgAAAAAAAAAFAAkAAgAAAAAAAAAFAAoAAgAAAAAAAAAFAAsAAgAAAAAAAAAFAAwAAgAAAAAAAAAFAA0AAgAAAAAAAAAFAA4AAgAAAAAAAAAFAA8AAgAAAAAAAAAFABAAAgAAAAAAAAAFABEAAgAAAAAAAAAFABIAAgAAAAAAAAAFABMAAgAAAAAAAAAVAAcAAgAAAAAAAAAWAAcAAgAAAAAAAAAXAAcAAgAAAAAAAAAYAAcAAgAAAAAAAAAZAAcAAgAAAAAAAAAZAAgAAgAAAAAAAAAZAAkAAgAAAAAAAAAZAAoAAgAAAAAAAAAZAAsAAgAAAAAAAAAZAAwAAgAAAAAAAAAZAA0AAgAAAAAAAAAZAA4AAgAAAAAAAAAZAA8AAgAAAAAAAAAZABAAAgAAAAAAAAAZABEAAgAAAAAAAAAZABIAAgAAAAAAAAAZABMAAgAAAAAAAAAZABQAAgAAAAAAAAAVABQAAgAAAAAAAAAWABQAAgAAAAAAAAAXABQAAgAAAAAAAAAYABQAAgAAAAAAAAAVAAgAAgAAAAAAAAAVAAkAAgAAAAAAAAAVAAoAAgAAAAAAAAAVAAsAAgAAAAAAAAAVAAwAAgAAAAAAAAAVAA0AAgAAAAAAAAAVAA4AAgAAAAAAAAAVAA8AAgAAAAAAAAAVABAAAgAAAAAAAAAVABEAAgAAAAAAAAAVABIAAgAAAAAAAAAVABMAAgAAAAAAAAA=") tile_set = ExtResource("3_vlvpl") -[node name="SubmergedBlocks" type="TileMapLayer" parent="TileMapLayers" unique_id=441634037] -tile_set = SubResource("TileSet_vlvpl") - [node name="Grass" type="TileMapLayer" parent="TileMapLayers" unique_id=1539200401] tile_map_data = PackedByteArray("AAAZABQAAQACAAIAAAAZABMAAQACAAEAAAAZABIAAQACAAEAAAAZABEAAQACAAEAAAAZABAAAQACAAEAAAAZAA8AAQACAAEAAAAZAA4AAQACAAEAAAAZAA0AAQACAAEAAAAZAAwAAQACAAEAAAAZAAsAAQACAAEAAAAZAAoAAQACAAEAAAAZAAkAAQACAAEAAAAZAAgAAQACAAEAAAAZAAcAAQACAAAAAAAYABQAAQABAAIAAAAYABMAAQABAAEAAAAYABIAAQABAAEAAAAYABEAAQABAAEAAAAYABAAAQABAAEAAAAYAA8AAQABAAEAAAAYAA4AAQABAAEAAAAYAA0AAQABAAEAAAAYAAwAAQABAAEAAAAYAAsAAQABAAEAAAAYAAoAAQABAAEAAAAYAAkAAQABAAEAAAAYAAgAAQABAAEAAAAYAAcAAQABAAAAAAAXABQAAQABAAIAAAAXABMAAQABAAEAAAAXABIAAQABAAEAAAAXABEAAQABAAEAAAAXABAAAQABAAEAAAAXAA8AAQABAAEAAAAXAA4AAQABAAEAAAAXAA0AAQABAAEAAAAXAAwAAQABAAEAAAAXAAsAAQABAAEAAAAXAAoAAQABAAEAAAAXAAkAAQABAAEAAAAXAAgAAQABAAEAAAAXAAcAAQABAAAAAAAWABQAAQABAAIAAAAWABMAAQABAAEAAAAWABIAAQABAAEAAAAWABEAAQABAAEAAAAWABAAAQABAAEAAAAWAA8AAQABAAEAAAAWAA4AAQABAAEAAAAWAA0AAQABAAEAAAAWAAwAAQABAAEAAAAWAAsAAQABAAEAAAAWAAoAAQABAAEAAAAWAAkAAQABAAEAAAAWAAgAAQABAAEAAAAWAAcAAQABAAAAAAAVABQAAQAAAAIAAAAVABMAAQAAAAEAAAAVABIAAQAAAAEAAAAVABEAAQAAAAEAAAAVABAAAQAAAAEAAAAVAA8AAQAAAAEAAAAVAA4AAQAAAAEAAAAVAA0AAQAAAAEAAAAVAAwAAQAAAAEAAAAVAAsAAQAAAAEAAAAVAAoAAQAAAAEAAAAVAAkAAQAAAAEAAAAVAAgAAQAAAAEAAAAVAAcAAQAAAAAAAAASABQAAQACAAIAAAASABMAAQACAAEAAAASABIAAQACAAEAAAASABEAAQACAAEAAAASABAAAQACAAEAAAASAA8AAQACAAEAAAASAA4AAQACAAEAAAASAA0AAQACAAEAAAASAAwAAQACAAEAAAASAAsAAQACAAEAAAASAAoAAQACAAEAAAASAAkAAQACAAEAAAASAAgAAQACAAEAAAASAAcAAQACAAAAAAARABQAAQABAAIAAAARABMAAQABAAEAAAARABIAAQABAAEAAAARABEAAQABAAEAAAARABAAAQABAAEAAAARAA8AAQABAAEAAAARAA4AAQABAAEAAAARAA0AAQABAAEAAAARAAwAAQABAAEAAAARAAsAAQABAAEAAAARAAoAAQABAAEAAAARAAkAAQABAAEAAAARAAgAAQABAAEAAAARAAcAAQABAAAAAAAQABQAAQABAAIAAAAQABMAAQABAAEAAAAQABIAAQABAAEAAAAQABEAAQABAAEAAAAQABAAAQABAAEAAAAQAA8AAQABAAEAAAAQAA4AAQABAAEAAAAQAA0AAQABAAEAAAAQAAwAAQABAAEAAAAQAAsAAQABAAEAAAAQAAoAAQABAAEAAAAQAAkAAQABAAEAAAAQAAgAAQABAAEAAAAQAAcAAQABAAAAAAAPABQAAQABAAIAAAAPABMAAQABAAEAAAAPABIAAQABAAEAAAAPABEAAQABAAEAAAAPABAAAQABAAEAAAAPAA8AAQABAAEAAAAPAA4AAQABAAEAAAAPAA0AAQABAAEAAAAPAAwAAQABAAEAAAAPAAsAAQABAAEAAAAPAAoAAQABAAEAAAAPAAkAAQABAAEAAAAPAAgAAQABAAEAAAAPAAcAAQABAAAAAAAOABQAAQABAAIAAAAOABMAAQABAAEAAAAOABIAAQABAAEAAAAOABEAAQABAAEAAAAOABAAAQABAAEAAAAOAA8AAQABAAEAAAAOAA4AAQABAAEAAAAOAA0AAQABAAEAAAAOAAwAAQABAAEAAAAOAAsAAQABAAEAAAAOAAoAAQABAAEAAAAOAAkAAQABAAEAAAAOAAgAAQABAAEAAAAOAAcAAQABAAAAAAANABQAAQABAAIAAAANABMAAQABAAEAAAANABIAAQABAAEAAAANABEAAQABAAEAAAANABAAAQABAAEAAAANAA8AAQABAAEAAAANAA4AAQABAAEAAAANAA0AAQABAAEAAAANAAwAAQABAAEAAAANAAsAAQABAAEAAAANAAoAAQABAAEAAAANAAkAAQABAAEAAAANAAgAAQABAAEAAAANAAcAAQABAAAAAAAMABQAAQABAAIAAAAMABMAAQABAAEAAAAMABIAAQABAAEAAAAMABEAAQABAAEAAAAMABAAAQABAAEAAAAMAA8AAQABAAEAAAAMAA4AAQABAAEAAAAMAA0AAQABAAEAAAAMAAwAAQABAAEAAAAMAAsAAQABAAEAAAAMAAoAAQABAAEAAAAMAAkAAQABAAEAAAAMAAgAAQABAAEAAAAMAAcAAQABAAAAAAALABQAAQABAAIAAAALABMAAQABAAEAAAALABIAAQABAAEAAAALABEAAQABAAEAAAALABAAAQABAAEAAAALAA8AAQABAAEAAAALAA4AAQABAAEAAAALAA0AAQABAAEAAAALAAwAAQABAAEAAAALAAsAAQABAAEAAAALAAoAAQABAAEAAAALAAkAAQABAAEAAAALAAgAAQABAAEAAAALAAcAAQABAAAAAAAKABQAAQABAAIAAAAKABMAAQABAAEAAAAKABIAAQABAAEAAAAKABEAAQABAAEAAAAKABAAAQABAAEAAAAKAA8AAQABAAEAAAAKAA4AAQABAAEAAAAKAA0AAQABAAEAAAAKAAwAAQABAAEAAAAKAAsAAQABAAEAAAAKAAoAAQABAAEAAAAKAAkAAQABAAEAAAAKAAgAAQABAAEAAAAKAAcAAQABAAAAAAAJABQAAQABAAIAAAAJABMAAQABAAEAAAAJABIAAQABAAEAAAAJABEAAQABAAEAAAAJABAAAQABAAEAAAAJAA8AAQABAAEAAAAJAA4AAQABAAEAAAAJAA0AAQABAAEAAAAJAAwAAQABAAEAAAAJAAsAAQABAAEAAAAJAAoAAQABAAEAAAAJAAkAAQABAAEAAAAJAAgAAQABAAEAAAAJAAcAAQABAAAAAAAIABQAAQABAAIAAAAIABMAAQABAAEAAAAIABIAAQABAAEAAAAIABEAAQABAAEAAAAIABAAAQABAAEAAAAIAA8AAQABAAEAAAAIAA4AAQABAAEAAAAIAA0AAQABAAEAAAAIAAwAAQABAAEAAAAIAAsAAQABAAEAAAAIAAoAAQABAAEAAAAIAAkAAQABAAEAAAAIAAgAAQABAAEAAAAIAAcAAQABAAAAAAAHABQAAQABAAIAAAAHABMAAQABAAEAAAAHABIAAQABAAEAAAAHABEAAQABAAEAAAAHABAAAQABAAEAAAAHAA8AAQABAAEAAAAHAA4AAQABAAEAAAAHAA0AAQABAAEAAAAHAAwAAQABAAEAAAAHAAsAAQABAAEAAAAHAAoAAQABAAEAAAAHAAkAAQABAAEAAAAHAAgAAQABAAEAAAAHAAcAAQABAAAAAAAGABQAAQABAAIAAAAGABMAAQABAAEAAAAGABIAAQABAAEAAAAGABEAAQABAAEAAAAGABAAAQABAAEAAAAGAA8AAQABAAEAAAAGAA4AAQABAAEAAAAGAA0AAQABAAEAAAAGAAwAAQABAAEAAAAGAAsAAQABAAEAAAAGAAoAAQABAAEAAAAGAAkAAQABAAEAAAAGAAgAAQABAAEAAAAGAAcAAQABAAAAAAAFABQAAQAAAAIAAAAFABMAAQAAAAEAAAAFABIAAQAAAAEAAAAFABEAAQAAAAEAAAAFABAAAQAAAAEAAAAFAA8AAQAAAAEAAAAFAA4AAQAAAAEAAAAFAA0AAQAAAAEAAAAFAAwAAQAAAAEAAAAFAAsAAQAAAAEAAAAFAAoAAQAAAAEAAAAFAAkAAQAAAAEAAAAFAAgAAQAAAAEAAAAFAAcAAQAAAAAAAAA=") tile_set = ExtResource("2_6jm70") +[node name="Blocks" type="TileMapLayer" parent="TileMapLayers" unique_id=441634037] +tile_map_data = PackedByteArray("AAAMAA0AAQAAAAAAAQAHABAAAQAAAAAAAQA=") +tile_set = SubResource("TileSet_vlvpl") + [node name="Cliffs" type="TileMapLayer" parent="TileMapLayers" unique_id=20831420] tile_map_data = PackedByteArray("AAARAA0ABAABAAIAAAARAAwABAACAAAAAAAQAA0ABAABAAIAAAAQAAwABAABAAAAAAAPAA0ABAAAAAIAAAAPAAwABAAAAAAAAAARABMABAABAAIAAAARABIABAABAAEAAAARABEABAABAAAAAAAQABMABAABAAIAAAAQABIABAABAAEAAAAQABEABAABAAAAAAAPABMABAAAAAIAAAAPABIABAAAAAEAAAAPABEABAABAAAAAAAOABEABAABAAQAAAANABEABAABAAQAAAAMABEABAAAAAQAAAASABMABAACAAIAAAASABIABAACAAEAAAASABEABAACAAAAAAASAA0ABAACAAQAAAA=") tile_set = ExtResource("3_ko04g") @@ -95,17 +102,6 @@ limit_right = 1700 limit_bottom = 1400 editor_draw_limits = true -[node name="PushBlock" parent="OnTheGround" unique_id=1349233887 node_paths=PackedStringArray("foam", "submerged_blocks") instance=ExtResource("6_ko04g")] -position = Vector2(882, 894) -foam = NodePath("../../TileMapLayers/Foam") -submerged_blocks = NodePath("../../TileMapLayers/SubmergedBlocks") - -[node name="PushBlock2" parent="OnTheGround" unique_id=357032112 node_paths=PackedStringArray("foam", "submerged_blocks") instance=ExtResource("6_ko04g")] -position = Vector2(720, 958) -collision_mask = 275 -foam = NodePath("../../TileMapLayers/Foam") -submerged_blocks = NodePath("../../TileMapLayers/SubmergedBlocks") - [node name="CollectibleItem" parent="OnTheGround" unique_id=327991066 instance=ExtResource("7_jh3jm")] position = Vector2(1499, 1008) item = SubResource("Resource_ctuqu") diff --git a/push_block.gd b/push_block.gd index 7376b2914..87e09f598 100644 --- a/push_block.gd +++ b/push_block.gd @@ -3,6 +3,13 @@ extends CharacterBody2D @export var foam: TileMapLayer @export var submerged_blocks: TileMapLayer +func _ready() -> void: + if not submerged_blocks and get_parent() is TileMapLayer: + submerged_blocks = get_parent() + + if not foam: + foam = submerged_blocks.get_parent().get_node("Foam") + func _on_area_2d_body_shape_entered( body_rid: RID, From a3e83f0facf328d6d049dd4b496496c4cc3dbf52 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Fri, 13 Mar 2026 12:07:32 +0000 Subject: [PATCH 4/5] Push blocks by repelling --- in_game_sokoban_test.tscn | 1 + project.godot | 1 + push_block.gd | 32 +++++++++++++++++-- push_block.tscn | 17 +++++----- .../characters/player/components/player.gd | 31 ------------------ .../player/components/player_fighting.gd | 5 +-- .../characters/player/player.tscn | 2 +- 7 files changed, 45 insertions(+), 44 deletions(-) diff --git a/in_game_sokoban_test.tscn b/in_game_sokoban_test.tscn index 1f0ee222d..eb35e80b5 100644 --- a/in_game_sokoban_test.tscn +++ b/in_game_sokoban_test.tscn @@ -93,6 +93,7 @@ y_sort_enabled = true [node name="Player" parent="OnTheGround" unique_id=296354958 instance=ExtResource("1_b58vp")] position = Vector2(715, 831) player_name = "StoryWeaver" +mode = 1 sprite_frames = ExtResource("4_ko04g") [node name="Camera2D" type="Camera2D" parent="OnTheGround/Player" unique_id=1941828126] diff --git a/project.godot b/project.godot index 0ee44379c..aae475ee1 100644 --- a/project.godot +++ b/project.godot @@ -295,6 +295,7 @@ locale/translations_pot_files=PackedStringArray("res://scenes/menus/title/compon 2d_physics/layer_8="enemies hitbox" 2d_physics/layer_9="projectiles" 2d_physics/layer_10="non_walkable_floor" +2d_physics/layer_11="pushable" 2d_physics/layer_13="hookable" [rendering] diff --git a/push_block.gd b/push_block.gd index 87e09f598..c3aa5d46b 100644 --- a/push_block.gd +++ b/push_block.gd @@ -1,5 +1,10 @@ extends CharacterBody2D +# Beware dodgy maths +const INITIAL_VELOCITY := 256.0 # px/s +const DURATION := 0.5 # s +const DECELERATION := INITIAL_VELOCITY / DURATION # px/s^2 + @export var foam: TileMapLayer @export var submerged_blocks: TileMapLayer @@ -11,6 +16,23 @@ func _ready() -> void: foam = submerged_blocks.get_parent().get_node("Foam") +func snap_to_cardinal(v: Vector2) -> Vector2: + return Vector2(signf(v.x), 0) if absf(v.x) > absf(v.y) else Vector2(0, signf(v.y)) + + +func got_hit(player: Node2D) -> void: + var dir := player.global_position.direction_to(global_position) + velocity = snap_to_cardinal(dir) * INITIAL_VELOCITY + + +func _physics_process(delta: float) -> void: + velocity = velocity.move_toward(Vector2.ZERO, DECELERATION * delta) + + # Need to not call move_and_slide() otherwise, or else you can push the box by running against it and then it slides away to resolve the collision. + if not velocity.is_zero_approx(): + move_and_slide() + + func _on_area_2d_body_shape_entered( body_rid: RID, body: Node2D, @@ -23,14 +45,20 @@ func _on_area_2d_body_shape_entered( # For this to work, the water layer's physics quadrant size has to be set to # 1, i.e. no chunking of water physics - probably bad for performance... + # But if this became a practical problem we could split up the water layer + # based on whether it's placed somewhere where blocks can be pushed into it, or not. var coords := tile_map.get_coords_for_body_rid(body_rid) - # This doesn't work because at the point when the 1×1px area in the centre of a block travelling rightwards touches a block of water at (x, y), its centre is still in tile (x - 1, y). + + # This doesn't work because at the point when the 1×1px area in the centre of a block + # travelling rightwards touches a block of water at (x, y), + # its centre is still in tile (x - 1, y). # var coords := tile_map.local_to_map(tile_map.to_local(global_position)) + # Erase the water tile_map.set_cell(coords, -1) # Add foam foam.set_cell(coords, 2, Vector2i(0, 0)) - # Put a static copy of this block into the water + # Put a static copy of this block "into the water" submerged_blocks.set_cell(coords, 0, Vector2i(1, 0)) # Free the physical block queue_free() diff --git a/push_block.tscn b/push_block.tscn index fd2b1b369..8cb6d2a16 100644 --- a/push_block.tscn +++ b/push_block.tscn @@ -3,29 +3,30 @@ [ext_resource type="Script" uid="uid://bxulfsreyu63i" path="res://push_block.gd" id="1_jmvaw"] [ext_resource type="Texture2D" uid="uid://c86ayucyybr2t" path="res://scenes/eternal_loom_sokoban/components/wall/walls.png" id="2_byqtm"] +[sub_resource type="RectangleShape2D" id="RectangleShape2D_6jm70"] +size = Vector2(64, 64) + [sub_resource type="AtlasTexture" id="AtlasTexture_ko04g"] atlas = ExtResource("2_byqtm") region = Rect2(64, 0, 64, 64) -[sub_resource type="RectangleShape2D" id="RectangleShape2D_6jm70"] -size = Vector2(64, 64) - [sub_resource type="RectangleShape2D" id="RectangleShape2D_cqfek"] size = Vector2(1, 1) [node name="PushBlock" type="CharacterBody2D" unique_id=1349233887] -collision_mask = 274 +collision_layer = 272 +collision_mask = 17 motion_mode = 1 script = ExtResource("1_jmvaw") -[node name="Sprite2D" type="Sprite2D" parent="." unique_id=448744553] -texture = SubResource("AtlasTexture_ko04g") -metadata/_edit_lock_ = true - [node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1387816029] shape = SubResource("RectangleShape2D_6jm70") metadata/_edit_lock_ = true +[node name="Sprite2D" type="Sprite2D" parent="." unique_id=448744553] +texture = SubResource("AtlasTexture_ko04g") +metadata/_edit_lock_ = true + [node name="WaterDetector" type="Area2D" parent="." unique_id=222932605] collision_layer = 0 collision_mask = 512 diff --git a/scenes/game_elements/characters/player/components/player.gd b/scenes/game_elements/characters/player/components/player.gd index 6c808f6fb..fb1bf2384 100644 --- a/scenes/game_elements/characters/player/components/player.gd +++ b/scenes/game_elements/characters/player/components/player.gd @@ -74,14 +74,6 @@ const DEFAULT_SPRITE_FRAME: SpriteFrames = preload("uid://vwf8e1v8brdp") var input_vector: Vector2 -# Storing this is cribbed from top_down_push_ship_player_2d.gd in GDQuest's Node -# Essentials course. TODO: I don't understand why this is necessary, and in my -# implementation the player "sticks" to the block for 1 frame when they walk -# away, dragging the block with them. -var _pushing_block: CharacterBody2D -var _pushing_direction: Vector2 -var _detach_distance: float - @onready var player_interaction: PlayerInteraction = %PlayerInteraction @onready var player_fighting: Node2D = %PlayerFighting @onready var player_hook: PlayerHook = %PlayerHook @@ -209,31 +201,8 @@ func _physics_process(delta: float) -> void: ) velocity = velocity.move_toward(input_vector, step * delta) - if is_instance_valid(_pushing_block): - _pushing_block.velocity = velocity - _pushing_block.move_and_slide() - move_and_slide() - _push_block() - - -func _push_block() -> void: - for i: int in get_slide_collision_count(): - var collision := get_slide_collision(i) - var collider := collision.get_collider() as CharacterBody2D - if collider: - _pushing_block = collider - # TODO: quantize to cardinal direction? - _pushing_direction = input_vector - _detach_distance = global_position.distance_to(collider.global_position) + 1.0 - break - - if _pushing_block: - var distance := global_position.distance_to(_pushing_block.global_position) - if input_vector != _pushing_direction or distance > _detach_distance: - _pushing_block = null - func teleport_to( tele_position: Vector2, diff --git a/scenes/game_elements/characters/player/components/player_fighting.gd b/scenes/game_elements/characters/player/components/player_fighting.gd index 8321d4130..eb9afbf0d 100644 --- a/scenes/game_elements/characters/player/components/player_fighting.gd +++ b/scenes/game_elements/characters/player/components/player_fighting.gd @@ -34,8 +34,9 @@ func _on_body_entered(body: Node2D) -> void: CameraShake.shake() -func _on_air_stream_body_entered(body: Projectile) -> void: - body.got_hit(owner) +func _on_air_stream_body_entered(body: Node2D) -> void: + if body.has_method("got_hit"): + body.got_hit(owner) func _notification(what: int) -> void: diff --git a/scenes/game_elements/characters/player/player.tscn b/scenes/game_elements/characters/player/player.tscn index 9068ac692..1c120edd1 100644 --- a/scenes/game_elements/characters/player/player.tscn +++ b/scenes/game_elements/characters/player/player.tscn @@ -604,7 +604,7 @@ script = ExtResource("7_5gtgg") unique_name_in_owner = true position = Vector2(0, -24) collision_layer = 0 -collision_mask = 256 +collision_mask = 1280 [node name="AirStreamCollision" type="CollisionShape2D" parent="PlayerFighting/AirStream" unique_id=2073501549] unique_name_in_owner = true From 9321c6aefe35ea564509ff7ab0db5b79ab24d86a Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Fri, 13 Mar 2026 17:11:49 +0000 Subject: [PATCH 5/5] More push blocks --- in_game_sokoban_test.tscn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/in_game_sokoban_test.tscn b/in_game_sokoban_test.tscn index eb35e80b5..9c1a9dc27 100644 --- a/in_game_sokoban_test.tscn +++ b/in_game_sokoban_test.tscn @@ -80,7 +80,7 @@ tile_map_data = PackedByteArray("AAAZABQAAQACAAIAAAAZABMAAQACAAEAAAAZABIAAQACAAE tile_set = ExtResource("2_6jm70") [node name="Blocks" type="TileMapLayer" parent="TileMapLayers" unique_id=441634037] -tile_map_data = PackedByteArray("AAAMAA0AAQAAAAAAAQAHABAAAQAAAAAAAQA=") +tile_map_data = PackedByteArray("AAAMAA0AAQAAAAAAAQAHABAAAQAAAAAAAQAJAA4AAQAAAAAAAQAJAAsAAQAAAAAAAQAMAAoAAQAAAAAAAQAMABAAAQAAAAAAAQA=") tile_set = SubResource("TileSet_vlvpl") [node name="Cliffs" type="TileMapLayer" parent="TileMapLayers" unique_id=20831420]