# Touch and Drag to Move Question [ANSWERED]

A neophyte question… is there a simple way to code the ability to touch and move a graphic object (for example a game piece for a board game)?

I’ve looked through the examples and the shared code of others but can’t seem to find what I’m looking for…

As a start I’d love to have a rect() or ellipse() on the screen know when it is touched and dragged to another location (thus redrawn at the new co-ordinates).

Here’s a simple class that makes a rect you can drag around the screen.

``````-- DragMe
DragMe = class()

function DragMe:init()
self.pos = vec2(0,0)
self.size = 200
end

function DragMe:draw()
pushStyle()

fill(255,0,0)

rectMode(CENTER)
rect(self.pos.x, self.pos.y, self.size, self.size)

popStyle()
end

function DragMe:hit(point)
if point.x > (self.pos.x - self.size/2) and
point.x < (self.pos.x + self.size/2) and
point.y > (self.pos.y - self.size/2) and
point.y < (self.pos.y + self.size/2) then
return true
end
return false
end

function DragMe:touched(touch)
if self:hit( vec2(touch.x, touch.y) ) and
touch.state == MOVING then
self.pos = self.pos + vec2( touch.deltaX, touch.deltaY )
end
end
``````

And here’s the Main file:

``````-- Main
function setup()
box = DragMe()
end

function draw()
background(0)
box:draw()
end

function touched(touch)
box:touched(touch)
end
``````

Note that this won’t do touch tracking - that is, if you drag fast enough that your touch jumps out of the rect in one frame, the rect will lose tracking of the touch.

This can be fixed by checking if the touch hit on touch.state == BEGAN, and then tracking the position with the touch regardless until the touch state is ENDED.

Thanks a million Simeon! This is a great help!

I vote that something like this is included in the Codea examples.

Hi,

I’ve found this dragging example and I was able to adapt it to my needs so far.

Now I’d like to “mimic” the behaviour of the iOS icon pages: if I drag an object a little bit and release it, the object comes smoothly back to its original position; if I drag it past a certain distance, then it goes away and another will replace it.

Is there an example of this somewhere?

Thanks,

Pedro

I would look up tween. Just save the x,y of the start position when the object is touched and tween it with the release of the object. You might want to tackle touch first

@pvchagas here is an example

``````-- DragMe
DragMe = class()
local list = {}
local rnd = function() return math.random(255) end
function DragMe:init(x,y)
self.x = x or WIDTH/2
self.y = y or HEIGHT/2
self.size = 100
self.c = color(rnd(),rnd(),rnd())
table.insert(list,self)
end

function DragMe:draw()
pushStyle()

fill(self.c)

rectMode(CENTER)
rect(self.x, self.y, self.size, self.size)

popStyle()
end

function DragMe:hit(point)
if point.x > (self.x - self.size/2) and
point.x < (self.x + self.size/2) and
point.y > (self.y - self.size/2) and
point.y < (self.y + self.size/2) then
return true
end
return false
end
local d0 = 150
function DragMe:touched(touch)
if self:hit( touch ) then
if touch.state == BEGAN then
self.x0 = self.x
self.y0 = self.y
self.go = true
elseif touch.state == MOVING then
self.x = self.x+touch.deltaX
self.y = self.y+touch.deltaY
local d = vec2(self.x-self.x0,self.y-self.y0):len()
if  d >= d0 and self.go then
new = DragMe(self.x0,self.y0)
self.go = false
new.size = 0
tween(0.5,new,{size=100},tween.easing.elasticOut)
end
elseif touch.state == ENDED or touch.state == CANCELLED then
local d = vec2(self.x-self.x0,self.y-self.y0):len()
if  d < d0 then
tween(0.5,self,{x=self.x0,y=self.y0},
tween.easing.elasticOut)
end
end

end
end

-- Main
function setup()
DragMe()
end

function draw()
background(0)
for i,box in pairs(list) do box:draw() end
end

function touched(touch)
for i,box in pairs(list) do box:touched(touch) end
end

``````

@Simeon When I use this method and try to drag a rectangle, I get an output saying [string “DragMe = class()…”]:19: attempt to perform arithmetic on field ‘size’ (a nil value). Any advice?

you pbly wrote a `.` instead of a `:`

@Jmv38 I didn’t do that, but I found that I accidentally put “self.pos.size” instead of “self.size” . Thanks anyway!