I have one game object that I need to drag around on the screen when, and only when, the user holds and drags the object itself. What I am finding is that when the object captures input focus the first time I tap the screen the object’s on_input method fires for the tap/click event even though that initial tap/click happens in an entirely different area of the screen.
I can work around this by checking that action.x/action.y lie within a “safe area” around the object’s current position. However, this is at best clumsy. Why is the on_input method being fired even though what is being tapped is some other part of the screen?
This is a common misconception. The on_input callback catches all kinds of input regardless of where it happens: keys, game pads, touch, mouse and text. We clarify this in the next release.
If you want to restrict input to a certain area of the screen, for instance the location of the game object, then you need to take care of that yourself.
In a gui we provide the gui.pick_node() function, but we have no such thing for game objects since picking of game objects depends on the camera projection and other factors.
You can use collision triggers to detect mouse touch on top of a game object. The Defold-Input library provides a cursor script that takes care of most of the work for you. Demo: Defold-Input 0.1
@britzl, before I read your reply I had coded in a work around that appears to handle the job - at least for my present needs. The work around goes like this
The Requirement: move a specified game object - in my case this is a “lasso” - in response to an apparent drag/drop operation using the mouse (click) or touch screen (touch/tap)
The Problem: on_input is triggered for a tap/click interaction at ANY point on the screen
The Consequence:The “lasso” is being dragged around even when the user clicks/taps at some other point on the screen
The Solution: Create another, static (in the sense of design-type, not factory generated/run-time) game object and then do the following (I am calling this object the Cursor)
Initially place the Cursor off screen/at position (0,0,1)
Get it to capture input events
When the input is tap/click move it to the action.x,action.y position
Also have the Lasso object capture input events
When the input is tap/click first check that the Cursor X/Y position lies within a predefined envelop around the Lasso X/Y position. If so, move the Cursor and the Lasso to the same new position
This works. The end result is smooth and responsive. I wonder if you could comment on any issues that it might throw up.
Thanks! I imagine that the Cursor object need not have a collision object? A simple script to set its position to the tap/click input event action.x/action.y coordinates is really all that is needed
Ummm… I meant the solution I outlined. I initially had a collision object but I also tested it after removing the collision object - just the Cursor game object and a simple script that listens for on_input and then dispatches it by moving the Cursor. Quite by accident I ended by calling the object in my solution a “Cursor” as you have in your own defold_input extension.
Even with the collision object gone I can still trap the input event and operate on the action.x/y attributes to move my “Cursor”. Then I proceed to trap the input event in my other (Lasso) object which has a visual representation (a sprite) and a collision object.
A little note for the benefit of anyone else who tries to copy my solution prior to closing this thread - although it probably will make little difference in most cases it would probably be good practice to “park” the Cursor object offscreen or at (0,0,1) when action.released is detected in the Lasso (or whatever you call it in your case) on_input handler.
I’m trying to drag paddle object using cursor object, I have added this script to my cursor object, it works well but i want to understand if i’m doing something unusual with my script?!
function init(self)
msg.post(".", "acquire_input_focus")
self.pressed = false
self.diffX = 0
self.diffY = 0
self.dragging = false
end
function update(self, dt)
if self.dragging then
local cursorPos = go.get_position()
cursorPos.x = cursorPos.x - self.diffX
cursorPos.y = cursorPos.y - self.diffY
go.set_position(cursorPos, "/paddle")
end
end
function on_input(self, action_id, action)
-- set the cursor object poistion with mouse cursor position
go.set_position(vmath.vector3(action.x, action.y, 0))
if action_id == hash("touch") and action.pressed then
self.pressed = true
self.diffX = go.get_position().x - go.get_position("/paddle").x
self.diffY = go.get_position().y - go.get_position("/paddle").y
elseif action_id == hash("touch") and action.released then
self.pressed = false
self.dragging = false
end
end
function on_message(self, message_id, message, sender)
if message_id == hash("collision_response") and self.pressed then
self.dragging = true
end
end