BitFive: Now with multitouch

This is only a small thing out of everything I need to make/finish/release in next months, but...
So there is now multi-touch support in openfl-bitfive, which is an alternative OpenFL HTML5 backend with focus on blitting and compatibility across platforms.
Usage is identical to Flash/AIR - you add an according event listener to your desired DisplayObject, and handle the TouchEvent objects it catches:

stage.addEventListener(TouchEvent.TOUCH_BEGIN, function(e) {
	trace("Touched at (" + e.stageX + ", " + e.stageY + ")");
});

And, same as it goes for mouse events, the rest is handled behind the scenes - events are routed automatically, and you don't need to worry about browsers and devices with partial or glitchy support.
You can even have your mouse events converted into touch events for ease of testing if you want (see bitfive_mouseTouches flag).

Addition is already live at both repository and haxelib, there's a demo available (probably want to view it from mobile device), and this post contains some extra details on what it took.
Also, if you needed this for some time, you can pretty much thank Ozdy (which is also the largest supporter of backend) for suggesting the feature.

The reason of why this wasn't added initially is simple, but also is not.

Inner works

In openfl-bitfive, every time you bind an event to DisplayObject, it is actually bound to two instances - an internal representation of DisplayObject (which you interface with), and an actual HTML DOM element that represents it on stage.

Since HTML DOM hierarchy matches up with Flash DOM, this also means that multiple event types can traverse the stage without any help from library whatsoever. This also allows you to block keyboard shortcuts via preventDefault() and some other nice things.

This applies to keyboard events, focus events, applied to mouse events until recently (changed to manual handling to mimic Flash behaviour better), and many others.

Subtle differences

However, in all it's usefulness, this method could not be applied to touch events.
And not because of some complicated technical issue (although there is about a half hundred lines changed for this), but simply because the touch event API does not quite match between Flash and HTML5.

In Flash, every touch is wrapped in it's own TouchEvent, which shares a fair deal of properties with MouseEvent, and also has a couple of important ones like touch radius (sizeX/sizeY), pressure (if supported), and, most importantly, touch point index (which allows you to tell the touches apart):

TouchEvent = {
	stageX:Float, stageY:Float,
	localX:Float, localY:Float,
	sizeX:Float, sizeY:Float,
	pressure:Float,
	touchPointID:Float,
	// ...
}

In HTML5, however, touch points are implemented differently. A single TouchEvent is dispatched at once, which contains some of properties (such as special keys held), and several arrays of Touch objects, which represent the actual touches (and slightly resemble Flash TouchEvent objects):

TouchEvent = {
	touches:Array<Touch>,
	changedTouches:Array<Touch>,
	targetTouches:Array<Touch>,
	// ...
}
Touch = {
	pageX:Float, pageY:Float,
	radiusX:Float, radiusY:Float,
	force:Float,
	identifier:Int,
	// ...
}

Solution was to catch HTML touch events right on Stage (HTML window, to be precise), create a Flash/OpenFL TouchEvent object for each of touches, find affected (currently hovered) objects, and dispatch them into those.
And, since events are being listened to at Window, this will also work on pretty much all devices possible.

So... yeah, that's it pretty much. Now make some games (or apps) with multitouch 🙂

Related posts:

One thought on “bitfive: Now with multitouch

Leave a Reply

Your email address will not be published. Required fields are marked *