touch and multitouch

hey there,
im trying to make an image do 2 different functions depending if theres one finger or 2 fingers touching it.
the thing is i can make it so it can diffrentiate between 1 and 2 fingers touching it but it gives me an error.
im trying to make it drag a picture if 1 finger is dragged across the screen, and if there are 2 fingers that it will zoom in on the picture without dragging it, 

function backgroundmove( event ) if (touch==1) then if event.phase == "began" then background.markX = background.x -- store x location of object background.markY = background.y -- store y location of object elseif event.phase == "moved" then local x = (event.x - event.xStart) + background.markX local y = (event.y - event.yStart) + background.markY background.x, background.y = x, y -- move object based on calculations above end return true end end local function calculateDelta( previousTouches, event ) local id,touch = next( previousTouches ) if event.id == id then id,touch = next( previousTouches, id ) assert( id ~= event.id ) end local dx = touch.x - event.x local dy = touch.y - event.y return dx, dy end function scene:createScene( event ) function background:touch( event ) local result = true local phase = event.phase local previousTouches = self.previousTouches local numTotalTouches = 1 if ( previousTouches ) then -- add in total from previousTouches, subtract one if event is already in the array numTotalTouches = numTotalTouches + self.numPreviousTouches if previousTouches[event.id] then numTotalTouches = numTotalTouches - 1 end end if "began" == phase then -- Very first "began" event if ( not self.isFocus ) then -- Subsequent touch events will target button even if they are outside the contentBounds of button display.getCurrentStage():setFocus( self ) self.isFocus = true previousTouches = {} self.previousTouches = previousTouches self.numPreviousTouches = 0 elseif ( not self.distance ) then local dx,dy if previousTouches and ( numTotalTouches ) \>= 2 then dx,dy = calculateDelta( previousTouches, event ) end -- initialize to distance between two touches if ( dx and dy ) then local d = math.sqrt( dx\*dx + dy\*dy ) if ( d \> 0 ) then self.distance = d self.xScaleOriginal = self.xScale self.yScaleOriginal = self.yScale print( "distance = " .. self.distance ) end end end if not previousTouches[event.id] then self.numPreviousTouches = self.numPreviousTouches + 1 end previousTouches[event.id] = event elseif self.isFocus then if "moved" == phase then if ( self.distance ) then local dx,dy if previousTouches and ( numTotalTouches ) \>= 2 then dx,dy = calculateDelta( previousTouches, event ) end if ( dx and dy ) then local newDistance = math.sqrt( dx\*dx + dy\*dy ) local scale = newDistance / self.distance print( "newDistance(" ..newDistance .. ") / distance(" .. self.distance .. ") = scale(".. scale ..")" ) if ( scale \> 0 ) then self.xScale = self.xScaleOriginal \* scale self.yScale = self.yScaleOriginal \* scale end end end if not previousTouches[event.id] then self.numPreviousTouches = self.numPreviousTouches + 1 end previousTouches[event.id] = event elseif "ended" == phase or "cancelled" == phase then if previousTouches[event.id] then self.numPreviousTouches = self.numPreviousTouches - 1 previousTouches[event.id] = nil end if ( #previousTouches \> 0 ) then -- must be at least 2 touches remaining to pinch/zoom self.distance = nil else -- previousTouches is empty so no more fingers are touching the screen -- Allow touch events to be sent normally to the objects they "hit" display.getCurrentStage():setFocus( nil ) self.isFocus = false self.distance = nil self.xScaleOriginal = nil self.yScaleOriginal = nil -- reset array self.previousTouches = nil self.numPreviousTouches = nil end end end return result end end

the code is pretty much copy+paste, and then added something myself.
the thing is that i can see it registers the number of touches but when i drag the picture i get an error saying
 

"atempt to perfor arithmetic on field’markX’ (a nil value)
on the line         local x = (event.x - event.xStart) + background.markX
if i remove the if statement for touch==1 then i can drag it flawlessly but it will also move when i try to pinch zoom it

To start, I don’t see where, in the posted code, you are setting “touch = 1”. I’m going to assume it’s in a different portion, which increases/decreases the touch variable. 

Next, I’d suggest putting in print statements in your touch listener so that you can identify the value of the “touch” variable, and the markX/markY variables of the background object. That way you can see where and when the values are being modified, and from there check to see why markX is becoming nil somewhere.

i seemed to get it working by combining the 2 functions, fucks up a little if i put on 3+ fingers at the same time but i tried to make a a function on each frame to set make sure it doesnt get over 2 touches or below 0 touches.
cant see why it sometimes gives me -1 or -2 toches but it works-ish

Very interested in this, does RANDOM have more info on solution?

I’m trying to implement a multitouch to pinchzoom using standard script PLUS have another touch event attached to another graphic overlaying (or underneath) the graphic with the multitouch function.

On device, the 2 functions fight each other and the touch event (on top) wins.

is there any way for a touch event to exit when there is a multitouch event running?

So I work out how to get ‘normal’ touch events in the midst of the multitouch code.

See below.

I’ve dumped a lot of the code from the original example above, and show where I inserted code in BEGAN, MOVE and ENDED phases.

function mapContainer:touch( event )

local result = true

local phase = event.phase

… ETC

if “began” == phase then

– Very first “began” event

if ( not self.isFocus ) then

…ETC

----ADD HERE FOR BEGAN PHASE OF ONE TOUCH


elseif ( not self.distance ) then

local dx,dy

if previousTouches and ( numTotalTouches ) >= 2 then

dx,dy = calculateDelta( previousTouches, event )

end

– initialize to distance between two touches

if ( dx and dy ) then

…ETC

end

end

if not previousTouches[event.id] then

self.numPreviousTouches = self.numPreviousTouches + 1

end

previousTouches[event.id] = event

elseif self.isFocus then

if “moved” == phase and (not locked) then

if ( mapContainer.distance ) then

local dx,dy

if previousTouches and ( numTotalTouches ) >= 2 then

dx,dy = calculateDelta( previousTouches, event )

end

if ( dx and dy ) then

local newDistance = math.sqrt( dx*dx + dy*dy )

local scale = newDistance / mapContainer.distance

if ( scale > 0 ) then

…ETC

----ADD HERE FOR MOVE PHASE OF ONE TOUCH


end

end

----ADD HERE FOR MOVE PHASE OF ONE TOUCH

else


end

if not previousTouches[event.id] then

self.numPreviousTouches = self.numPreviousTouches + 1

end

previousTouches[event.id] = event

elseif “ended” == phase or “cancelled” == phase then

----ADD HERE FOR END OF ONE TOUCH


if previousTouches[event.id] then

self.numPreviousTouches = self.numPreviousTouches - 1

previousTouches[event.id] = nil

end

if ( #previousTouches > 0 ) then

…ETC

else

…ETC

----ADD HERE FOR END OF ONE TOUCH


end

end

end

return result

end

To start, I don’t see where, in the posted code, you are setting “touch = 1”. I’m going to assume it’s in a different portion, which increases/decreases the touch variable. 

Next, I’d suggest putting in print statements in your touch listener so that you can identify the value of the “touch” variable, and the markX/markY variables of the background object. That way you can see where and when the values are being modified, and from there check to see why markX is becoming nil somewhere.

i seemed to get it working by combining the 2 functions, fucks up a little if i put on 3+ fingers at the same time but i tried to make a a function on each frame to set make sure it doesnt get over 2 touches or below 0 touches.
cant see why it sometimes gives me -1 or -2 toches but it works-ish

Very interested in this, does RANDOM have more info on solution?

I’m trying to implement a multitouch to pinchzoom using standard script PLUS have another touch event attached to another graphic overlaying (or underneath) the graphic with the multitouch function.

On device, the 2 functions fight each other and the touch event (on top) wins.

is there any way for a touch event to exit when there is a multitouch event running?

So I work out how to get ‘normal’ touch events in the midst of the multitouch code.

See below.

I’ve dumped a lot of the code from the original example above, and show where I inserted code in BEGAN, MOVE and ENDED phases.

function mapContainer:touch( event )

local result = true

local phase = event.phase

… ETC

if “began” == phase then

– Very first “began” event

if ( not self.isFocus ) then

…ETC

----ADD HERE FOR BEGAN PHASE OF ONE TOUCH


elseif ( not self.distance ) then

local dx,dy

if previousTouches and ( numTotalTouches ) >= 2 then

dx,dy = calculateDelta( previousTouches, event )

end

– initialize to distance between two touches

if ( dx and dy ) then

…ETC

end

end

if not previousTouches[event.id] then

self.numPreviousTouches = self.numPreviousTouches + 1

end

previousTouches[event.id] = event

elseif self.isFocus then

if “moved” == phase and (not locked) then

if ( mapContainer.distance ) then

local dx,dy

if previousTouches and ( numTotalTouches ) >= 2 then

dx,dy = calculateDelta( previousTouches, event )

end

if ( dx and dy ) then

local newDistance = math.sqrt( dx*dx + dy*dy )

local scale = newDistance / mapContainer.distance

if ( scale > 0 ) then

…ETC

----ADD HERE FOR MOVE PHASE OF ONE TOUCH


end

end

----ADD HERE FOR MOVE PHASE OF ONE TOUCH

else


end

if not previousTouches[event.id] then

self.numPreviousTouches = self.numPreviousTouches + 1

end

previousTouches[event.id] = event

elseif “ended” == phase or “cancelled” == phase then

----ADD HERE FOR END OF ONE TOUCH


if previousTouches[event.id] then

self.numPreviousTouches = self.numPreviousTouches - 1

previousTouches[event.id] = nil

end

if ( #previousTouches > 0 ) then

…ETC

else

…ETC

----ADD HERE FOR END OF ONE TOUCH


end

end

end

return result

end