The example MIDlet demonstrates the usage of multipoint touch events.
The example zip file can be downloaded here.
The MIDlet is a small game, and it uses multipoint touch functionality that is available in Java Runtime 2.2 to emulate a gamepad, consisting of an analog stick and a fire button. The virtual analog stick behaves in a similar way to a traditional analog joystick: the thumb can be moved to any direction inside of its range, providing the game information about the position relative to its center.
Figure: Ghosts example MIDlet
The game uses two JAD attributes to achieve good touch experience:
Nokia-UI-Enhancement: EnableMultiPointTouchEvents
which enables multipoint touch events and makes it possible to simultaneously control the crosshair and fire at the ghost, and
Nokia-MIDlet-Tap-Detection-Options: 0, 0
which disables tap detection to improve responsiveness of the gamepad analog stick.
Multipoint touch event handling is implemented in the class Scene
, which derives from LCDUI Canvas
and overrides Canvas
methods pointerPressed
, pointerDragged
and pointerReleased
. When multipoint touch events are enabled, the system property com.nokia.pointer.number
exists in scope of these methods,
and can be queried to obtain the pointer number of pointer which was
the source of the pointer event.
The pointer number is obtained using the Scene
method getPointerId
:
private int getPointerEventId() { String idString = System.getProperty("com.nokia.pointer.number"); int id = 0; if (idString != null) { id = Integer.parseInt(idString); } return id; }
The pointer number and pointer event coordinates are then passed
to Gamepad
methods pointerPressed
, pointerDragged
and pointerReleased
which handle the interaction with virtual gamepad.
Gamepad
stores information about pointer numbers
which are used to interact with both the fire button and the virtual
analog stick. When the player touches the screen, Gamepad
's pointerPressed
is executed and when the pointer
event is generated in virtual analog stick or the fire button area,
the pointer number is stored like in the code snippet:
public void pointerPressed(int pointerId, int x, int y) { if(this.fireButtonPointerId == -1 && this.fireButtonHitTest(x, y)) { this.fireButtonPointerId = pointerId; } if(this.analogStickPointerId == -1 && this.analogStickHitTest(x, y)) { this.analogStickPointerId = pointerId; } }
Drag events in the virtual analog stick can be then easily distinguished:
public void pointerDragged(int pointerId, int x, int y) { if(this.analogStickPointerId == pointerId) { // Process analog stick movement // ... } }
Pointer release event resets stored pointer numbers for both the fire button and the virtual analog stick:
public void pointerReleased(int pointerId, int x, int y) { if(this.fireButtonPointerId == pointerId) { this.fireButtonPointerId = -1; } if(this.analogStickPointerId == pointerId) { this.analogStickPointerId = -1; // Handle analog stick pointer release ... } }