Detecting swipe in x (left-right) and y (up-down) direction and moving the sprite.

Hello guys, Newbie here! I was working on a game that works on tiles as shown in the pic. Now the user should be able to move the tiles as they swipe in any direction ( up, down , left , right ). I am having problem swiping the box in the place of empty boxes as shown below.

I did try working on the code i found here : https://coronalabs.com/blog/2014/09/16/tutorial-swiping-an-object-to-fixed-points/

Code :

local LEFT = 50 local CENTER = display.contentCenterX local RIGHT &nbsp;= display.contentWidth - 50 local function handleSwipe( event ) &nbsp; &nbsp; if ( event.phase == "moved" ) then &nbsp; &nbsp; &nbsp; &nbsp; local dX = event.x - event.xStart &nbsp; &nbsp; &nbsp; &nbsp; --print( event.x, event.xStart, dX ) &nbsp; &nbsp; &nbsp; &nbsp; if ( dX \> 5 ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --swipe right &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("RIGHT ", dX) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local spot = RIGHT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( event.target.x == LEFT ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spot = CENTER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transition.to( event.target, { time=500, x=spot } ) &nbsp; &nbsp; &nbsp; &nbsp; elseif ( dX \< -5 ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --swipe left &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("LEFT " , dX) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; local spot = LEFT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if ( event.target.x == RIGHT ) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; spot = CENTER &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; transition.to( event.target, { time=500, x=spot } ) &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; end &nbsp; &nbsp; return true end TileGroup:addEventListener( "touch", handleSwipe )

But no success :frowning: Any help?

Hi @14bscsarabbani,

Welcome to Corona! I assume you want to handle swipe on each individual tile? If so, you should add a dedicated event listener (":addEventListener()") to each tile, not the entire group of tiles. Right now, your code will attempt to handle swipe on the entire group which probably isn’t your goal.

Hope this helps,

Brent

Hey thanks for the reply! I think you are confusing the TileGroup name…TileGroup is that individual tile and not all tiles grouped together. And also i was able to implement this code here which detects the swipe but the problem is that i have to use the “moved” event phase which detects 5-6 times when a user swipes. I want to detect it just once and move the tile there. Right now if i try to move the tile it gets called 5-6 times and the tile moves way too much than required. Is there any simple way to detect a swipe direction on an object and just move it to that specific position? :frowning:

Code :

function swipe(event) &nbsp; tile = event.target &nbsp; &nbsp; &nbsp; &nbsp; if event.phase == "moved" then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (event.x \> event.xStart) and (event.y - event.yStart == 0) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Right") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (event.x \< event.xStart) and (event.y - event.yStart == 0) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Left") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (event.y \> event.yStart) and (event.x - event.xStart == 0) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Down") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (event.y \< event.yStart) and (event.x - event.xStart == 0) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Up") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp;&nbsp; end TileGroup:addEventListener("touch", swipe)

Hi @14bscsarabbani,

The “moved” event triggers a bunch of times by design (that’s normal), so for you to “handle” a swipe and not have it trigger multiple times, you should build in some kind of flag variable that marks when the user first reaches a swipe state on the object. Meaning, if you acknowledge that a swipe occurs at like “dx > 5”, that means it could occur many times after it’s > 5… perhaps at 6, 7, 10, 20, and onward. So, your job is to code in a flag to prevent that from happening, by accepting only the first time it reaches > 5. Then, do the transition, but also add an “onComplete” call to reset the flag variable so that further swipes can be done (but only after the transition completes).

Basically, expanding on your first bit of code, it might be something like this:

[lua]

local LEFT = 50

local CENTER = display.contentCenterX

local RIGHT  = display.contentWidth - 50

local swipeWasDone = false  – Set flag variable

[/lua]

And then, inside the function:

[lua]

    if ( dX > 5 and swipeWasDone == false ) then  – Swipe right

        swipeWasDone = true

        local spot = RIGHT

        if ( event.target.x == LEFT ) then

                spot = CENTER

        end

        transition.to( event.target, { time=500, x=spot,

            onComplete=function() swipeWasDone = false; end } )

    elseif ( dX < -5 and swipeWasDone == false ) then  – Swipe left

        swipeWasDone = true

        local spot = LEFT

        if ( event.target.x == RIGHT ) then

                spot = CENTER

        end

        transition.to( event.target, { time=500, x=spot,

            onComplete=function() swipeWasDone = false; end } )

    end

[/lua]

Hope this helps. I’ve asked the author of that tutorial to inspect it for potential updates along these lines.

Brent

Hi @14bscsarabbani,

Welcome to Corona! I assume you want to handle swipe on each individual tile? If so, you should add a dedicated event listener (":addEventListener()") to each tile, not the entire group of tiles. Right now, your code will attempt to handle swipe on the entire group which probably isn’t your goal.

Hope this helps,

Brent

Hey thanks for the reply! I think you are confusing the TileGroup name…TileGroup is that individual tile and not all tiles grouped together. And also i was able to implement this code here which detects the swipe but the problem is that i have to use the “moved” event phase which detects 5-6 times when a user swipes. I want to detect it just once and move the tile there. Right now if i try to move the tile it gets called 5-6 times and the tile moves way too much than required. Is there any simple way to detect a swipe direction on an object and just move it to that specific position? :frowning:

Code :

function swipe(event) &nbsp; tile = event.target &nbsp; &nbsp; &nbsp; &nbsp; if event.phase == "moved" then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (event.x \> event.xStart) and (event.y - event.yStart == 0) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Right") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (event.x \< event.xStart) and (event.y - event.yStart == 0) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Left") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (event.y \> event.yStart) and (event.x - event.xStart == 0) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Down") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (event.y \< event.yStart) and (event.x - event.xStart == 0) then &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; print("Up") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;end &nbsp; &nbsp; &nbsp; &nbsp; end &nbsp; &nbsp; &nbsp;&nbsp; end TileGroup:addEventListener("touch", swipe)

Hi @14bscsarabbani,

The “moved” event triggers a bunch of times by design (that’s normal), so for you to “handle” a swipe and not have it trigger multiple times, you should build in some kind of flag variable that marks when the user first reaches a swipe state on the object. Meaning, if you acknowledge that a swipe occurs at like “dx > 5”, that means it could occur many times after it’s > 5… perhaps at 6, 7, 10, 20, and onward. So, your job is to code in a flag to prevent that from happening, by accepting only the first time it reaches > 5. Then, do the transition, but also add an “onComplete” call to reset the flag variable so that further swipes can be done (but only after the transition completes).

Basically, expanding on your first bit of code, it might be something like this:

[lua]

local LEFT = 50

local CENTER = display.contentCenterX

local RIGHT  = display.contentWidth - 50

local swipeWasDone = false  – Set flag variable

[/lua]

And then, inside the function:

[lua]

    if ( dX > 5 and swipeWasDone == false ) then  – Swipe right

        swipeWasDone = true

        local spot = RIGHT

        if ( event.target.x == LEFT ) then

                spot = CENTER

        end

        transition.to( event.target, { time=500, x=spot,

            onComplete=function() swipeWasDone = false; end } )

    elseif ( dX < -5 and swipeWasDone == false ) then  – Swipe left

        swipeWasDone = true

        local spot = LEFT

        if ( event.target.x == RIGHT ) then

                spot = CENTER

        end

        transition.to( event.target, { time=500, x=spot,

            onComplete=function() swipeWasDone = false; end } )

    end

[/lua]

Hope this helps. I’ve asked the author of that tutorial to inspect it for potential updates along these lines.

Brent