Package fr.umlv.escapeir.gesture

Source Code of fr.umlv.escapeir.gesture.GestureRecognizer

package fr.umlv.escapeir.gesture;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.util.ArrayList;
import java.util.LinkedList;

import org.jbox2d.common.Vec2;

import fr.umlv.escapeir.physic.World;
import fr.umlv.escapeir.utils.Renderable;
import fr.umlv.zen2.ApplicationContext;
import fr.umlv.zen2.MotionEvent;

/**
* Handle gestures catching and recognition
* A gesture being a movement starting when the left-click is pressed and ending when the left click is released
* @author Joachim ARCHAMBAULT, Alexandre ANDRE
*
*/
public final class GestureRecognizer implements Renderable {
  /**
   * Enumeration representing types of gestures
   * @author Joachim ARCHAMBAULT, Alexandre ANDRE
   */
  public enum GestureID {
    /**
     * A simple movement on the left and slightly forward
     */
    LEFT_DRIFT,
    /**
     * A simple movement on the left and slightly forward
     */
    RIGHT_DRIFT,
    /**
     * A simple backward movement (kind of defensive)
     */
    BACKOFF,
    /**
     * A forward movement with shoot
     */
    ATTACK,
    /**
     * A simple shoot
     */
    SHOOT,
    /**
     * A looping on the left
     */
    LEFT_LOOPING,
    /**
     * A looping on the right
     */
    RIGHT_LOOPING,
    /**
     * Represents an invalid gesture
     */
    INVALID,
    /**
     * Represents an unknown or unfinished gesture
     */
    UNKNOWN,
    /**
     * A click to pick a weapon
     */
    SELECT,
  }

  private static GestureRecognizer instance = null;
  private boolean capturing;
  private GestureID recognizedGesture;
  private GestureID drawedRecognizedGesture;
  private ArrayList<Point> points;
  private LinkedList<Gesture> gestures;

  private GestureRecognizer() {
    this.capturing = false;
    this.setGesture(GestureID.UNKNOWN);
    this.points = new ArrayList<>();
    this.gestures = new LinkedList<>();
    this.gestures.add(new Backoff());
    this.gestures.add(new Shoot());
    this.gestures.add(new Attack());
    this.gestures.add(new LeftLooping());
    this.gestures.add(new RightLooping());
    this.gestures.add(new LeftDrift());
    this.gestures.add(new RightDrift());
    this.gestures.add(new Select());
  }

  /**
   * Returns the unique instance of GestureRecognizer
   * @return an instance of GestureRecognizer
   */
  public static GestureRecognizer getInstance() {
    if (GestureRecognizer.instance == null)
      GestureRecognizer.instance = new GestureRecognizer();

    return GestureRecognizer.instance;
  }

  /**
   * Update the point list representing a possible gesture
   * @param context The application context to handle event
   */
  public void update(ApplicationContext context) {
        while (true) {
            final MotionEvent event = context.pollMotion();
            if (event == null)
              break;

            if (this.capturing == false && event.getKind() == MotionEvent.Kind.ACTION_DOWN) {
            this.points = new ArrayList<>();
            this.capturing = true;
            this.setGesture(GestureID.UNKNOWN);
            this.points.add(new Point(event.getX(), event.getY()));
          } else if (this.capturing == true && event.getKind() == MotionEvent.Kind.ACTION_UP) {
            this.capturing = false;
            this.analyze();
          } else if (this.capturing == true && event.getKind() == MotionEvent.Kind.ACTION_MOVE) {
            this.points.add(new Point(event.getX(), event.getY()));
          }
        }
  }

  /**
   * Analyze the list of points and try to define a gesture
   */
  private void analyze() {
    this.setGesture(GestureID.INVALID);
    for (Gesture gesture : this.gestures) {
      if (!gesture.recognized(this.points))
        continue;
      this.setGesture(gesture.getId());
      return;
    }
  }

  /**
   * Draw the gesture on the screen
   */
  public void render(Graphics2D graphics) {
    if (this.points.size() < 2)
      return;

    Point last = this.points.get(0);
    for (Point point : this.points) {
      if (this.drawedRecognizedGesture == GestureID.UNKNOWN)
        graphics.setColor(Color.WHITE);
      else if (this.drawedRecognizedGesture == GestureID.INVALID)
        graphics.setColor(Color.RED);
      else {
        graphics.setColor(Color.GREEN);
      }
      graphics.setStroke(new BasicStroke(5));
      graphics.drawLine((int) last.getX(), (int) last.getY(), (int) point.getX(), (int) point.getY());
      last = point;
    }
  }

  /**
   * Return the analyzed gesture
   * @return the gesture identifier
   */
  public GestureID getGesture() {
    return this.recognizedGesture;
  }

  /**
   * Clear the analyzed gesture
   */
  public void clearGesture() {
    this.recognizedGesture = GestureID.UNKNOWN;
  }

  private void setGesture(GestureID gesture) {
    this.recognizedGesture = gesture;
    this.drawedRecognizedGesture = gesture;
  }

  public Point getStartingPoint() {
    return this.points.get(0);
  }

  protected Point getEndingPoint() {
    return this.points.get(this.points.size() - 1);
  }

  public ArrayList<Point> getPoints(){
    return this.points;
  }
 
  /**
   * Returns the distance between the first and last stored points
   * @return distance between first and last point
   */
  public double getDistance() {
    if (this.points.size() < 2)
      return 0;

    return this.getEndingPoint().distance(this.getStartingPoint());
  }

  /**
   * Returns the distance angle the first and last stored points
   * @return angle between first and last point
   */
  public Vec2 getAngle() {
    if (this.points.size() < 2)
      return new Vec2(0, 0);

    return World.angle(this.getStartingPoint(), this.getEndingPoint());
  }
}
TOP

Related Classes of fr.umlv.escapeir.gesture.GestureRecognizer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.