Am I missing something with multitouch, I know in as3 you add:
Multitouch.inputMode=MultitouchInputMode.TOUCH_POINT;
to allow the user to use more than one finger at a time. Bt even with this line, on my app, only one finger is picked up.
Any ideas?
Am I missing something with multitouch, I know in as3 you add:
Multitouch.inputMode=MultitouchInputMode.TOUCH_POINT;
to allow the user to use more than one finger at a time. Bt even with this line, on my app, only one finger is picked up.
Any ideas?
You should only need to set:
Starling.multitouchEnabled = true;
before creating your Starling instance and multitouch should work
I have:
Starling.multitouchEnabled = true; _starling = new Starling(StarlingViewport, stage); _starling.simulateMultitouch = true; _starling.start();
But still no luck, any ideas?
Are you testing on a real touch device? You don't need/want simulateMultitouch at true if you are. Maybe your touch processing code isn't working as you expect to find all the touch events that might be happening...
I've taken _starling.simulateMultitouch = true; out but the issue persists.
I'm testing on an iphone 4.
Here's the code that deals with the touches, perhaps something is wrong here?
private function addZombieEventListeners(e:Event):void{ leftThumbImage.addEventListener(TouchEvent.TOUCH, goForward); } private function goForward(e:TouchEvent):void{ var touch:Touch = e.getTouch(stage); if ( touch.phase == TouchPhase.BEGAN) { //do something here } }
Yes, there is your problem
Take a closer look at the methods (and code if you are willing) of starling.events.TouchEvent. Also look at the sample code of the class TouchSheet in the demos.
Doing e.getTouch(stage) is going to just pick the first active touch every time.
If you want to handle multiple touches you really want to call e.getTouches(...) with possibly optional filtering on what phase you want (or looking at the phase of each touch returned)
Ok, thanks, I shall take a look!
I've checked out the demo and implemented the following, with still no luck. You still cannot do 2 touches on screen, any help would be appreciated!
private var touchesBegan:Vector.<Touch>; private var touchesEnded:Vector.<Touch> private function addEvents():void{ leftThumbImage.addEventListener(TouchEvent.TOUCH, thumbDown); rightThumbImage.addEventListener(TouchEvent.TOUCH, thumbDown); } private function thumbDown(e:TouchEvent):void{ touchesBegan = e.getTouches(this, TouchPhase.BEGAN); touchesEnded = e.getTouches(this, TouchPhase.ENDED); for (var i:int=0; i<touchesBegan.length;i++){ if(touchesBegan[i].target.name == "leftThumb"){ leftThumbImage.x = 5 leftThumbImage.y = 483 goForward(); } else if(touchesBegan[i].target.name == "rightThumb"){ rightThumbImage.x = 800 rightThumbImage.y = 483 goForward(); } } for (var n:int=0; n<touchesEnded.length;n++){ if(touchesEnded[n].target.name == "leftThumb"){ leftThumbImage.x = 0 leftThumbImage.y = 488 } else if(touchesEnded[n].target.name == "rightThumb"){ rightThumbImage.x = 805; rightThumbImage.y = 488; } }
Unfortunately you aren't really providing enough code to see where your problem lies.
Try doing some basic debugging and tracing.
Where are things not working? Are you getting no touchesBegan or touchesEnded?
I see you are showing floating code that removes touch handlers on your objects you are calling leftThumbImage, rightThumbImage, but then in your e.getTouches calls you are passing a 'this' what exactly is the 'this'? You aren't showing us what class your thumbDown method even lives in.
Since you show lines like leftThumbImage.removeEventListener(TouchEvent.TOUCH, thumbDown); we can only assume that somewhere else in your code you are doing?
leftThumbImage.addEventListener(TouchEvent.TOUCH, thumbDown);?
If so,
then your thumbDown method can do things like
to give you a direct list of touches on the target leftThumbImage instead of having to check
e.getTouches(leftThumbImage, TouchPhase.BEGAN);
.target.name everywhere.
It seems like if you are adding touch handlers on your leftThumbImage and rightThumbImage sprites, you should be passing them to your e.getTouches() calls and not 'this'.
Right Ive simplified things for testing purposes.
In my code event listeners are added to a right and left thumb image:
leftThumbImage.addEventListener(TouchEvent.TOUCH, thumbDown); rightThumbImage.addEventListener(TouchEvent.TOUCH, thumbDown);
The thumb down method has this in it
private function thumbDown(e:TouchEvent):void{ trace('thumb down'): }
The problem is that the trace fires when you press the left or right thumb, but when you press the left thumb and keep your finger on it, the right one does not fire.
I'm not sure how to implement the touches vector part with touch began and touch ended.
Heres my sudo code for what I want:
private function thumbDown(e:TouchEvent):void{ //left thumb down //animate thumb down //left thumb up //animate thumb up //right thumb down //animate thumb down //right thumb up //animate thumb up }
Any help would be greatly appreciated.
Thanks!
Providing even less code doesn't really help to see where you might be tripping up.
Things like e.getTouches(leftThumbImage, TouchPhase.BEGAN) and e.getTouches(leftThumbImage, TouchPhase.ENDED) should give you the different arrays of touches, but it looks like you aren't currently even concerned about multiple touches on one sprite so even e.getTouch(leftThumbImage, TouchPhase.BEGAN) would return any active begin touch on the leftThumbImage, for example.
You could also follow the style of the demo code in TouchSheet where each of your thumb sprites tracks and handles its own touches and not share a common thumbDown handler that just complicates checking multiple objects.
I also faced a problem with multitouch.
Platform used : Flash Builder
SDK : Adobe air 3.1 (Flex 4.6)
Problem : Multitouch not working. Only single touch working.
Code issue : Definitely not, using the sample TouchSheet codes. Moreover, simulatemultitouch works. But I need it to work with the hardware.
Hardware issue : Not hardware issue because sample app works if I compile it using Flash Player 11.0
I've split each thumb so each has its own event listener. I add my event listeners:
leftThumbImage.addEventListener(TouchEvent.TOUCH, leftThumbDown); rightThumbImage.addEventListener(TouchEvent.TOUCH, rightThumbDown);
And here is the code that deals with them. When I have my finger on the leftThumbImage the trace appears fine. But when I keep my finger on the leftThumbImage and press the right one, the right thumb trace does not work. It's as if multitouch is nto working on the device at all. The events fire fine with just one finger on the screen but not with two.
private function leftThumbDown(e:TouchEvent):void{ var leftThumbTouches:Vector.<Touch> = e.getTouches(this, TouchPhase.BEGAN); if (leftThumbTouches.length == 1) { trace('left thumb touch begin'); } } private function rightThumbDown(e:TouchEvent):void{ var rightThumbTouches:Vector.<Touch> = e.getTouches(this, TouchPhase.BEGAN); if (rightThumbTouches.length == 1) { trace('right thumb touch begin'); } }
(make sure you are using Adobe AIR 3.2 RC SDK to build and deploy your project, AIR 3.1 does not have Stage3D support for mobile)
@jefflemon Make sure you have Starling.multitouchEnabled = true; enabled in your main startup class before you start the Starling instance.
You should also be passing 'leftThumbImage' and 'rightThumbImage' into your calls to e.getTouches() and not 'this' as I mentioned earlier.
I just tested the following bit of code to simulate what you are trying to do and when I deployed this on an actual mobile device with captive AIR SDK 3.2 it worked as you wanted. I.e. I could leave a touch on the leftThumb (red square) and I could separately touch the other rightThumb (green square) and receive traces (even when using the same handler callback). There must be something in your configuration or development deployment that is not set right...
... Starling.multitouchEnabled = true; mStarling = new Starling(Game,stage); ...
package { import starling.display.Quad; import starling.display.Sprite; import starling.display.Stage; import starling.events.Event; import starling.events.TouchEvent; import starling.events.TouchPhase; public class Game extends Sprite { private var leftThumb:Quad; private var rightThumb:Quad; public function Game() { addEventListener(starling.events.Event.ADDED_TO_STAGE, onAdded); } private function onAdded(e:Event):void { leftThumb = new Quad(50, 50); leftThumb.color = 0xff0000; leftThumb.x = leftThumb.y = 10; leftThumb.addEventListener(TouchEvent.TOUCH, onTouch); stage.addChild(leftThumb); rightThumb = new Quad(25, 25); rightThumb.color = 0x00ff00; rightThumb.x = rightThumb.y = 150; rightThumb.addEventListener(TouchEvent.TOUCH, onTouch); stage.addChild(rightThumb); } private function onTouch(e:TouchEvent):void { if (e.getTouches(leftThumb, TouchPhase.BEGAN).length > 0) trace('touches began on leftThumb'); if (e.getTouches(leftThumb, TouchPhase.ENDED).length > 0) trace('touches ended on leftThumb'); if (e.getTouches(rightThumb, TouchPhase.BEGAN).length > 0) trace('touches began on rightThumb'); if (e.getTouches(rightThumb, TouchPhase.ENDED).length > 0) trace('touches ended on rightThumb'); } } }
I tried it, but still doesn't work. Thing is, I'm developing app for adobe air to run on Desktops, not mobile. I tried on a 23inch monitor with Dual-Touch.
The native Flash TouchEvent works fine. The old version of starling also works.
But I tried the latest starling with adobe air 3.2, still no luck.
Any idea what's the problem?
@clementyew Daniel would have to chime in on this, but now that you mention you are working on a multitouch desktop system and that your code worked with an earlier version of Starling, it sounds like it might have to do with the current implementation of starling.core.Starling.touchEventTypes()
The latest drop implements it as:
private function get touchEventTypes():Array { return Mouse.supportsCursor || !multitouchEnabled ? [ MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_MOVE, MouseEvent.MOUSE_UP ] : [ TouchEvent.TOUCH_BEGIN, TouchEvent.TOUCH_MOVE, TouchEvent.TOUCH_END ]; }
and as you can see, if you are on a system that supports cursor, Starling is not going to include TouchEvents only MouseEvents.
An earlier version of Starling would return both types.
return [ TouchEvent.TOUCH_BEGIN, TouchEvent.TOUCH_MOVE, TouchEvent.TOUCH_END, MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_MOVE, MouseEvent.MOUSE_UP ];
but Daniel changed this about 2 months back with a log of: "changed which mouse/touch event types are processed (because both are dispatched simultaneously in certain environments)"
Not sure if this is related to your issue...
@Jeff thanks for all your help, it works after all this it appears that I had:
Starling.multitouchEnabled = true;
after my starling initiation and not before. Thanks for all your help, very much appreciated.
Ah great to hear your issues are resolved jefflemon, sometimes it is the simple fixes
Technically, I think Starling could be changed to reset the touch event handlers if this were changed even after a Starling instance was created, but currently this setup only happens in the constructor call.
That might be it. Is this considered a bug then? Because on desktops with multitouch screens, mouse and touchevents are fired together.
Normally the mouse would be considered as the "First touch". However, the app I'm creating requires multi-touch. I am trying to develop apps using starling as i feel it's a great performance boost. Any idea how can I solve this issue?
Hm ... yes, you can consider that a bug. I've had quite a few problems with Flash's MouseEvents vs. TouchEvents, that's why I made the change Jeff mentioned above (checking for a mouse cursor) for now.
But that's already on my TODO list, I'll see if I find a better way!
BTW, thanks for all your help in this thread, Jeff!!
I am also having this problem, the app is developed using the AIR 3.2 SDK with Starling v1.0 and is running on a windows 7 desktop machine with a multitouch enabled screen. The final deployment will be on a 52 inch touch table also running Windows 7 so will also return Mouse.supportsCursor = true which i think is part of the problem.
On Starling v0.91 there isn't a problem with multiple touches, but the event.touches.length always returns 1 regardless of how many touches i place on the screen in Starling v1.0 (or the latest build off GitHub for that matter)
When i change the code in Starling.as
from:
private function get touchEventTypes():Array
{
return Mouse.supportsCursor || !multitouchEnabled ?
[ MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_MOVE, MouseEvent.MOUSE_UP ] :
[ TouchEvent.TOUCH_BEGIN, TouchEvent.TOUCH_MOVE, TouchEvent.TOUCH_END ];
}
to the code from the v0.91 build:
private function get touchEventTypes():Array
{
return [ TouchEvent.TOUCH_BEGIN, TouchEvent.TOUCH_MOVE, TouchEvent.TOUCH_END];
}
it allows multiple touches, but this causes a problem with some cases in the TouchProcessor.as class (when dragging a finger from a non-starling object added to the native display list onto the stage, this throws an error with the touch.target being null in the advance time method)
It seems these issues are related to Daniel's problems with Flash's MouseEvents vs TouchEvents.
I think i can hack the problem for now but just thought i would post my findings here in case they were useful.
Unfortunately, I haven't yet had the chance to look at this issue ... my main problem is the lack of a test environment with both mouse and touchscreen ... so if anyone knows of a cheap way to test that, I'm all ears!
In the meantime, I hope you can live with the hack. :-\
Dear @jefflemon, I am here as I faced the same problem: When I testing my little demo on a real multi-touch device, my 2nd touch point doesn't fire.
I noticed you mention that you make:
Starling.multitouchEnabled = true;after starling initiation and not before.
However I don't have any luck even if I did the same.
package { import flash.display.Sprite; import net.hires.debug.Stats; import starling.core.Starling; [SWF(frameRate="60", width="800",height="600",backgroundColor="0x333333")] public class myStarlingTest extends Sprite { private var stats:Stats; private var myStarling:Starling; public function myStarlingTest() { stats = new Stats(); this.addChild(stats); trace("Starling.VERSION:"+Starling.VERSION); trace("Starling.multitouchEnabled:"+Starling.multitouchEnabled); myStarling = new Starling(TouchTest, stage); Starling.multitouchEnabled = true; // useful on mobile devices trace("Starling.multitouchEnabled:"+Starling.multitouchEnabled); // emulate multi-touch myStarling.simulateMultitouch = true; trace("Starling.multitouchEnabled:"+Starling.multitouchEnabled); myStarling.antiAliasing = 1; myStarling.start(); Starling.multitouchEnabled = true; // Enable the Multitouch in Starling trace("Starling.multitouchEnabled:"+Starling.multitouchEnabled); } } }
I traced the "Starling.multitouchEnabled" everywhere but received the same result: false.
It seems that this code line:
Starling.multitouchEnabled = true;doesn't work.
Could you kindly tell me where did you put this code line?
Really appreciated!
There are a few posts at the end of the topic that mention this setting only works if it is *before* you do 'new Starling'.
That still does not address the underlying issues with devices with mouse and touchscreens.
Hey Daniel, how is your progress with the mouse and touchscreen issue?
I think that this can open a the door to implement Starling with multimedia kiosks and many other opportunities.
Thank“s for your work!
Hi there,
I had the same problem at a windows 7 touch device. Didn't get any multitouch event.
So I did what Jeff suggested. I changed
private function get touchEventTypes():Array { return Mouse.supportsCursor || !multitouchEnabled ? [ MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_MOVE, MouseEvent.MOUSE_UP ] : [ TouchEvent.TOUCH_BEGIN, TouchEvent.TOUCH_MOVE, TouchEvent.TOUCH_END ]; }
back to
return [ TouchEvent.TOUCH_BEGIN, TouchEvent.TOUCH_MOVE, TouchEvent.TOUCH_END, MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_MOVE, MouseEvent.MOUSE_UP ];
It worked fine then except I have a weird behaviour now. It seems like I get both Mouse- and Touch-Events at the same time. But not sure. Could that be possible?
What I do is storing the time on TOUCH_BEGIN and checking on TOUCH_END if it's less then 200 msec to simulate TAP Events. Or maybe there is another way to do that?
Thanks for answers!
Stefan
Stefan, the fact that you can get both at the same time was the reason Daniel is not using the alternate code version of always including all the types, all the time.
This is the open issue alluded to at the end of the topic.
There is another property mentioned in this related topic:
http://forum.starling-framework.org/topic/starlingmultitouchenabled-true-not-registering-and-storing-boolean
Maybe if you turn off flash.ui.Multitouch.mapTouchToMouse in conjunction with the code change that would eliminate the 'both events'.
(Don't have such a device to test if that makes the solution for the alternate code viable or not)
Thank you for the fast answer. I can test that only on Monday. I will post the results then.
I tried it with turning off flash.ui.Multitouch.mapTouchToMouse but unfortunately it didn't work. Still got two events at once.
But since I only need Touch events on the device I did it like this:
return Multitouch.supportsTouchEvents ? [ TouchEvent.TOUCH_BEGIN, TouchEvent.TOUCH_MOVE, TouchEvent.TOUCH_END ] : [ MouseEvent.MOUSE_DOWN, MouseEvent.MOUSE_MOVE, MouseEvent.MOUSE_UP ] ;
Works fine for me.
By the way, it's a TUIO Screen.
You must log in to post.