From f1208d5d88727cb50ce6040caff380a5cbc2f0f1 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Thu, 30 Oct 2025 09:54:40 +0700 Subject: [PATCH] Get selection box working and stuff --- main/knight-blue.go | 6 +- main/level1.tilemap | 300 ++++++++++++++++++++++++------- main/main.collection | 19 +- main/selection_box.go | 35 ++++ main/slice9.sprite | 2 - scripts/ControllerManager.script | 91 +++++----- scripts/game.script | 29 +-- scripts/knight.script | 14 +- scripts/selection_box.go | 8 - 9 files changed, 349 insertions(+), 155 deletions(-) create mode 100644 main/selection_box.go delete mode 100644 main/slice9.sprite delete mode 100644 scripts/selection_box.go diff --git a/main/knight-blue.go b/main/knight-blue.go index 2df859f..c83e74d 100644 --- a/main/knight-blue.go +++ b/main/knight-blue.go @@ -14,12 +14,12 @@ components { embedded_components { id: "collisionobject" type: "collisionobject" - data: "type: COLLISION_OBJECT_TYPE_KINEMATIC\n" + data: "type: COLLISION_OBJECT_TYPE_TRIGGER\n" "mass: 0.0\n" "friction: 0.1\n" "restitution: 0.5\n" - "group: \"default\"\n" - "mask: \"default\"\n" + "group: \"unit\"\n" + "mask: \"selection\"\n" "embedded_collision_shape {\n" " shapes {\n" " shape_type: TYPE_BOX\n" diff --git a/main/level1.tilemap b/main/level1.tilemap index f622b45..494efeb 100644 --- a/main/level1.tilemap +++ b/main/level1.tilemap @@ -2,100 +2,280 @@ tile_set: "/main/terrain.tilesource" layers { id: "layer1" z: 0.0 + cell { + x: 1 + y: 0 + tile: 136 + } + cell { + x: 2 + y: 0 + tile: 137 + } + cell { + x: 3 + y: 0 + tile: 138 + } + cell { + x: 4 + y: 0 + tile: 139 + } + cell { + x: 5 + y: 0 + tile: 140 + } + cell { + x: 6 + y: 0 + tile: 137 + } + cell { + x: 7 + y: 0 + tile: 138 + } + cell { + x: 8 + y: 0 + tile: 139 + } + cell { + x: 9 + y: 0 + tile: 140 + } + cell { + x: 10 + y: 0 + tile: 137 + } + cell { + x: 11 + y: 0 + tile: 138 + } + cell { + x: 12 + y: 0 + tile: 139 + } + cell { + x: 13 + y: 0 + tile: 140 + } + cell { + x: 14 + y: 0 + tile: 137 + } + cell { + x: 15 + y: 0 + tile: 138 + } + cell { + x: 16 + y: 0 + tile: 139 + } + cell { + x: 17 + y: 0 + tile: 140 + } + cell { + x: 18 + y: 0 + tile: 141 + } + cell { + x: 1 + y: 1 + tile: 190 + } + cell { + x: 2 + y: 1 + tile: 119 + } + cell { + x: 3 + y: 1 + tile: 120 + } + cell { + x: 4 + y: 1 + tile: 121 + } + cell { + x: 5 + y: 1 + tile: 122 + } + cell { + x: 6 + y: 1 + tile: 119 + } + cell { + x: 7 + y: 1 + tile: 120 + } + cell { + x: 8 + y: 1 + tile: 121 + } + cell { + x: 9 + y: 1 + tile: 122 + } + cell { + x: 10 + y: 1 + tile: 119 + } + cell { + x: 11 + y: 1 + tile: 120 + } + cell { + x: 12 + y: 1 + tile: 121 + } + cell { + x: 13 + y: 1 + tile: 122 + } + cell { + x: 14 + y: 1 + tile: 119 + } + cell { + x: 15 + y: 1 + tile: 120 + } + cell { + x: 16 + y: 1 + tile: 121 + } + cell { + x: 17 + y: 1 + tile: 122 + } + cell { + x: 18 + y: 1 + tile: 123 + } cell { x: 1 y: 2 - tile: 90 + tile: 100 } cell { x: 2 y: 2 - tile: 91 + tile: 101 } cell { x: 3 y: 2 - tile: 92 + tile: 102 } cell { x: 4 y: 2 - tile: 93 + tile: 103 } cell { x: 5 y: 2 - tile: 94 + tile: 104 } cell { x: 6 y: 2 - tile: 91 + tile: 101 } cell { x: 7 y: 2 - tile: 92 + tile: 102 } cell { x: 8 y: 2 - tile: 93 + tile: 103 } cell { x: 9 y: 2 - tile: 94 + tile: 104 } cell { x: 10 y: 2 - tile: 91 + tile: 101 } cell { x: 11 y: 2 - tile: 92 + tile: 102 } cell { x: 12 y: 2 - tile: 93 + tile: 103 } cell { x: 13 y: 2 - tile: 94 + tile: 104 } cell { x: 14 y: 2 - tile: 91 + tile: 101 } cell { x: 15 y: 2 - tile: 92 + tile: 102 } cell { x: 16 y: 2 - tile: 93 + tile: 103 } cell { x: 17 y: 2 - tile: 94 + tile: 104 } cell { x: 18 y: 2 - tile: 95 + tile: 105 } cell { x: 1 y: 3 - tile: 72 + tile: 82 } cell { x: 2 @@ -180,12 +360,12 @@ layers { cell { x: 18 y: 3 - tile: 77 + tile: 87 } cell { x: 1 y: 4 - tile: 54 + tile: 64 } cell { x: 2 @@ -270,12 +450,12 @@ layers { cell { x: 18 y: 4 - tile: 59 + tile: 69 } cell { x: 1 y: 5 - tile: 36 + tile: 46 } cell { x: 2 @@ -360,12 +540,12 @@ layers { cell { x: 18 y: 5 - tile: 41 + tile: 51 } cell { x: 1 y: 6 - tile: 18 + tile: 28 } cell { x: 2 @@ -450,12 +630,12 @@ layers { cell { x: 18 y: 6 - tile: 23 + tile: 33 } cell { x: 1 y: 7 - tile: 72 + tile: 82 } cell { x: 2 @@ -540,12 +720,12 @@ layers { cell { x: 18 y: 7 - tile: 77 + tile: 87 } cell { x: 1 y: 8 - tile: 54 + tile: 64 } cell { x: 2 @@ -630,12 +810,12 @@ layers { cell { x: 18 y: 8 - tile: 59 + tile: 69 } cell { x: 1 y: 9 - tile: 36 + tile: 46 } cell { x: 2 @@ -720,12 +900,12 @@ layers { cell { x: 18 y: 9 - tile: 41 + tile: 51 } cell { x: 1 y: 10 - tile: 18 + tile: 28 } cell { x: 2 @@ -810,12 +990,12 @@ layers { cell { x: 18 y: 10 - tile: 23 + tile: 33 } cell { x: 1 y: 11 - tile: 72 + tile: 82 } cell { x: 2 @@ -900,12 +1080,12 @@ layers { cell { x: 18 y: 11 - tile: 77 + tile: 87 } cell { x: 1 y: 12 - tile: 54 + tile: 64 } cell { x: 2 @@ -990,12 +1170,12 @@ layers { cell { x: 18 y: 12 - tile: 59 + tile: 69 } cell { x: 1 y: 13 - tile: 36 + tile: 46 } cell { x: 2 @@ -1080,12 +1260,12 @@ layers { cell { x: 18 y: 13 - tile: 41 + tile: 51 } cell { x: 1 y: 14 - tile: 18 + tile: 28 } cell { x: 2 @@ -1170,97 +1350,97 @@ layers { cell { x: 18 y: 14 - tile: 23 + tile: 33 } cell { x: 1 y: 15 - tile: 0 + tile: 10 } cell { x: 2 y: 15 - tile: 1 + tile: 11 } cell { x: 3 y: 15 - tile: 2 + tile: 12 } cell { x: 4 y: 15 - tile: 3 + tile: 13 } cell { x: 5 y: 15 - tile: 4 + tile: 14 } cell { x: 6 y: 15 - tile: 1 + tile: 11 } cell { x: 7 y: 15 - tile: 2 + tile: 12 } cell { x: 8 y: 15 - tile: 3 + tile: 13 } cell { x: 9 y: 15 - tile: 4 + tile: 14 } cell { x: 10 y: 15 - tile: 1 + tile: 11 } cell { x: 11 y: 15 - tile: 2 + tile: 12 } cell { x: 12 y: 15 - tile: 3 + tile: 13 } cell { x: 13 y: 15 - tile: 4 + tile: 14 } cell { x: 14 y: 15 - tile: 1 + tile: 11 } cell { x: 15 y: 15 - tile: 2 + tile: 12 } cell { x: 16 y: 15 - tile: 3 + tile: 13 } cell { x: 17 y: 15 - tile: 4 + tile: 14 } cell { x: 18 y: 15 - tile: 7 + tile: 15 } } material: "/builtins/materials/tile_map.material" diff --git a/main/main.collection b/main/main.collection index b22ea48..c92c9ae 100644 --- a/main/main.collection +++ b/main/main.collection @@ -16,11 +16,11 @@ instances { } } instances { - id: "knight-blue1" + id: "knight-blue-hello" prototype: "/main/knight-blue.go" position { - x: 488.0 - y: 162.0 + x: 511.0 + y: 256.0 } component_properties { id: "knight" @@ -67,8 +67,8 @@ instances { id: "knight-blue4" prototype: "/main/knight-blue.go" position { - x: 232.0 - y: 414.0 + x: 144.0 + y: 424.0 } component_properties { id: "knight" @@ -97,10 +97,11 @@ instances { } instances { id: "selection_box" - prototype: "/scripts/selection_box.go" - position { - z: 1.0 - } + prototype: "/main/selection_box.go" +} +instances { + id: "-Game" + prototype: "/main/Game.go" } scale_along_z: 0 embedded_instances { diff --git a/main/selection_box.go b/main/selection_box.go new file mode 100644 index 0000000..07244d3 --- /dev/null +++ b/main/selection_box.go @@ -0,0 +1,35 @@ +components { + id: "selection_box" + component: "/main/selection_box.sprite" +} +components { + id: "ControllerManager" + component: "/scripts/ControllerManager.script" +} +embedded_components { + id: "collisionobject" + type: "collisionobject" + data: "type: COLLISION_OBJECT_TYPE_TRIGGER\n" + "mass: 0.0\n" + "friction: 0.1\n" + "restitution: 0.5\n" + "group: \"selection\"\n" + "mask: \"unit\"\n" + "embedded_collision_shape {\n" + " shapes {\n" + " shape_type: TYPE_BOX\n" + " position {\n" + " }\n" + " rotation {\n" + " }\n" + " index: 0\n" + " count: 3\n" + " id: \"box\"\n" + " }\n" + " data: 3.0\n" + " data: 3.0\n" + " data: 0.5\n" + "}\n" + "locked_rotation: true\n" + "" +} diff --git a/main/slice9.sprite b/main/slice9.sprite deleted file mode 100644 index fc97644..0000000 --- a/main/slice9.sprite +++ /dev/null @@ -1,2 +0,0 @@ -default_animation: "" -material: "/builtins/materials/sprite.material" diff --git a/scripts/ControllerManager.script b/scripts/ControllerManager.script index c27c2c7..e270e51 100644 --- a/scripts/ControllerManager.script +++ b/scripts/ControllerManager.script @@ -1,62 +1,60 @@ --- Control_Manager.script +local utils = require "scripts.utils" -- Input Variables local dragging = false -local selection_box -- Camera Variables -local rts_camera -local rts_camera_size local inv_matrix -- inverse matrix cached on drag start -- Position Variables local start_pos = vmath.vector3() local prev_pos = vmath.vector3() +function on_reload(self) + -- TODO: Investigate why using `local` wasn't working on reload + -- msg.post(".", "acquire_input_focus") + -- -- NOTE: For some reason I need to also call this on_reload, or else it gets niled out + -- self.rts_camera = msg.url("CameraParent#camera") + -- local DISPLAY_WIDTH = sys.get_config_int("display.width") + -- local DISPLAY_HEIGHT = sys.get_config_int("display.height") + -- self.rts_camera_size = vmath.vector3(DISPLAY_WIDTH, DISPLAY_HEIGHT, 0) + self.selection_collider = msg.url("/selection_box#collisionobject") +end + function init(self) msg.post(".", "acquire_input_focus") -- Activates to get inputs - selection_box = msg.url("#selection_box") -- Selection Box - Sprite Component - msg.post(selection_box, "disable") -- Sprite Hidden - rts_camera = msg.url("CameraParent#camera") -- Camera Component2 - -- Gets Display Properties from System + self.selection_box = msg.url("#selection_box") -- Selection Box - Sprite Component + msg.post(self.selection_box, "disable") -- Sprite Hidden + self.rts_camera = msg.url("CameraParent#camera") -- Camera Component2 + self.selection_collider = msg.url("#selection_box/collisionobject") + -- Gets Display Properties from System local DISPLAY_WIDTH = sys.get_config_int("display.width") local DISPLAY_HEIGHT = sys.get_config_int("display.height") -- Get Screen To World Properties - rts_camera_size = vmath.vector3(DISPLAY_WIDTH, DISPLAY_HEIGHT, 0) + self.rts_camera_size = vmath.vector3(DISPLAY_WIDTH, DISPLAY_HEIGHT, 0) end -local function screen_to_world(x, y) - -- Convert screen coordinates to the [-1, 1] range (Normalized Device Coordinates) - local ndc_x = (x / rts_camera_size.x) * 2 - 1 -- X Ranges From [-1 (left) to 1 (right)] - local ndc_y = (y / rts_camera_size.y) * 2 - 1 -- Y Ranges From [-1 (bottom) to 1 (top)] - - -- Applies the inverse camera transformation to convert NDC to world coordinates. - local world = inv_matrix * vmath.vector4(ndc_x, ndc_y, 0, 1) -- NDC position as a 4D vector - -- Converts homogeneous coordinates (x, y, z, w) to 3D world coordinates - -- No effect for orthographic(2D). Depth Scaling For perspective cameras. - return world.x / world.w, world.y / world.w -- Return X, Y -end - -local function selection_update_start(action) -- Runs once when pressed +local function selection_update_start(self, action) -- Runs once when pressed -- Updates Screen_to_World Variables - local projection = camera.get_projection(rts_camera) -- Gets the Projection Size - local view = camera.get_view(rts_camera) -- Gets the View Size + local projection = camera.get_projection(self.rts_camera) -- Gets the Projection Size + local view = camera.get_view(self.rts_camera) -- Gets the View Size inv_matrix = vmath.inv(projection * view) -- Gets the Inversion -- Initialize positions - local x, y = screen_to_world(action.x, action.y) -- Gets Global Position + local x, y, _ = utils.screen_to_world(action.x, action.y, 0, "/CameraParent#camera") -- Gets Global Position start_pos.x, start_pos.y = x, y -- Sets start_pos prev_pos.x, prev_pos.y = x, y -- Updates prev_pos -- Update Sprite Properties - go.set_position(start_pos, selection_box) -- Set Position - go.set(selection_box, "size", vmath.vector3(0.1, 0.1, 0)) -- Set Size(0.1) in X, Y - msg.post(selection_box, "enable") -- Sprite Visable + go.set_position(start_pos, self.selection_box) -- Set Position + go.set(self.selection_box, "size", vmath.vector3(0.1, 0.1, -1)) -- Set Size(0.1) in X, Y + msg.post(self.selection_box, "enable") -- Sprite Visable + msg.post("/selection_box#collisionobject", "enable") dragging = true -- Dragging True end -local function selection_update_dragging(x, y) -- Runs when Dragging +local function selection_update_dragging(self, x, y) -- Runs when Dragging -- Calculate bounding box local min_x = math.min(start_pos.x, x) -- Min X local min_y = math.min(start_pos.y, y) -- Min Y @@ -64,41 +62,38 @@ local function selection_update_dragging(x, y) -- Runs when Dragging local max_y = math.max(start_pos.y, y) -- Max Y -- Calculates the center of the selection box - local center = vmath.vector3( - (min_x + max_x) * 0.5, -- X Direction - (min_y + max_y) * 0.5, -- Y Direction - 0 -- Z Direction -) + local center = vmath.vector3((min_x + max_x) * 0.5, (min_y + max_y) * 0.5, 0) --- Calculate width/height of the selection box from drag distance --- Ensures a minimum size of 0.1 to prevent the sprite from collapsing -local size = vmath.vector3( -math.max(max_x - min_x, 0.1), -- Width -math.max(max_y - min_y, 0.1), -- Height -0 -- Z Direction -) + -- Calculate width/height of the selection box from drag distance + -- Ensures a minimum size of 0.1 to prevent the sprite from collapsing + local size = vmath.vector3(math.max(max_x - min_x, 0.1),math.max(max_y - min_y, 0.1),0) --- Set sprite properties -go.set_position(center, selection_box) -- Sets Position -go.set(selection_box, "size", size) -- Sets Size + -- Set sprite properties + go.set_position(center, self.selection_box) -- Sets Position + go.set(self.selection_box, "size", size) -- Sets Size + -- go.set(self.selection_collider, "size", size) + local box = physics.get_shape("/selection_box#collisionobject", "box") + box.dimensions = size + physics.set_shape("/selection_box#collisionobject", "box", box) end function on_input(self, action_id, action) if action_id ~= hash("touch") then return end if action.pressed and not dragging then - selection_update_start(action) -- Applies Sprite Properties at Start + selection_update_start(self, action) -- Applies Sprite Properties at Start elseif action.released and dragging then dragging = false -- Dragging False - msg.post(selection_box, "disable") -- Sprite Hidden + msg.post(self.selection_box, "disable") -- Sprite Hidden + msg.post("/selection_box#collisionobject", "disable") elseif dragging then - local x, y = screen_to_world(action.x, action.y) -- Gets Global Position + local x, y = utils.screen_to_world(action.x, action.y, 0, "/CameraParent#camera") -- Gets Global Position -- Only update if position changed if math.abs(x - prev_pos.x) > 0.001 or math.abs(y - prev_pos.y) > 0.001 then prev_pos.x, prev_pos.y = x, y -- Updates prev_pos - selection_update_dragging(x, y) -- Applies Sprite Properties during dragging + selection_update_dragging(self, x, y) -- Applies Sprite Properties during dragging end end end \ No newline at end of file diff --git a/scripts/game.script b/scripts/game.script index b4d856f..1c34245 100644 --- a/scripts/game.script +++ b/scripts/game.script @@ -1,7 +1,7 @@ +local utils = require "scripts.utils" + function init(self) - -- Add initialization code here - -- Learn more: https://defold.com/manuals/script/ - -- Remove this function if not needed + msg.post(".", "acquire_input_focus") end function final(self) @@ -31,33 +31,18 @@ function on_message(self, message_id, message, sender) -- Remove this function if not needed end -local function screen_to_world(x, y, z, camera_id) - local projection = camera.get_projection(camera_id) - local view = camera.get_view(camera_id) - local w, h = window.get_size() - - -- https://defold.com/manuals/camera/#converting-mouse-to-world-coordinates - local inv = vmath.inv(projection * view) - x = (2 * x / w) - 1 - y = (2 * y / h) - 1 - z = (2 * z) - 1 - local x1 = x * inv.m00 + y * inv.m01 + z * inv.m02 + inv.m03 - local y1 = x * inv.m10 + y * inv.m11 + z * inv.m12 + inv.m13 - local z1 = x * inv.m20 + y * inv.m21 + z * inv.m22 + inv.m23 - return x1, y1, z1 -end - function on_input(self, action_id, action) - if action_id == hash("left-click") and action.pressed then + if action_id == hash("touch") and action.pressed then self.next_state = "moving" - local tx, ty, _ = screen_to_world(action.screen_x, action.screen_y, 0, "/CameraParent#camera") + local tx, ty, _ = utils.screen_to_world(action.screen_x, action.screen_y, 0, "/CameraParent#camera") self.target_pos = vmath.vector3(tx, ty, 0) elseif action_id == hash("right-click") then - + -- msg.post(receiver, message_id, message) end end function on_reload(self) + msg.post(".", "acquire_input_focus") -- Add reload-handling code here -- Learn more: https://defold.com/manuals/hot-reload/ -- Remove this function if not needed diff --git a/scripts/knight.script b/scripts/knight.script index 9942a80..bd851bf 100644 --- a/scripts/knight.script +++ b/scripts/knight.script @@ -5,6 +5,7 @@ function init(self) self.target_pos = vmath.vector3() self.state = "idling" self.next_state = "idling" + self.selected = false end local function move_to_target(self, target, dt) @@ -31,9 +32,16 @@ function update(self, dt) end function on_message(self, message_id, message, sender) - -- Add message-handling code here - -- Learn more: https://defold.com/manuals/message-passing/ - -- Remove this function if not needed + if message_id == hash("collision_response") then + print(go.get_id()) + end + if message_id == hash("trigger_response") then + if message.enter then + self.selected = true + else + self.selected = false + end + end end function final(self) diff --git a/scripts/selection_box.go b/scripts/selection_box.go deleted file mode 100644 index 15a5770..0000000 --- a/scripts/selection_box.go +++ /dev/null @@ -1,8 +0,0 @@ -components { - id: "selection_box" - component: "/main/selection_box.sprite" -} -components { - id: "ControllerManager" - component: "/scripts/ControllerManager.script" -}