Multi Touch problem [solved]

Hi,

I try to add multitouch zooming to one of my apps. When I played around with the sample app I noticed that my 2 fingers have to touch the screen exactly at the same time otherwise it won’t work.
I saw that multitouch behaviour has changed in the latest Corna Beta thats probably the reason for this.
Is there an update sample for multitouch zooming for the latest Corona Beta? I don’t want to use the build settings work aroud even if this might fix my current problem.

Thanks in advance,
Patrick. [import]uid: 4589 topic_id: 1176 reply_id: 301176[/import]

OK. I think I got it:

[code]

– Abstract: Multitouch sample app (pinch and zoom)

– Version: 1.0

– Disclaimer: IMPORTANT: This ANSCA software is supplied to you by ANSCA Inc.
– (“ANSCA”) in consideration of your agreement to the following terms, and your
– use, installation, modification or redistribution of this ANSCA software
– constitutes acceptance of these terms. If you do not agree with these terms,
– please do not use, install, modify or redistribute this ANSCA software.

– In consideration of your agreement to abide by the following terms, and subject
– to these terms, ANSCA grants you a personal, non-exclusive license, under
– ANSCA’s copyrights in this original ANSCA software (the “ANSCA Software”), to
– use, reproduce, modify and redistribute the ANSCA Software, with or without
– modifications, in source and/or binary forms; provided that if you redistribute
– the ANSCA Software in its entirety and without modifications, you must retain
– this notice and the following text and disclaimers in all such redistributions
– of the ANSCA Software.
– Neither the name, trademarks, service marks or logos of ANSCA Inc. may be used
– to endorse or promote products derived from the ANSCA Software without specific
– prior written permission from ANSCA. Except as expressly stated in this notice,
– no other rights or licenses, express or implied, are granted by ANSCA herein,
– including but not limited to any patent rights that may be infringed by your
– derivative works or by other works in which the ANSCA Software may be
– incorporated.

– The ANSCA Software is provided by ANSCA on an “AS IS” basis. ANSCA MAKES NO
– WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
– WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
– PURPOSE, REGARDING THE ANSCA SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
– COMBINATION WITH YOUR PRODUCTS.

– IN NO EVENT SHALL ANSCA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
– CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
– GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
– ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR
– DISTRIBUTION OF THE ANSCA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF
– CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
– ANSCA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

– Copyright © 2010 ANSCA Inc. All Rights Reserved.

– activate multitouch
system.activate( “multitouch” )

– add bkgd image to screen
local background = display.newImage( “aquariumbackgroundIPhone.jpg”, 0, 0 )

– create a table listener object for the bkgd image
function background:touch( event )
local result = true

local phase = event.phase

– when multitouch is active, the event will contain an array of
– all touch events that have changed since the last touch event
– these should all share the same phase
local touches = event.touches

– when multitouch is active, the event will contain an array of
– all touches that are still touching the screen from previous events
local previousTouches = event.previousTouches

local numTotalTouches = #touches
if ( previousTouches ) then
numTotalTouches = numTotalTouches + #previousTouches
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 stageBounds of button
display.getCurrentStage():setFocus( self )
self.isFocus = true
end

if ( not self.distance ) then
local dx,dy

if #touches >= 2 then
dx = touches[2].x - touches[1].x
dy = touches[2].y - touches[1].y
elseif previousTouches and ( numTotalTouches ) >= 2 then
dx = previousTouches[1].x - touches[1].x
dy = previousTouches[1].y - touches[1].y
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
elseif self.isFocus then
if “moved” == phase then

– ADDED –

if ( not self.distance ) then
local dx,dy

if #touches >= 2 then
dx = touches[2].x - touches[1].x
dy = touches[2].y - touches[1].y
elseif previousTouches and ( numTotalTouches ) >= 2 then
dx = previousTouches[1].x - touches[1].x
dy = previousTouches[1].y - touches[1].y
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

– END –

if ( self.distance ) then
local dx,dy
if #touches >= 2 then
dx = touches[2].x - touches[1].x
dy = touches[2].y - touches[1].y
elseif previousTouches and ( numTotalTouches ) >= 2 then
dx = previousTouches[1].x - touches[1].x
dy = previousTouches[1].y - touches[1].y
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
elseif “ended” == phase or “cancelled” == phase then
– if there are no previous touches, then there no more fingers will touch the screen
if ( not previousTouches ) then
– 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
elseif ( #previousTouches == 1 ) then
– must be at least 2 touches remaining to pinch/zoom
self.distance = nil
end
end
end

return result
end

– register table listener
background:addEventListener( “touch”, background )
[/code] [import]uid: 4589 topic_id: 1176 reply_id: 3142[/import]

I found the same problem with the sample code and modified it like you did. I also added the ability to move the image around on the screen similar to what you can do in the iPhone photo app. It only took a few extra lines of code.

Ansca should include this in their next updated SDK.

Tom [import]uid: 6119 topic_id: 1176 reply_id: 3144[/import]

@fogview

I would like to experiment with that a bit… would you be so kind to post your modification too? [import]uid: 6928 topic_id: 1176 reply_id: 3194[/import]

@OderWat

Here is my modified code. It does support pinch/zoom and single finger movement of the image. It also doesn’t require both fingers touch the screen at the same time.

The code is not totally complete because it doesn’t check for screen bounds (for image movement) and there is a bug where the image jumps position when touched after movement.

Tom

[code]

– activate multitouch
system.activate( “multitouch” )

– add bkgd image to screen
local background = display.newImage( “aquariumbackgroundIPhone.jpg”, 0, 0 )

– create a table listener object for the bkgd image
function background:touch( event )
local result = true

local phase = event.phase

txtTouchPhase.text = "touch Phase: " … event.phase

– when multitouch is active, the event will contain an array of
– all touch events that have changed since the last touch event
– these should all share the same phase
local touches = event.touches

– when multitouch is active, the event will contain an array of
– all stationary touch events since the last touch event
local previousTouches = event.previousTouches

local numTotalTouches = #touches
if ( previousTouches ) then
numTotalTouches = numTotalTouches + #previousTouches
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 stageBounds of button
display.getCurrentStage():setFocus( self )
self.isFocus = true
end

if ( not self.distance ) then
local dx,dy

if #touches >= 2 then
dx = touches[2].x - touches[1].x
dy = touches[2].y - touches[1].y
elseif previousTouches and ( numTotalTouches ) >= 2 then
dx = previousTouches[1].x - touches[1].x
dy = previousTouches[1].y - touches[1].y
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
elseif self.isFocus then
if “moved” == phase then
if ( self.distance ) then
local dx,dy
if #touches >= 2 then
dx = touches[2].x - touches[1].x
dy = touches[2].y - touches[1].y
elseif previousTouches and ( numTotalTouches ) >= 2 then
dx = previousTouches[1].x - touches[1].x
dy = previousTouches[1].y - touches[1].y
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
else – added

– ****** new code 6/7/10
– This fixes the problem where the second finger touches the screen after
– the “began” phase. Before this code was added you could only pinch and
– zoom if both fingers were touched at the same time.

local dx,dy

if #touches >= 2 then
dx = touches[2].x - touches[1].x
dy = touches[2].y - touches[1].y
elseif previousTouches and ( numTotalTouches ) >= 2 then
dx = previousTouches[1].x - touches[1].x
dy = previousTouches[1].y - touches[1].y
else
– Single Touch Moved
self.x = self.x + touches[1].x - self.x
self.y = self.y + touches[1].y - self.y
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 of new code
end

elseif “ended” == phase or “cancelled” == phase then
– if there are no previous touches, then there no more fingers will touch the screen
if ( not previousTouches ) then
– 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
elseif ( #previousTouches == 1 ) then
– must be at least 2 touches remaining to pinch/zoom
self.distance = nil
end
end
end

return result
end

txtTouchPhase = display.newText( “touch Phase: begin”, 45, 440, “Verdana-Bold”, 16 )
txtTouchPhase:setTextColor( 255,255,255 )

– register table listener
background:addEventListener( “touch”, background )

[/code] [import]uid: 6119 topic_id: 1176 reply_id: 3217[/import]

Cool! Thank you… I am going to extend this probably to something even more like the photo app later! [import]uid: 6928 topic_id: 1176 reply_id: 3219[/import]

@ Fogview,

Does Corona 2 beta 7 have multi-touch bug? I tested your code in corona2 b7 but got an error output: event.touches = nil
even got nill when tested it in iPad.

Tks first for your time. =)

[import]uid: 5377 topic_id: 1176 reply_id: 5088[/import]

I tried to recompile one of my apps yesterday but it didn’t work at all. It worked fine with Beta 5. From the console output I figured out that the problem is related to multitouch. I will look into this during the weekend. [import]uid: 4589 topic_id: 1176 reply_id: 5091[/import]