Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Swipe Handling

edited March 2014 in Code Sharing Posts: 2,042

For a project of mine I needed some simple code to detect swipes. I've seen people ask how to do it before, so I figured I'd go ahead and share it here (along with a simple code in main showing how it's used)

Basically it works as so: A swipe must be of a certain length and time and not distance too far vertically or horizontally depending on the direction of the swipe. You can call Swipes:getSwipe() and it will return a vector based on how much you swiped (Ex a long swipe right would return vec2(3.2, 0) whereas a short swipe down would return vec2(0, -1.3)

Enough talking, here's the code:


--# Main -- Swiper -- Use this function to perform your initial setup function setup() swiper = Swipes() x = WIDTH / 2 y = HEIGHT / 2 end -- This function gets called once every frame function draw() background(255, 255, 255, 255) stroke(0, 155, 255, 255) strokeWidth(2) noFill() local drawX, drawY = x % WIDTH, y % HEIGHT ellipse(drawX, drawY, 100) end function touched(t) -- Pass touch along to swipe handler swiper:touched(t) if t.state == ENDED then -- Get the swipe and use it to move the ball local s = swiper:getSwipe() tween(math.abs(0.2 * s.x), _G, { x = x + s.x * 100 }, tween.easing.linear) tween(math.abs(0.2 * s.y), _G, { y = y + s.y * 100 }, tween.easing.linear) end end --# Swipes Swipes = class() function Swipes:init() self.allowedMargin = WIDTH / 10 self.swipeLen = WIDTH / 21 self.allowedTime = 2 self.firstTouch = nil self.lastTouch = nil self.startTime = nil self.endTime = nil self.swipe = vec2(0, 0) end function Swipes:getSwipe() local ret = self.swipe or vec2(0,0) self.swipe = vec2(0,0) return ret end function Swipes:findSwipes() if self.startTime == nil or self.endTime == nil or self.endTime - self.startTime > self.allowedTime then return end if self.firstTouch == nil or self.lastTouch == nil then self.firstTouch = nil self.lastTouch = nil return end if self.lastTouch.x - self.firstTouch.x >= self.swipeLen and math.abs(self.lastTouch.y - self.firstTouch.y) <= self.allowedMargin then -- Swiped right local amp = (self.lastTouch.x - self.firstTouch.x) / self.swipeLen self.swipe = vec2(amp, 0) elseif self.firstTouch.x - self.lastTouch.x >= self.swipeLen and math.abs(self.lastTouch.y - self.firstTouch.y) <= self.allowedMargin then -- Swiped left local amp = (self.lastTouch.x - self.firstTouch.x) / self.swipeLen self.swipe = vec2(amp, 0) elseif self.lastTouch.y - self.firstTouch.y >= self.swipeLen and math.abs(self.lastTouch.x - self.firstTouch.x) <= self.allowedMargin then -- Swiped up local amp = (self.lastTouch.y - self.firstTouch.y) / self.swipeLen self.swipe = vec2(0, amp) elseif self.firstTouch.y - self.lastTouch.y >= self.swipeLen and math.abs(self.lastTouch.x - self.firstTouch.x) <= self.allowedMargin then -- Swiped down local amp = (self.lastTouch.y - self.firstTouch.y) / self.swipeLen self.swipe = vec2(0, amp) end self.firstTouch = nil self.lastTouch = nil end function Swipes:touched(t) if t.state == BEGAN and self.firstTouch == nil then self.firstTouch = t self.startTime = ElapsedTime end if t.state == ENDED and self.lastTouch == nil then self.lastTouch = t self.endTime = ElapsedTime self:findSwipes() end end
Tagged:

Comments

  • dave1707dave1707 Mod
    Posts: 7,468

    @JakAttak I looked thru my collection of code and found this swipe program. Thought I'd share it while we're on the subject. Swipe in the direction you want the circle to go. Speed is determined by the length of the swipe.


    displayMode(FULLSCREEN) function setup()     speed=30    -- set initial speed value     swipe=vec3(0,0,0)    -- initialize swipe variable     x=WIDTH/2    -- starting x location     y=HEIGHT/2   -- starting y location end function draw()     background(40,40,50)    -- set background color     fill(255)    -- white color for circle     text("Swipe for direction, length for speed",WIDTH/2,HEIGHT-100)     ellipse(x,y,40)    -- draw a circle at x,y with size of 40     if swipe.z>0 then    -- check if a swipe occured         x=x+swipe.x*swipe.z    -- add x swipe speed to x value         y=y+swipe.y*swipe.z    -- add y swipe speed to y value     end   end function touched(t)     if t.state==BEGAN then    -- start of swipe         ts=vec2(t.x,t.y)    -- save touch start values     end     if t.state==ENDED then    -- end of swipe         d=vec2(t.x,t.y):dist(vec2(ts.x,ts.y))    -- calculate swipe distance         td=vec2(t.x-ts.x,t.y-ts.y):normalize()    -- x,y movement         swipe=vec3(td.x,td.y,d/speed)    -- set swipe variable x,y,speed     end        end
  • Posts: 16

    Hi ! these codes looks really good ! But I think a swipe should be short in time (1 or 2 seconds max). Is there a way to handle that ?

  • Posts: 2,042

    @RyZum sure! You just save the time of the first and last touches, then compare them to see if the time in between is short enough. I've made the changes necessary in the code in the original post.

    Simply change the allowedTime variable in the swipe class to however long you choose.

  • dave1707dave1707 Mod
    Posts: 7,468

    @Ryzum You could start a timer when the touch state equals BEGAN and then when the touch state equals MOVING you could check the timer. When the timer reaches the value you want (1 or 2 sec), stop changing the x and y values and process the swipe. When the touch state equals ENDED, you can either process the swipe if it you didn't do it when MOVING, or ignore the swipe if you did it in MOVING.

  • Posts: 16

    Great ! Thanks.

Sign In or Register to comment.