Swiping object without directly touching it

Hi,

I currently have a player object that when touched and the finger is dragged around the screen, the player moves along with it. However, I want to make it so that I can move the player without directly touching the player, so that any touch/drag in any direction moves the player in a similar way around the screen (at a faster speed than swiping the finger).

If anybody knows how to detect touches anywhere on the screen despite the players position, please let me know.

Thanks!

just create an invisible rectangle full screen, give that rectangle same touch events than the player. that invisible rectangle must be on top of everything, and if you have any other touches you need to return false or it will have exclusive touch events. don’t for get to enable isHitTestable on invisible objects to work :wink:

or change your object listener to a runtime listener that will automatically capture touch events anywhere on the screen

Runtime:addEventListener( "touch", onTouch )

Yet another possibility is to detect the first “moved” phase on the object as the start of your swipe. This would let the user start the actual swipe somewhere outside of the object, and then the object would start picking up touch phases after the first move. There are some other factors which you might need to account for, like setting focus on the object after the first “moved” phase (so it would then recognize the “ended” phase if it ended outside of the object), but that could be for a later discussion.

Brent

Runtime:addEventListener vs Object:addEventListener what are the differences in its core? perfomance wise what should we use?

Hi @carloscosta,

It’s not really a question of performance, but usage. Runtime method detects touches on the entire screen without any real regard to what display object is being touched. That can be useful in cases, but typically you’ll need to know exactly what object is being touched/tapped, unless there is just one touch/tab-able object on the screen at once.

Brent

thanks brent for your replay.

but, its a question of performance. if i can use an object that can be used like a global touch event like i suggested and if i can use a runtime like sphere suggested so the only difference is speed. if using the object is faster i will use objects it if its the same, i will use runtime. usually when i ear runtimes i runaway from them because i think of constant running functions consuming battery and cpu. but i was just wondering internally how objects touch event are that different from runtimes on its core.

Why create an additional object (and allocate additional memory) if it is not required?

The only difference between object listeners and runtime listeners is scope - i.e. they are always listening

Bear in mind the Corona runtime is always running and drawing the screen.

Hi - thank you all for the replies and suggestions.

I have worked a bit on this concept after finding a ‘throwing’ code on the forums. The current code allows for me to touch anywhere on the screen and drag, causing the player object to mimic the same drag behavior as created by the touch drag.

Now I would like for the dragging to feel more fluid/less choppy. Currently once the drag is stopped, the player instantly stops. However, I would like to make it so the motion is delayed upon the start of the swipe/is slow at the start, moves for a majority of the swipe, then slows again as it approaches the end of the swipe, as illustrated in the following video:

https://vimeo.com/93206523#t=68s

I know this effect is rather simple using transitions, but physics is necessary as other objects can affect the course. If anybody can help out with this easing effect on the player, please let me know.

Here’s the current code:

local physics = require("physics") local \_x50 = display.contentCenterX local \_y50 = display.contentCenterY local player = display.newRect(\_x50, \_y50, 16, 16) physics.addBody(player) player:setFillColor(1) player.gravityScale = 0 local touchMask function playerSwipe(event) if (event.phase == "began") then touchMask = display.newCircle(event.x, event.y, 64, 64, 32) touchMask:setFillColor(1, 1, 1, 0.75) touchMask.isVisible = true physics.addBody(touchMask) touchMask.isSensor = true touchMask.joint = physics.newJoint("touch", touchMask, event.x, event.y) function touchMask.enterFrame(event) local vx, vy = touchMask:getLinearVelocity() player:setLinearVelocity(vx, vy) player.angularVelocity = touchMask.angularVelocity end Runtime:addEventListener("enterFrame", touchMask) elseif (event.phase == "moved") then touchMask.joint:setTarget(event.x, event.y) elseif (event.phase == "cancelled") or (event.phase == "ended") then player:setLinearVelocity(0, 0) touchMask:setLinearVelocity(0, 0) Runtime:removeEventListener("enterFrame", touchMask) touchMask.joint:removeSelf() end end Runtime:addEventListener("touch", playerSwipe)

@hi1,

Well I didn’t run the actual code, but the line that’s making your player stop dead is:

[lua]

player:setLinearVelocity(0, 0)

[/lua]

Try removing that and see how the behavior looks.

Take care,

Brent

just create an invisible rectangle full screen, give that rectangle same touch events than the player. that invisible rectangle must be on top of everything, and if you have any other touches you need to return false or it will have exclusive touch events. don’t for get to enable isHitTestable on invisible objects to work :wink:

or change your object listener to a runtime listener that will automatically capture touch events anywhere on the screen

Runtime:addEventListener( "touch", onTouch )

Yet another possibility is to detect the first “moved” phase on the object as the start of your swipe. This would let the user start the actual swipe somewhere outside of the object, and then the object would start picking up touch phases after the first move. There are some other factors which you might need to account for, like setting focus on the object after the first “moved” phase (so it would then recognize the “ended” phase if it ended outside of the object), but that could be for a later discussion.

Brent

Runtime:addEventListener vs Object:addEventListener what are the differences in its core? perfomance wise what should we use?

Hi @carloscosta,

It’s not really a question of performance, but usage. Runtime method detects touches on the entire screen without any real regard to what display object is being touched. That can be useful in cases, but typically you’ll need to know exactly what object is being touched/tapped, unless there is just one touch/tab-able object on the screen at once.

Brent

thanks brent for your replay.

but, its a question of performance. if i can use an object that can be used like a global touch event like i suggested and if i can use a runtime like sphere suggested so the only difference is speed. if using the object is faster i will use objects it if its the same, i will use runtime. usually when i ear runtimes i runaway from them because i think of constant running functions consuming battery and cpu. but i was just wondering internally how objects touch event are that different from runtimes on its core.

Why create an additional object (and allocate additional memory) if it is not required?

The only difference between object listeners and runtime listeners is scope - i.e. they are always listening

Bear in mind the Corona runtime is always running and drawing the screen.

Hi - thank you all for the replies and suggestions.

I have worked a bit on this concept after finding a ‘throwing’ code on the forums. The current code allows for me to touch anywhere on the screen and drag, causing the player object to mimic the same drag behavior as created by the touch drag.

Now I would like for the dragging to feel more fluid/less choppy. Currently once the drag is stopped, the player instantly stops. However, I would like to make it so the motion is delayed upon the start of the swipe/is slow at the start, moves for a majority of the swipe, then slows again as it approaches the end of the swipe, as illustrated in the following video:

https://vimeo.com/93206523#t=68s

I know this effect is rather simple using transitions, but physics is necessary as other objects can affect the course. If anybody can help out with this easing effect on the player, please let me know.

Here’s the current code:

local physics = require("physics") local \_x50 = display.contentCenterX local \_y50 = display.contentCenterY local player = display.newRect(\_x50, \_y50, 16, 16) physics.addBody(player) player:setFillColor(1) player.gravityScale = 0 local touchMask function playerSwipe(event) if (event.phase == "began") then touchMask = display.newCircle(event.x, event.y, 64, 64, 32) touchMask:setFillColor(1, 1, 1, 0.75) touchMask.isVisible = true physics.addBody(touchMask) touchMask.isSensor = true touchMask.joint = physics.newJoint("touch", touchMask, event.x, event.y) function touchMask.enterFrame(event) local vx, vy = touchMask:getLinearVelocity() player:setLinearVelocity(vx, vy) player.angularVelocity = touchMask.angularVelocity end Runtime:addEventListener("enterFrame", touchMask) elseif (event.phase == "moved") then touchMask.joint:setTarget(event.x, event.y) elseif (event.phase == "cancelled") or (event.phase == "ended") then player:setLinearVelocity(0, 0) touchMask:setLinearVelocity(0, 0) Runtime:removeEventListener("enterFrame", touchMask) touchMask.joint:removeSelf() end end Runtime:addEventListener("touch", playerSwipe)

@hi1,

Well I didn’t run the actual code, but the line that’s making your player stop dead is:

[lua]

player:setLinearVelocity(0, 0)

[/lua]

Try removing that and see how the behavior looks.

Take care,

Brent