A pure haXe gesture engine

922 views
Skip to first unread message

Rocks Wang

unread,
Dec 12, 2012, 1:08:18 PM12/12/12
to haxe...@googlegroups.com
Hi all,

I've just completed a gesture engine, it's pure haXe, so supposed to be cross platform, however I just tested in Android, I hope someone here could help me to test it against more targets, iOS, mac, html5 etc.
It's opensource and free, please feel free to report bugs to me in this thread or via mail.
Here's the feature list:
* support tap, long press, pan, swipe on all targets.
* support pinch & rotation on multi-touch devices.
* two mode, touch_point & gesture, in touch_point mode it simply converts all mouse events & touch events to a unified event type, so you don't have to handle this by yourself.
* provide default event handlers for pan/swipe/pinch/rotation events.
* low coupling with your code, you simply attach your Sprite to an engine instance, then you can listen gesture events from standard AS3 event flow.

Here's a sample about how to use the engine:
==========================================================
class TestGesture extends Sprite {

    public function new() {
        super();
        graphics.beginFill(0xFFBBBB);
        graphics.drawRect(0, 0, RocGame.screenWidth, RocGame.screenHeight);
        graphics.endFill();

        var big = new Sprite();
        var bmp = new Bitmap(RocUtils.loadBitmapData("res/content1.jpg"));
        bmp.smoothing = true;
        bmp.x = -bmp.width / 2;
        bmp.y = -bmp.height / 2;
        big.addChild(bmp);
        big.name = "big";
        big.x = RocGame.screenWidth / 2;
        big.y = RocGame.screenHeight / 2;
        new RoxGestureAgent(big, RoxGestureAgent.GESTURE);
        big.rotation = 15;
        big.addEventListener(RoxGestureEvent.GESTURE_PAN, RoxGestureAgent.getHandler(3));
        big.addEventListener(RoxGestureEvent.GESTURE_SWIPE, RoxGestureAgent.getHandler(3));
        big.addEventListener(RoxGestureEvent.GESTURE_PINCH, RoxGestureAgent.getHandler(0));
        big.addEventListener(RoxGestureEvent.GESTURE_ROTATION, RoxGestureAgent.getHandler(0));
        addChild(big);
        //big.scaleX = big.scaleY = 1.5;

        var small = new Sprite();
        small.name = "small";
        bmp = new Bitmap(RocUtils.loadBitmapData("res/content2.jpg"));
        bmp.smoothing = true;
        bmp.x = -bmp.width / 2;
        bmp.y = -bmp.height / 2;
        small.addChild(bmp);
        small.x = 0;
        small.y = 0;
        new RoxGestureAgent(small, RoxGestureAgent.GESTURE);
        small.addEventListener(RoxGestureEvent.GESTURE_TAP, onTouch);
        small.addEventListener(RoxGestureEvent.GESTURE_PAN, RoxGestureAgent.getHandler(2));
        small.addEventListener(RoxGestureEvent.GESTURE_PINCH, RoxGestureAgent.getHandler(2));
        small.addEventListener(RoxGestureEvent.GESTURE_LONG_PRESS, onTouch);
        big.addChild(small);

    }

    private function onTouch(e: RoxGestureEvent) {
        var sp = cast(e.target, DisplayObject);
        switch (e.type) {
            case RoxGestureEvent.GESTURE_TAP:
                trace(">>tap: e=" + e);
                var oldscale = sp.scaleX;
                Actuate.tween(sp, 0.05, { scaleX: oldscale * 1.3, scaleY: oldscale * 1.3});
                Actuate.tween(sp, 0.35, { scaleX: oldscale, scaleY: oldscale }, false).ease(Elastic.easeOut).delay(0.05);
            case RoxGestureEvent.GESTURE_LONG_PRESS:
                var oldscale = sp.scaleX;
                Actuate.tween(sp, 0.05, { scaleX: oldscale * 1.3, scaleY: oldscale * 1.3});
                Actuate.tween(sp, 0.25, { scaleX: oldscale, scaleY: oldscale }, false).ease(Elastic.easeOut).delay(0.05);
                Actuate.tween(sp, 0.05, { scaleX: oldscale * 1.3, scaleY: oldscale * 1.3}, false).delay(0.3);
                Actuate.tween(sp, 0.25, { scaleX: oldscale, scaleY: oldscale }, false).ease(Elastic.easeOut).delay(0.35);
        }
    }

}
 
gesture_src.zip

Francois Nicaise

unread,
Dec 12, 2012, 1:35:32 PM12/12/12
to haxe...@googlegroups.com
Great ! I needed one, I did not know which one I would use so I will try yours  ( mac, win, linux, ios) 
I will tell you how it works.

Cheers.
Francois

Thinkslow 
Cross- platform gaming experiments 
<gesture_src.zip>

Marcelo de Moraes Serpa

unread,
Dec 12, 2012, 1:43:55 PM12/12/12
to haxe...@googlegroups.com
Nice one, why not put it on github?

- Marcelo

whitetigle

unread,
Dec 13, 2012, 8:33:03 AM12/13/12
to haxe...@googlegroups.com
+1 :)
-- 
ThinkSlow - 
cross-platform gaming experiments

( who ? why ? what ? ) -> http://thinkslow.net
( how ? when ? ) -> http://blog.thinkslow.net

Rocks Wang

unread,
Dec 13, 2012, 9:12:38 AM12/13/12
to haxe...@googlegroups.com
Thanks, will do that

在 2012年12月13日星期四UTC+8上午2时43分55秒,FullOfCaffeine写道:

Rocks Wang

unread,
Dec 13, 2012, 9:23:16 AM12/13/12
to haxe...@googlegroups.com
Hi anyone has experience working with swipe? Originally in my engine I just use the average pan-speed & pan-direction as swipe velocity vector (convered to polar coordinate), however I feel it's too fast, in the attached source code I've shrinked the value to 1/4, but I don't think it's a good smell, any suggestion? or maybe it's a defect of my code?

Rocks

whitetigle

unread,
Dec 31, 2012, 4:53:46 AM12/31/12
to haxe...@googlegroups.com
Hi,
I would like to use your code. Could you upload it to github/
bitbucket/whatever ?
Thanks :)

Fran�ois

Le 13/12/2012 15:23, Rocks Wang a �crit :

Baluta Cristian

unread,
Dec 31, 2012, 5:13:07 AM12/31/12
to haxe...@googlegroups.com
This would be great on haxelib


On Mon, Dec 31, 2012 at 9:53 AM, whitetigle <white...@gmail.com> wrote:
Hi,
I would like to use your code. Could you upload it to github/ bitbucket/whatever ?
Thanks :)

François


Le 13/12/2012 15:23, Rocks Wang a écrit :

Hi anyone has experience working with swipe? Originally in my engine I just use the average pan-speed & pan-direction as swipe velocity vector (convered to polar coordinate), however I feel it's too fast, in the attached source code I've shrinked the value to 1/4, but I don't think it's a good smell, any suggestion? or maybe it's a defect of my code?

Rocks
--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en





--
ThinkSlow -
cross-platform gaming experiments

( who ? why ? what ? ) -> http://thinkslow.net
( how ? when ? ) -> http://blog.thinkslow.net




--
Băluță Cristian
http://ralcr.com
http://imagin.ro

Cambiata

unread,
Dec 31, 2012, 5:32:42 AM12/31/12
to haxe...@googlegroups.com
Attached a simple FD project using Rock's code, if anyone's interested.
Replaced the bitmap dependencies with simple colored sprites.

Jonas

Gesture.zip

whitetigle

unread,
Dec 31, 2012, 6:00:58 AM12/31/12
to haxe...@googlegroups.com
Cool I was just starting to play with it :)
Thanks!

Le 31/12/2012 11:32, Cambiata a �crit :
> Attached a simple FD project using Rock's code, if anyone's interested.
> Replaced the bitmap dependencies with simple colored sprites.
>
> Jonas
>

whitetigle

unread,
Dec 31, 2012, 7:17:13 AM12/31/12
to haxe...@googlegroups.com
I am trying to use swipe however, it just works once... never twice...

I am using it like this (in a sprite):

new RoxGestureAgent(this, RoxGestureAgent.GESTURE);
this.addEventListener(RoxGestureEvent.GESTURE_SWIPE, onTouch );

function onTouch(e:RoxGestureEvent){
trace( "onTouch " + e.type );
switch (e.type) {
case RoxGestureEvent.GESTURE_SWIPE:
trace("swipe");
}

After playing with trace, it seems that MOUSE_DOWN is never called more
than once.


Le 31/12/2012 12:00, whitetigle a �crit :

whitetigle

unread,
Dec 31, 2012, 7:37:17 AM12/31/12
to haxe...@googlegroups.com
Once the first swipe is done, I only get mousemoves and mouseout events.

Le 31/12/2012 13:17, whitetigle a �crit :

whitetigle

unread,
Dec 31, 2012, 8:19:57 AM12/31/12
to haxe...@googlegroups.com
Ok it was a problem of context. :)

Le 31/12/2012 13:37, whitetigle a �crit :

whitetigle

unread,
Dec 31, 2012, 8:38:01 AM12/31/12
to haxe...@googlegroups.com
Great! So far it works well! (tap, pan, swipe)
But I had to modify the code so that I can add listener and recognize
gestures to the whole stage.

So next what would be great would be to have a release on haxelib + a
proper license.
if you could make it soon, I could use your lib in my latest game
(www.strangemasks.com) this very week :)

Congratulations :)

Le 31/12/2012 14:19, whitetigle a �crit :

Rocks Wang

unread,
Jan 1, 2013, 12:24:34 AM1/1/13
to haxe...@googlegroups.com
Thanks!
I've just created a github repo at: https://github.com/rockswang/roxlib
I've made some changes to gesture agent:
1. added begin & end event to indicate the starting and finishing of two-finger gestures
2. bug fix: touch-out/mouse-out events bubbled from children will not trigger swipe/end gestures
3. tap will automatically stop the swipe-scrolling if you are using RoxGestureAgent.startTween() to scroll the sprite

在 2012年12月31日星期一UTC+8下午9时38分01秒,François Nicaise写道:
Great! So far it works well! (tap, pan, swipe)
But I had to modify the code so that I can add listener and recognize
gestures to the whole stage.

So next what would be great would be to have a release on haxelib + a
proper license.
if you could make it soon, I could use your lib in my latest game
(www.strangemasks.com) this very week :)

Congratulations :)

Le 31/12/2012 14:19, whitetigle a �crit :
> Ok it was a problem of context. :)
>
> Le 31/12/2012 13:37, whitetigle a �crit :
>> Once the first swipe is done, I only get mousemoves and mouseout events.
>>
>> Le 31/12/2012 13:17, whitetigle a �crit :
>>> I am trying to use swipe however, it just works once... never twice...
>>>
>>> I am using it like this (in a sprite):
>>>
>>>         new RoxGestureAgent(this, RoxGestureAgent.GESTURE);
>>>         this.addEventListener(RoxGestureEvent.GESTURE_SWIPE, onTouch );
>>>
>>>     function onTouch(e:RoxGestureEvent){
>>>         trace( "onTouch " + e.type );
>>>         switch (e.type) {
>>>             case RoxGestureEvent.GESTURE_SWIPE:
>>>                 trace("swipe");
>>>         }
>>>
>>> After playing with trace, it seems that MOUSE_DOWN is never called
>>> more than once.
>>>
>>>
>>> Le 31/12/2012 12:00, whitetigle a �crit :
>>>> Cool I was just starting to play with it :)
>>>> Thanks!
>>>>
>>>> Le 31/12/2012 11:32, Cambiata a �crit :

Rocks Wang

unread,
Jan 1, 2013, 12:27:42 AM1/1/13
to haxe...@googlegroups.com
Hi, thanks for the sample project!

在 2012年12月31日星期一UTC+8下午6时32分42秒,Cambiata写道:

Cambiata

unread,
Jan 1, 2013, 2:01:53 AM1/1/13
to haxe...@googlegroups.com
Great, thank you you Rocks!

Do you have some code or demo to share, showing the ui/framework functions?

Jonas

Francois Nicaise

unread,
Jan 1, 2013, 4:07:56 AM1/1/13
to haxe...@googlegroups.com, haxe...@googlegroups.com
Great! Thanks!


Thinkslow 
Cross- platform gaming experiments 

Whitetigle

unread,
Jan 23, 2013, 4:11:31 AM1/23/13
to haxe...@googlegroups.com
Hi just so you know, on my ipad 2 on nme 3.5.4 touchevents are not fired
but mouseevents are although multitouch is correctly found.

It took me some time to figure why events would not fire.
++
Francois

Le 1/1/13 8:01 AM, Cambiata a �crit :

Rocks Wang

unread,
Jan 23, 2013, 5:52:46 AM1/23/13
to haxe...@googlegroups.com
Hi, have you tried the newest version in github? link: https://github.com/rockswang/roxlib
I've had it tested on an ios device, I was using nme 3.4

Rocks

在 2013年1月23日星期三UTC+8下午5时11分31秒,François Nicaise写道:
Hi just so you know, on my ipad 2 on nme 3.5.4 touchevents are not fired
but mouseevents are although multitouch is correctly found.

It took me some time to figure why events would not fire.
++
Francois

Le 1/1/13 8:01 AM, Cambiata a �crit :

Whitetigle

unread,
Jan 23, 2013, 6:59:31 AM1/23/13
to haxe...@googlegroups.com
Nope, mainly because I had modified the base code to get events fired without messing with Actuate.
But I will try to merge your changes.

Now, since I use the events for the whole stage, could you make the events firing without binding actuate. For instance for a swipe I just want to know if it occured without actually having something done to the sprite.
I prefer then to do stuff my way so that I can use my own anim engine.

What do you think ?

Le 1/23/13 11:52 AM, Rocks Wang a écrit :

Rocks Wang

unread,
Jan 23, 2013, 7:47:32 AM1/23/13
to haxe...@googlegroups.com
Yes sure, RoxGestureAgent.getHandler() is just the default handler for pan/swipe/rotation/pinch events, you don't have to use it. If you don't use the default handler, then actuate will not be bound. 
The reason why gestureAgent have a startTween() method is that the internal tweener can be automatically stopped by next gesture, that's a common requirement of modern mobile ui.
If you don't want those features, then just write your own handler for swipe event, the extra field of swipe event is the velocity vector. 

Rocks

在 2013年1月23日星期三UTC+8下午7时59分31秒,François Nicaise写道:

Andrew Sargeant

unread,
Jul 16, 2013, 11:17:48 AM7/16/13
to haxe...@googlegroups.com
I've just found this and it was great to see it was updated yesterday to work with OpenFL and HaXe 3!  Nice work.  I had to do some minor import statement amendments in the classes, basically replacing "nme.somelibrary" with "openfl.somelibrary".  Took me about 3 minutes and it was up and running.  Thanks! :)

Skyler Parr

unread,
Aug 3, 2013, 1:38:26 PM8/3/13
to haxe...@googlegroups.com
What are the plans of getting this into haxelib?  I collaborating with another developer and haxelib just makes the whole process easier.
Reply all
Reply to author
Forward
0 new messages