Implementation

For information about the design and functionality of the MIDlet, see section Design.

To implement multipoint touch handling in the MIDlet:

  1. To enable a good touch experience, set the following attributes in the MIDlet JAD file:

    • Nokia-UI-Enhancement: EnableMultiPointTouchEvents

      This attribute enables multipoint touch events and makes it possible to simultaneously both control the crosshair and fire at the ghost.

    • Nokia-MIDlet-Tap-Detection-Options: 0, 0

      This attribute disables tap detection to improve responsiveness of the game pad analog stick.

  2. To catch touch events, override selected Canvas methods in the Scene class. This class forwards the events and the pointer ID to the Gamepad class.

        protected void pointerPressed(int x, int y)
        {
            int pointerId = this.getPointerEventId();
            // Check whether the exit button was tapped
            this.exitButtonPointerDown = this.exitButtonHitTest(pointerId, x, y);
    
            boolean wasFirePressed = this.gamepad.isFireButtonPressed();
            // Pass pointer event to gamepad
            this.gamepad.pointerPressed(pointerId, x, y);
            if (!wasFirePressed && this.gamepad.isFireButtonPressed())
            {
                // Fire only when the fire button was released and pressed again
                this.handleFire();
            }
        }
    
        protected void pointerDragged(int x, int y)
        {
            int pointerId = this.getPointerEventId();
            // Update exit button state
            this.exitButtonPointerDown = this.exitButtonHitTest(pointerId, x, y);
            // Pass pointer event to gamepad
            this.gamepad.pointerDragged(pointerId, x, y);
        }
    
        protected void pointerReleased(int x, int y)
        {
            int pointerId = this.getPointerEventId();
            if (this.exitButtonPointerDown && this.exitButtonHitTest(pointerId, x, y))
            {
                // The exit button was pressed and released, exit the game.
                this.exit();
            }
            else
            {
                this.exitButtonPointerDown = false;
            }
            // Pass pointer event to gamepad
            this.gamepad.pointerReleased(pointerId, x, y);
        }
  3. When multipoint touch events are enabled, pointerPressed, pointerDragged, and pointerReleased methods contain the com.nokia.pointer.number system property. This property can be queried to obtain the pointer number of the pointer that was the source of the pointer event. To obtain the pointer number, use the Scene.getPointerEventId method.

        private int getPointerEventId()
        {
            String idString = System.getProperty("com.nokia.pointer.number");
            int id = 0;
            if (idString != null)
            {
                id = Integer.parseInt(idString);
            }
            return id;
        }
  4. The Gamepad class contains methods for handling the events called from the Scene class. The methods use the pointer IDs to determine which pointer was used: the one on the stick or the one on the fire button.

        /**
         * This method needs to be called from Canvas pointerPressed() method.
         */
        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;
            }
        }
    
        /**
         * This method needs to be called from Canvas pointerDragged() method.
         */
        public void pointerDragged(int pointerId, int x, int y)
        {
            if (this.analogStickPointerId == pointerId)
            {
                double thumbDistance = this.getAnalogStickThumbDistance(x, y);
                if ((thumbDistance + this.analogStickThumbDiameter / 2) < (this.analogStickDiameter / 2))
                {
                    this.analogStickPosition.x = x - this.analogStickCenter.x;
                    this.analogStickPosition.y = y - this.analogStickCenter.y;
                }
            }
        }
    
        /**
         * This method needs to be called from Canvas pointerReleased() method.
         */
        public void pointerReleased(int pointerId, int x, int y)
        {
            if (this.fireButtonPointerId == pointerId)
            {
                this.fireButtonPointerId = -1;
            }
    
            if (this.analogStickPointerId == pointerId)
            {
                this.analogStickPointerId = -1;
                this.analogStickPosition.x = 0;
                this.analogStickPosition.y = 0;
            }
        }