@Override
  protected boolean onTouchImpl(View view, MotionEvent event) {
    boolean result = false;

    if (mJoystickLeft != null && mJoystickLeft.processTouch(view, event)) result = true;

    if (mJoystickRight != null && mJoystickRight.processTouch(view, event)) result = true;

    // check for double tap
    if (mSettings.isFlipEnabled() && event.getActionMasked() == MotionEvent.ACTION_POINTER_UP) {
      long currTimestamp = event.getEventTime();

      if (event.getPointerCount() > 1) {
        if (currTimestamp - timestampLast < DOUBLE_TAP_TIMESTAMP_DELTA
            && Math.abs(event.getX(1) - xLast) < COORDINATE_DELTA
            && Math.abs(event.getY(1) - yLast) < COORDINATE_DELTA) {
          // Double tap detected.
          mDroneControl.doLeftFlip();
          result = true;
        }
      }
    }

    return result;
  }
  protected Sprite[] getSpritesImpl() {
    final float joypadOpacity = mSettings.getInterfaceOpacity() / 100f;

    if (mJoystickLeft != null) {
      mJoystickLeft.setAlign(Align.BOTTOM_LEFT);
      mJoystickLeft.setAlpha(joypadOpacity);
      mJoystickLeft.setInverseYWhenDraw(true);
    }
    if (mJoystickRight != null) {
      mJoystickRight.setAlign(Align.BOTTOM_RIGHT);
      mJoystickRight.setAlpha(joypadOpacity);
      mJoystickRight.setInverseYWhenDraw(true);
    }

    JoystickBase[] joysticks = new JoystickBase[2];
    joysticks[0] = mJoystickLeft;
    joysticks[1] = mJoystickRight;
    return joysticks;
  }
  private void initVirtualJoysticks(
      JoystickType leftType, JoystickType rightType, boolean isLeftHanded) {
    JoystickBase joystickLeft = (!isLeftHanded ? mJoystickLeft : mJoystickRight);
    JoystickBase joystickRight = (!isLeftHanded ? mJoystickRight : mJoystickLeft);

    if (leftType == JoystickType.ANALOGUE) {
      if (joystickLeft == null
          || !(joystickLeft instanceof AnalogueJoystick)
          || joystickLeft.isAbsoluteControl() != mSettings.isAbsoluteControlEnabled()) {
        joystickLeft =
            JoystickFactory.createAnalogueJoystick(
                mDroneControl, mSettings.isAbsoluteControlEnabled(), rollPitchListener);
      } else {
        joystickLeft.setOnAnalogueChangedListener(rollPitchListener);
        joystickRight.setAbsolute(mSettings.isAbsoluteControlEnabled());
      }
    } else if (leftType == JoystickType.ACCELERO) {
      if (joystickLeft == null
          || !(joystickLeft instanceof AcceleroJoystick)
          || joystickLeft.isAbsoluteControl() != mSettings.isAbsoluteControlEnabled()) {
        joystickLeft =
            JoystickFactory.createAcceleroJoystick(
                mDroneControl, mSettings.isAbsoluteControlEnabled(), rollPitchListener);
      } else {
        joystickLeft.setOnAnalogueChangedListener(rollPitchListener);
        joystickRight.setAbsolute(mSettings.isAbsoluteControlEnabled());
      }
    }

    if (rightType == JoystickType.ANALOGUE) {
      if (joystickRight == null
          || !(joystickRight instanceof AnalogueJoystick)
          || joystickRight.isAbsoluteControl() != mSettings.isAbsoluteControlEnabled()) {
        joystickRight =
            JoystickFactory.createAnalogueJoystick(mDroneControl, false, gazYawListener);
      } else {
        joystickRight.setOnAnalogueChangedListener(gazYawListener);
        joystickRight.setAbsolute(false);
      }
    } else if (rightType == JoystickType.ACCELERO) {
      if (joystickRight == null
          || !(joystickRight instanceof AcceleroJoystick)
          || joystickRight.isAbsoluteControl() != mSettings.isAbsoluteControlEnabled()) {
        joystickRight =
            JoystickFactory.createAcceleroJoystick(mDroneControl, false, gazYawListener);
      } else {
        joystickRight.setOnAnalogueChangedListener(gazYawListener);
        joystickRight.setAbsolute(false);
      }
    }

    if (!isLeftHanded) {
      mJoystickLeft = joystickLeft;
      mJoystickRight = joystickRight;
    } else {
      mJoystickLeft = joystickRight;
      mJoystickRight = joystickLeft;
    }
  }