Win an Ipad
  Developer   Demos & Samples   Gestures

Gestures

Screenshot
The invention of touch screens caused a revolution in the mobile industry. Once they started to be implemented in the smarthphones, the number of mobile devices has increased rabidly and still rising. Nowadays, we cannot even imagine controlling the smarthphone by old-school buttons only.

Moscrif fully supports the gestures allowing the developer to create modern mobile game that is played by touching the screen with the fingers.

Moscrif can automatically recognize 6 the most commonly used gestures:

By default, Moscrif does not recognize any gesture. The recognition must be allowed by setGesture(Rotate | Swipe | Tap etc.) method. Some conditions have to be met first prior to using some gesture.  These conditions can be also set in setGesture* methods.

Example: methods setGestureSwipe, setGestureTap and setGesturePress can hold additional parameters like the number of taps or touches

  1.     
  2. setGestureSwipe(enable, numberOfTouchesRequired, direction);    
  3. setGestureTap(enable, numberOfTapsRequired, numberOfTouchesRequired);    
  4. setGesturePress(enable, numberOfTapsRequired, numberOfTouchesRequired);

When the gesture is recognized a gesture event (onGesturePinch, onGesturePan, onGesturePwipe etc…) is raised. These events should contain all the code needed to react to the raised gesture.

Table: gestures' events parameters

onGesturePinch state, scale, velocity
onGestureRotate state, angle, velocity
onGesturePan state, transX, transY, velX, velY
onGesturePress -
onGestureSwipe direction
onGestureTap -

Handling the gestures

Rotate gesture

A typical usage based on rotate gestures is rotating photos in photo viewer or maps in navigation. In games or applications it is mostly used to rotate some items on the screen.

A rotate gesture is raised when user taps the screen by two fingers and rotates with the imaginary connection line of this taps. The rotate gesture has no additional settings in setGestureRotate method.

Example: Allowing the rotate gesture

game.setGestureRotate(true);

When the rotate gesture is recognized the onGestureRotate event is raised. The first parameter of this event represents the state. The following state symbols are supported:

  • #began: the recognizer has received touches recognized as the gesture. The action method will be called at the next turn of the run loop.
  • #chnaged: the recognizer has received touches recognized as a change in the gesture. The action method will be called at the next turn of the run loop.
  • #ended: the recognizer has received touches recognized as the end of the gesture. The action method will be called at the next turn of the run loop and the recognizer will be reset to UIGestureRecognizerStatePossible.
  • #cancelled: the recognizer has received touches resulting in the cancellation of the gesture. The action method will be called at the next turn of the run loop. The recognizer will be reset to UIGestureRecognizerStatePossible.

The second parameter specifies the angle in radians from the previous call of this event.

The following example represents sample scene which applies the rotate gesture onto an image. This scene allows the rotate gesture when the scene is shown and disables the gesture when the scene is going to be removed. The reaction onto the onGestureRotate event calculates the angle, which is applied onto the image in the draw method.

Example: using the rotate gesture

include "lib://game2d/textButton.ms"
include "lib://game2d/label.ms" class RotateScene : Scene
{
    function init()
    {
        super.init();         this.add(new Label({text:"Rotate gesture", y:System.height / 12, x:System.width/2}));
        this._back = new TextButton({text:"Back", x:System.width/2, y:System.height/10*9});
        this._back.onClick = function() {
            SFX.playClick();
            this super._goBack();
        }         this.add(this._back);
        // allow rotate gesture
        game.setGestureRotate(true);         game.onGestureRotate = function(state, angle, velocity)
        {
            var self = this super;             this.state = state;
            // do not return the angle to zero, when touch is released
            if (state != #ended) {
                // radians to degrees
                self.angle -= self.lastRotation - angle * 180.0/ Math.PI;
                self.lastRotation = angle * 180.0/ Math.PI;
            } else {
                self.lastRotation = 0;
            }
        }         this._transitionMatrix = new Matrix();
        this.angle = 0;
        this.lastRotation = 0;
    }     function _goBack()
    {
        Game.instance.pop(new SlideToBottom());
    }     function draw(canvas)
    {
        super.draw(canvas);         canvas.save();
        canvas.translate(System.width / 2, System.height / 2);
       
        this._transitionMatrix.setTranslate(-GFX.disk.width / 2, - GFX.disk.height / 2);
        this._transitionMatrix.postRotate(this.angle);         canvas.drawBitmapMatrix(GFX.disk, this._transitionMatrix);         canvas.restore();
    }     function exit()
    {
        // disable rotate gesture
        game.setGestureRotate(false);
    } }

Pinch gesture

The pinch gesture is typically used to zoom photos, maps or layers in the games.

It is recognized when the user touches the screen by two fingers and moves them closer or further. According to the touches movement and scale are automatically calculated.

The pinch gesture can be allowed by setting setGesturePinch method to true. This method has only one parameter, which turns on / off the gesture.

Example: allowing the pinch gesture

game.setGesturePinch(true);

When the pinch gesture is recognized, the onGesturePinch method is called. The first parameter is the state parameter, which can contain following values:

  • #began: the recognizer has received touches recognized as the gesture. The action method will be called at the next turn of the run loop.
  • #chnaged: the recognizer has received touches recognized as a change to the gesture. The action method will be called at the next turn of the run loop.
  • #ended: the recognizer has received touches recognized as the end of the gesture. The action method will be called at the next turn of the run loop and the recognizer will be reset to UIGestureRecognizerStatePossible.
  • #cancelled: the recognizer has received touches resulting in the cancellation of the gesture. The action method will be called at the next turn of the run loop. The recognizer will be reset to UIGestureRecognizerStatePossible.

The second parameter represents the change of the scale from the last call of the onGesturePinch event.

Following example shows how to use the pinch gesture to scale a photo. The gesture is allowed when the scene is going to be showed and destroyed, when it is destroying. In the onGesturePinch event the actual scale as a product of previous scale and scale from the last call of this event is calculated.

Example: using the pinch gesture to scale a photo

include "lib://game2d/textButton.ms"
include "lib://game2d/label.ms" class PinchScene : Scene
{
    function init()
    {
        super.init();         this.add(new Label({text:"Pinch gesture", y:System.height / 12, x:System.width/2}));         this._back = new TextButton({text:"Back", x:System.width/2, y:System.height/10*9});
        this._back.onClick = function() {
            SFX.playClick();
            this super._goBack();
        }
        this.add(this._back);         // allow pinch gesture
        game.setGesturePinch(true);         game.onGesturePinch = function(state, scale, velocity)
        {
            var self = this super;             self.scale = self.scale * scale;
            if (self.scale < self.minScale)
                self.scale = self.minScale;
            else if (self.scale > self.maxScale)
                self.scale = self.maxScale;
        }         this._transitionMatrix = new Matrix();
        this.scale = 1.0;
        this.minScale = 0.2;
        this.maxScale = 5.0;
    }     function _goBack()
    {
        Game.instance.pop(new SlideToBottom());
    }     function draw(canvas)
    {
        super.draw(canvas);         canvas.save();
        canvas.translate(System.width / 2, System.height / 2);
       
        this._transitionMatrix.setTranslate(-GFX.disk.width / 2, - GFX.disk.height / 2);
        this._transitionMatrix.postScale(this.scale, this.scale);         canvas.drawBitmapMatrix(GFX.disk, this._transitionMatrix);         canvas.restore();
    }     function exit()
    {
        // disable pinch gesture
        game.setGesturePinch(false);
    }
}

Swipe gesture

The swipe gesture is a simple gesture recognized by horizontal or vertical movement on the screen. This gesture could be used for various actions which are invoked by simple fingers’ movement by one or more fingers. Switching between the running applications on iOS, or amplifying / attenuating music in the players are the typical examples of this gesture.

The gesture is recognized when the required number of touches is recognized. Before the gesture can be used it must be allowed in the setGestureSwipe method. The setGestureSwipe method also sets the number of required touches and directions.

Example: allowing the swipe gesture

// allowing swipe gesture 1 touch all directions
game.setGestureSwipe(true, 1, #all);

When a swipe gesture is recognized the onGestureSwipe event is raised. It holds only one parameter representing the direction we are interested in (#left, #right, #up or #down).

Example: using the swipe gesture

include "lib://game2d/textButton.ms"
include "lib://game2d/label.ms" class SwipeScene : Scene
{
    function init()
    {
        super.init();         this.add(new Label({text:"Swipe gesture", y:System.height / 12, x:System.width/2}));         this.label = new Label({text:"direction: none", y:System.height / 5, x:System.width/2});
        this.add(this.label);         this._back = new TextButton({text:"Back", x:System.width/2, y:System.height/10*9});
        this._back.onClick = function() {
            SFX.playClick();
            this super._goBack();
        }
        this.add(this._back);         // allow swipe gesture 1 touch all directions
        game.setGestureSwipe(true, 1, #all);         game.onGestureSwipe = function(direction)
        {
            var self = this super;             self.label.text = "direction: " + direction.toString();
        }
    }     function _goBack()
    {
        Game.instance.pop(new SlideToBottom());
    }     function exit()
    {
        // disable swipe gesture
        game.setGestureSwipe(false);
    }
}

Pan gesture

The pan gesture can be used when some movement according to the touch is needed (not according to the touch coordinates).

Similar to all other gestures also this gesture must be allowed before it is possible to detect it. It can be allowed in setGesturePan method.

Example: allowing the pan gesture

game.setGesturePan(true);

When the pan gesture is recognized the onGesturePanevent is raised. This event provides information about state, translation and velocity on both axes.

The state can contain following values:

  • #began: the recognizer has received touches recognized as the gesture. The action method will be called at the next turn of the run loop.
  • #chnaged: the recognizer has received touches recognized as a change to the gesture. The action method will be called at the next turn of the run loop.
  • #ended: the recognizer has received touches recognized as the end of the gesture. The action method will be called at the next turn of the run loop and the recognizer will be reset to UIGestureRecognizerStatePossible.
  • #cancelled: the recognizer has received touches resulting in the cancellation of the gesture. The action method will be called at the next turn of the run loop. The recognizer will be reset to UIGestureRecognizerStatePossible.

The second and the third parameter provide information about the translation on X and Y axis. The last two parameters hold information about velocity on both axes.

The following example shows how to use the pan gesture to move the photo. In the onGesturePan event information about translation in the member variables are saved, which are later used to move the image on the canvas.

Example: moving an image using the pan gesture

include "lib://game2d/textButton.ms"
include "lib://game2d/label.ms" class PanScene : Scene
{
    function init()
    {
        super.init();         this.add(new Label({text:"Pan gesture", y:System.height / 12, x:System.width/2}));         this._back = new TextButton({text:"Back", x:System.width/2, y:System.height/10*9});
        this._back.onClick = function() {
            SFX.playClick();
            this super._goBack();
        }
        this.add(this._back);         // allow pan gesture
        game.setGesturePan(true);         game.onGesturePan = function(state, transX, transY)
        {
            var self = this super;             self.transX += transX;
            self.transY += transY;
        }         this._transitionMatrix = new Matrix();
        this.transX = 0;
        this.transY = 0;
    }     function _goBack()
    {
        Game.instance.pop(new SlideToBottom());
    }     function draw(canvas)
    {
        super.draw(canvas);         canvas.save();
        canvas.translate(System.width / 2, System.height / 2);
       
        this._transitionMatrix.setTranslate(-GFX.disk.width / 2 - this.transX, - GFX.disk.height / 2 - this.transY);         canvas.drawBitmapMatrix(GFX.disk, this._transitionMatrix);         canvas.restore();
    }     function exit()
    {
        // disable pan gesture
        game.setGesturePan(false);
    }
}

Tap & Press gestures

The last two gestures - tap and press are very similar. Both are invoked by simple user tap on the screen. The only difference is the time of the tap. The tap is a short tap. Press gesture requires longer time between finger press and release.

Both gestures must be allowed before they can be used by setGesturePress and setGestureTap methods. The first parameter of both gestures is a boolean value allowing or disabling the gestures. The second parameter sets number of required touches (one or two).

 Prismatic joint 
Baby Sparkle
14.12.2012 20:25:53
Gestures inside the emulator

Hi!
It's been a couple of days I'm trying Moscrif and I can say it is pretty impressive.
Currently I'm trying to use gestures and I'd like to ask if there is some way to make them work using the emulator.
I see they are working on the real devices if I deploy the app, but this makes things a little slow when you're developing.
Any suggestion about this?

Thanks in advance

Write a Comment (1)
Subject
Please complete this mandatory field.
HTML Tags Not Allowed!
Comment
Please complete this mandatory field.