@Override
  public List<TouchEvent> getTouchEvents() {
    synchronized (this) {
      // We find out how many events are in the touchEvents arrayList
      int len = touchEvents.size();
      // Then we iterate through each item and add it to the Pool's recyclable Events ArrayList
      for (int i = 0; i < len; i++) {
        touchEventPool.free(touchEvents.get(i));
      }

      // Then we empty the touchEvents ArrayList
      touchEvents.clear();
      // Basically just copy all of the items in touchEventsBuffer ArrayList into touchEvents
      // ArrayList
      touchEvents.addAll(touchEventsBuffer);
      // Then we clear the touchEventsBuffer ArrayList
      touchEventsBuffer.clear();

      return touchEvents;
    }
  }
  /** Called when touch events are fired */
  @Override
  public boolean onTouch(View v, MotionEvent event) {
    synchronized (this) {
      // Create a blank TouchEvent object
      TouchEvent touchEvent = touchEventPool.newObject();

      // Fill the TouchEvent object's type variable and flag if the screen is being touched or not
      switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          {
            touchEvent.type = TouchEvent.TOUCH_DOWN;
            isTouched = true;
            break;
          }
        case MotionEvent.ACTION_MOVE:
          {
            touchEvent.type = TouchEvent.TOUCH_DRAGGED;
            isTouched = true;
            break;
          }
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
          {
            touchEvent.type = TouchEvent.TOUCH_UP;
            isTouched = false;
            break;
          }
      } // end switch

      touchEvent.x = touchX = (int) (event.getX() * scaleX);
      touchEvent.y = touchY = (int) (event.getY() * scaleY);
      // Add the TouchEvent to the touchEventsBuffer ArrayList
      touchEventsBuffer.add(touchEvent);

      // Return true because we handled the TouchEvent ourselves
      return true;
    }
  }