Multiple Touch Presses, Different Screen Positions

Terrible subject line, hard to describe.

Say I’m trying to make a 2 player game. So I’ve got 4 buttons, 1 at each corner of the screen. Pressing a button down makes your piece move to the left, releasing it makes it stop moving left, another does right movement, etc.

The problem I’m coming up against… and I’m really hoping this is just something silly I’m doing… is right now when I have one button pressed down I cannot press down anywhere else and have it detected.

I’ve tried this with the ui buttons, with display objects, with one giant rectangle that has focus, etc. It seems once I put a finger down, putting another finger down goes undetected. I was hoping with multitouch this would no longer be an issue, but I guess I’m doing it wrong.

Anyone have any suggestions or *know* this is incorrect and I’m just doing something silly?

Thanks,
Scott [import]uid: 5659 topic_id: 1119 reply_id: 301119[/import]

Hi scott,

I am just guessing here, but with multitouch you have to write your own handling mechanism.
The button approach with the touch events won’t get you far I think.

I will see if I can come up with something fast. Wanted to write a joypad lib anyway :slight_smile:

Cheers
Michael Hartlef

http://www.whiteskygames.com
http://www.twitter.com/mhartlef [import]uid: 5712 topic_id: 1119 reply_id: 2871[/import]

Hi Scott,

I think the current multitouch support is not really usable. Like for an example, once multitouch is activated, it seems that there is no event fired with just one touch. Also the framerate then goes down in the basement to be non existant. I will post a bug about that.

Plus I was wondering why the sample from Ansca ran so unresponsive. Here is my test file:

[lua]-- activate multitouch
system.activate( “multitouch” )
local tPrevious= 0

txtfps = display.newText( “fps:99”, 240, 20, “Verdana-Bold”, 16 )
txtfps:setTextColor( 0,0,255 )
txtTouch = display.newText( “ctouches:99”, 40, 20, “Verdana-Bold”, 16 )
txtTouch:setTextColor( 0,0,255 )
txtTouch.text = “ctouches:”…0

txtTouchp = display.newText( “ptouches:99”, 40, 60, “Verdana-Bold”, 16 )
txtTouchp:setTextColor( 0,0,255 )
txtTouchp.text = “ptouches:”…0

local finish = function(target)
target.parent:remove( target )
end
local mRandom = math.random

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

–local phase = event.phase
–print (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
txtTouch.text = “ctouches:”…#touches
txtTouchp.text = “ptouches:”…#previousTouches

– for i = 1,#touches do
– spr = display.newCircle(touches[i].x, touches[i].y, 10 )
– spr:setFillColor(255,0,255,255)
– transition.to(spr,{time=100, x=touches[i].x+mRandom(-40,40), y=touches[i].y+mRandom(-40,40), onComplete=finish})
– end

– for i = 1,#previousTouches do
– spr = display.newCircle(previousTouches[i].x, previousTouches[i].y, 10 )
– spr:setFillColor(0,0,255,255)
– transition.to(spr,{time=100, x=previousTouches[i].x+mRandom(-40,40), y=previousTouches[i].y+mRandom(-40,40), onComplete=finish})
– end

end

local onFrame = function(event)
local tDelta = event.time - tPrevious
tPrevious = event.time
txtfps.text = “fps:”…tDelta
collectgarbage(“collect”)
end

– register table listener
Runtime:addEventListener( “touch”, onTouch )
Runtime:addEventListener( “enterFrame”, onFrame )[/lua] [import]uid: 5712 topic_id: 1119 reply_id: 2876[/import]

Thanks for looking into it Mike. And that’s the exact same conclusion I came up with. hehe.

Buttons didn’t work.

Just plan display objects didn’t work.

So I figured I’d just handle it all myself with the multitouch system and my background image.

Same results as you, as soon as a finger is down, no new finger touches create any events. This is a major problem for any 2 player games since either player can simply hold down their finger and lock out the other one. /grin

Ideally, for me, I want to actually implement my touches in this very fashion once gameplay has started. I want one big background object to have the focus and I want to handle my own touches on the screen.

Specifically, I want to be able to look for a press and move in the x direction within a given y range. I would also handle my own “button” presses within this context.

Basically, I need an interface that let’s me continue to receive new press events regardless of whether or not someone has their finger already down and pressed on the surface (or multiple fingers).

Thanks again Mike. :slight_smile:

Scott [import]uid: 5659 topic_id: 1119 reply_id: 2878[/import]

I’ve played a little with the code and I’m not sure multitouch is really broken. Running Mike test program showed an error when displaying the number of previousTouches. The problem is event.previousTouches is a table that is “nil” when only one finger is touching the display. This generated a run-time error (can’t return the count of a nil object). I fixed that problem and the test code acts a lot better. I was able to detect up to four fingers on the display.

I modified the code adding a touch counter and event phase. I’m not sure the multitouch is 100% working because I haven’t looked at all the event being generated. I commented out the original code that was causing the errors.

Tom

[code]
– activate multitouch
system.activate( “multitouch” )
local tPrevious= 0
local touchCnt = 0 – total number of touches

txtfps = display.newText( “fps:99”, 240, 20, “Verdana-Bold”, 16 )
txtfps:setTextColor( 255,255,255 )

txtTouch = display.newText( " ctouches: 99", 40, 20, “Verdana-Bold”, 16 )
txtTouch:setTextColor( 255,255,255 )
txtTouch.text = " ctouches: "…0

txtTouchp = display.newText( " ptouches: 99", 40, 60, “Verdana-Bold”, 16 )
txtTouchp:setTextColor( 255,255,255 )
txtTouchp.text = " ptouches: "…0

txtTouchc = display.newText( “touch cnt: 0”, 40, 100, “Verdana-Bold”, 16 )
txtTouchc:setTextColor( 255,255,255 )

txtTouchType = display.newText( “previousTouch Type: nil”, 45, 400, “Verdana-Bold”, 16 )
txtTouchType:setTextColor( 255,255,255 )

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

local finish = function(target)
target.parent:remove( target )
end
local mRandom = math.random

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

–local phase = event.phase
–print (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

touchCnt = touchCnt + 1

–[[
txtTouch.text = “ctouches:”…#touches
txtTouchp.text = “ptouches:”…#previousTouches – *** This will cause error if “nil” ***
–]]
txtTouch.text = "ctouches: " … tostring(type(touches) ~= “nil” and #touches)
txtTouchp.text = "ptouches: " … tostring(type(previousTouches) ~= “nil” and #previousTouches)

txtTouchc.text = "touch cnt: " … touchCnt
txtTouchType.text = "previousTouches Type: " … type(event.previousTouches)
txtTouchPhase.text = "touch Phase: " … event.phase

– for i = 1,#touches do
– spr = display.newCircle(touches[i].x, touches[i].y, 10 )
– spr:setFillColor(255,0,255,255)
– transition.to(spr,{time=100, x=touches[i].x+mRandom(-40,40), y=touches[i].y+mRandom(-40,40), onComplete=finish})
– end

– for i = 1,#previousTouches do
– spr = display.newCircle(previousTouches[i].x, previousTouches[i].y, 10 )
– spr:setFillColor(0,0,255,255)
– transition.to(spr,{time=100, x=previousTouches[i].x+mRandom(-40,40), y=previousTouches[i].y+mRandom(-40,40), onComplete=finish})
– end

end

local onFrame = function(event)
local tDelta = event.time - tPrevious
tPrevious = event.time
txtfps.text = "fps: "…tDelta
collectgarbage(“collect”)
end

– register table listener
Runtime:addEventListener( “touch”, onTouch )
Runtime:addEventListener( “enterFrame”, onFrame )
[/code] [import]uid: 6119 topic_id: 1119 reply_id: 2881[/import]

One more comment about the above problem. I only found the run-time error because I tried to run it in the simulator and was lucky that the problem code was able to execute. When I first started to simulate the code it said that Multitouch was not supported in the simulator. If I stopped there the problem would have gone unnoticed. Running the code on the device showed no sign of the problem except that Multitouch didn’t seem to work and the first conclusion was a bug in the Corona SDK.

If I was running this under Xcode (and Objective C), the debugger would have showed the problem. Since none of that is possible under the Corona SDK, this a problem and another reason to push for some type of debugger or terminal that is active when running Corona programs on a real device.

From Ansca’s point of view, without any real-time debugger or terminal, issues like this will cause concern about the Corona SDK and most likely spend countless hours dealing with problems like this because the developer has no clue that he did anything wrong.

Anyway, just my two cents.
Tom
[import]uid: 6119 topic_id: 1119 reply_id: 2882[/import]

I’ll have to test your code, but the problem being described is that once a finger is pressed, a single one, if you then put another finger down, that does not generate an event.

At least it did not in my stuff. I’ll take a look at yours and see tho.

EDIT: Yup, tested it. Once you have one finger down and pressed, there are no events fired for any additional fingers that touch.

Scott [import]uid: 5659 topic_id: 1119 reply_id: 2884[/import]

Hi Scott,

One fingers generates a “ctouches” count. A second, third, etc. finger increments the “ptouches” count. You should see that in my modified code. I added the Touch Count so you can see when a touch is registered.

Tom [import]uid: 6119 topic_id: 1119 reply_id: 2885[/import]

Hi Tom,

Ran your code… we’re posting circles around each other on the two threads.

:slight_smile:

I threw this out to my ipad as it’s easier to test there. Once you are pressing one finger down (you have to be still so it doesn’t generate any move events) and you press another following that (note not at the same time, wait at least 2 seconds) there is no event generated.

I would be happy as a pig in poo to be wrong about this, but I’m not seeing it.

Want to prove me wrong? Please do! Draw two squares and move them with two separate fingers. Press 1 and start moving it, then press the 2nd and start moving it. If you can get that to work I’ll be your best friend forever. :slight_smile:

Scott [import]uid: 5659 topic_id: 1119 reply_id: 2888[/import]

Hi Scott,

I guess we are posting in circles on two different threads. :slight_smile:

First off, my response (and code posting) was in response to Mike’s post about not getting a single finger event trigger in Multitouch mode. I think my modified code showed that you do get a single finger event as well as detecting a multitouch event.

If I use the existing sample code I do notice an issue concerning your requirements. Going back to your example (from another thread), if I press my left index finger on the screen and move it around, I get triggers and “moved” phase. If I then touch my right index finger, I detect that with ptouches going from false -> 1. While holding both fingers on the screen, if I move my left index finger (the first finger touched), I see event triggers for the movement. If I move my right index finger (the second finger touched), there is less event triggers for the movement. I think this would translate with being able to drag one box with your left finger but not able to drag the second box at the same time with the second finger.

My conclusion is the Multitouch feature is optimized for pinch/zoom gestures and not for true multitouch detection (and dragging). My guess is you could detect multiple fingers touching the screen but not independent dragging, which may have been the design requirement for this feature. It may come down to how you define “multitouch.”

BTW, I’m testing this on my iPhone 3GS. I’ll put it on my iPad and see if I notice a difference.

I guess I’m out of the running for your “best friend forever.” :frowning:

Tom [import]uid: 6119 topic_id: 1119 reply_id: 2890[/import]

Thank Tom for clearing up my LUA mistake! [import]uid: 5712 topic_id: 1119 reply_id: 2891[/import]

Ahh I see what you were correcting.

Yah, I’m not clear why this hasn’t been available from the get-go with Corona.

I guess I should open a separate bug thread then specifically in regards to this.

Bottom line, detecting two (or 4 or more) “button presses” and “button releases” should be something which is supported in Corona.

On top of that, it truly seems like multitouch support would be better served by supporting a similar model to what we already have, namely, each new (as in not there initially) finger press should generate a “began” event so that finger can be tracked separately… should one want to.

For games (especially two player) having *at least* the button press/release tracking for multiple buttons (multiple objects if it needs to be done that way) is required. Being able to track multiple “fingers” on one large object (press and release) would be ideal (think about implementing an air hockey game).

Scott [import]uid: 5659 topic_id: 1119 reply_id: 2893[/import]

In playing with this more it looks like the event detection is optimized for multitouch “gesture” detection (pinch/zoom). If I touch the screen with my left index finger and hold it really still and then touch the screen with my right index finger, there is no touch event for the right finger. Only if I generate an event for the left finger (moving my finger) will it register the second finger touch.

The same thing happens if I remove the second finger – no event occurs until the left finger is moved and then it shows that the right finger was removed.

I must also correct what I said in a previous post about seeing events for moving the second finger. I’m not seeing that happen and I think I was seeing my movement of the left finger while I was moving the right finger.

From what I’m seeing this morning (under the light of a new day) is only the first finger generates touch events and when an event occurs, it will show if other fingers are present and moved (?).

I think lots of people associate multitouch with pinch/zoom gestures and I think that is supported with Corona’s multitouch implementation. What’s not supported is “true multitouch” where you get began/moved/ended events for every finger touching the display.

Tom [import]uid: 6119 topic_id: 1119 reply_id: 2894[/import]

Damn! So I can’t write my 1 vs 1 mode! This is a huge problem.
If you (Ansca) release a Game Edition you should have thought at this! [import]uid: 7022 topic_id: 1119 reply_id: 3876[/import]

This is indeed a problem for my pinball-type game (where a player should be able to fire both flippers at the same time) as well. Does anyone know of a workaround or changes coming down the pipeline? [import]uid: 5232 topic_id: 1119 reply_id: 3881[/import]