Package com.pointcliki.core

Source Code of com.pointcliki.core.Entity$EntityDispatcher

package com.pointcliki.core;

import org.newdawn.slick.Graphics;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.geom.Vector2f;

import com.pointcliki.event.Dispatcher;
import com.pointcliki.event.FrameManager;
import com.pointcliki.event.IEvent;

/**
* An entity is a displayable object in a scene that can be saved or loaded
*
* @author hugheth
* @since 1
*/
public abstract class Entity implements ISavable, Comparable<Entity> {
 
  /**
   * Serial key
   */
  private static final long serialVersionUID = 8256564243600872505L;
 
  protected long fID = -1;
  protected EntityContainer fParent;
  protected Scene fScene;
  protected EntityDispatcher fDispatcher;
 
  protected int fOrder;
  protected Vector2f fPosition = new Vector2f(0, 0);
  protected float fRotation = 0;
  protected Vector2f fOrigin = new Vector2f(0, 0);
  protected Vector2f fScale = new Vector2f(1, 1);
  protected float fOpacity = 1;
 
  /**
   * The span of the entity in space relative to its parent. This can be
   * set by extending classes to aid the rending of entities to the correct
   * bounds.
   */
  protected Rectangle fSpan = null;
  /**
   * The bounds during render relative to the position of the entity. This
   * should be used by extending classes to aid drawing of entities. The
   * bounds will always be contained inside the span.
   */
  protected Rectangle fBounds = new Rectangle(0, 0, 0, 0);
 
  /**
   * Clean up any resources that the entity was using prior to it being
   * destroyed. This should be called before the entity is removed from the
   * scene.
   */
 
  /**
   * Create a new entity
   */
  public Entity() {
    fDispatcher = new EntityDispatcher();
    // Register the entity
    PointClikiGame.entityManager().register(this);
  }
 
  /**
   * @return The unique id of the entity
   */
  public long id() {
    return fID;
  }
 
  /**
   * @return The current scene of the entity
   */
  public Scene scene() {
    return fScene;
  }
 
  public PointClikiGame game() {
    return fScene.game();
  }
 
  /**
   * Returns the scene of the entity, cast to a particular class
   * @param cls The class type of the entity's scene
   * @return The scene if it is an instance of cls, otherwise null
   */
  @SuppressWarnings("unchecked")
  public <V> V scene(Class<V> cls) {
    Scene s = scene();
    if (s == null || !cls.isInstance(s)) return null;
    return (V) s;
  }
 
  @SuppressWarnings("unchecked")
  public <V> V game(Class<V> cls) {
    PointClikiGame g = fScene.game();
    if (g == null || !cls.isInstance(g)) return null;
    return (V) g;
  }
 
  /**
   * @param cls The class of the manager
   * @return The manager registered of this type for the entity
   */
  public <V> V manager(Class<V> cls) {
    V manager;
    if (scene() == null) {
      manager = PointClikiGame.instance().manager(cls);
    } else {
      manager = scene().manager(cls);
    }
    if (manager == null) {
      System.err.println("Warning: Manager [" + cls + "] can't be found for " + this);
    }
    return manager;
  }
 
  /**
   * @return The TimeManager for the entity
   */
  public TimeManager timeManager() {
    return manager(TimeManager.class);
  }
  /**
   * @return The FrameManager for the entity
   */
  public FrameManager frameManager() {
    return manager(FrameManager.class);
  }

  /**
   * Clean up the entity when it is no longer needed
   */
  public void cleanup() {
    fDispatcher.cleanup();
    fDispatcher = null;
    if (fParent != null) fParent.removeChild(this);
    PointClikiGame.entityManager().unregister(this);
  }
 
  /**
   * Get the entity's parent, that may be the scene root or another entity
   * group
   * @return The parent entity
   */
  public EntityContainer getParent() {
    return fParent;
  }
 
  /**
   * Comparison here refers to the ordering of the entity on the screen. In
   * the case that the entities have the same order, we arbitrarily choose
   * one to be on top, otherwise they may be considered to be equal, such as
   * is the case in a Set implementation, where "duplicates" are ignored.
   */
  @Override
  public int compareTo(Entity o) {
    if (fOrder < o.order()) return -1;
    return 1;
  }
 
  @Override
  public boolean equals(Object o) {
    return (o instanceof Entity) && ((Entity) o).fID == fID;
  }

  /**
   * Set the entity's parent. This should be called when the entity is added
   * to an entity group.
   * @param parent The new parent of the entity
   */
  protected void setParent(EntityContainer parent) {
    fParent = parent;
    if (parent != null) setScene(parent.scene());
    else setScene(null);
  }
 
  /**
   * @return The order of the entity which determines when it is rendered
   */
  public int order() {
    return fOrder;
  }
 
  /**
   * @param o The order to set the entity to
   */
  public void order(int o) {
    fOrder = o;
    if (fParent != null) fParent.fChildren.update(this);
  }
 
  /**
   * @return The rotation of the entity around the position of the entity
   */
  public float rotation() {
    return fRotation;
  }
 
  /**
   * @param rotation Set the rotation of the entity, in degrees
   * @return The Entity instance
   */
  public Entity rotate(float rotation) {
    fRotation = rotation;
    return this;
  }
 
  public Vector2f origin() {
    return fOrigin;
  }
 
  public Entity origin(Vector2f origin) {
    fOrigin = origin;
    return this;
  }
 
  /**
   * @return The (x, y) scale of the entity
   */
  public Vector2f scale() {
    return fScale;
  }
  /**
   * @param scale The new scale of the entity
   * @return The Entity instance
   */
  public Entity scale(Vector2f scale) {
    fScale = scale;
    return this;
  }
 
  public Entity scale(float s) {
    fScale = new Vector2f(s, s);
    return this;
  }

  /**
   * @return The position of the entity relative to its container
   */
  public Vector2f position() {
    return fPosition.copy();
  }
  /**
   * @param position The new position of the entity
   * @return The Entity instance
   */
  public Entity position(Vector2f position) {
    fPosition = position;
    return this;
  }
 
  public Rectangle span() {
    return fSpan;
  }
 
  /**
   * @return The opacity of the entity, from 0 to 1
   */
  public float opacity() {
    return fOpacity;
  }
  /**
   * @param opacity The new opacity of the entity
   * @return The Entity instance
   */
  public Entity opacity(float opacity) {
    fOpacity = opacity;
    return this;
  }
 
  /**
   * @return The dispatcher for the entity that dispatches events originating
   * from the entity
   */
  public EntityDispatcher dispatcher() {
    return fDispatcher;
  }
 
  /**
   * @param v The new dimensions of the entity
   * @return The entity instance
   */
  public Entity resize(Vector2f v) {
    fScale.x = v.x / fSpan.getWidth();
    fScale.y = v.y / fSpan.getHeight();
    return this;
  }
 
  @Override
  public int hashCode() {
    return (int) fID;
  }
 
  /**
   * Sets the current scene of the entity
   * @param scene The current scene of the entity
   */
  protected void setScene(Scene scene) {
    if (fScene != null) {
      if (fScene.equals(scene)) return;
      scene().unregister(this);
    }
    fScene = scene;
    if (scene != null) {
      // Re-register the entity to a new id
      PointClikiGame.entityManager().register(this);
      scene.register(this);
    }
  }
 
  /**
   * Render the entity to the screen
   *
   * @param graphics The graphics instance to draw the entity's appearance onto
   * @param view The viewport being rendered through
   * @param currentTime The time elapsed since the scene was started
   */
  public void render(Graphics graphics, long currentTime) {
    // Update the movement, if there is one
    if (fDispatcher != null) fDispatcher.dispatchEvent(RenderEvent.TYPE, new RenderEvent(graphics, currentTime));
  }
 
  /**
   * Calculate the bounds of the displayable area that should be drawn to
   * by the entity during render. Entities should avoid drawing outside this
   * area. If the entity's span is set, the bounds field will be updated with
   * a sub-section of the span. Otherwise, the parent's bounds will just be
   * translated to this entity.
   *
   * @param bounds The parent entity's bounds relative to its origin
  
  public void calculateBounds(Rectangle bounds) {
    // Position of the bounds relative to the origin
    float ox = bounds.getX() - fPosition.x;
    float oy = bounds.getY() - fPosition.y;

    // Translate the bounds
    fBounds.setBounds(ox, oy, bounds.getWidth(), bounds.getHeight());
   
    // Crop the bounds
    if (fSpan != null) {
      // Position of the bounds or span relative to origin, whichever is
      // more south easterly.
      float lx = Math.max(ox, fSpan.getX());
      float ly = Math.max(oy, fSpan.getY());
     
      // Ensure these points don't lie outside the span
      lx = Math.min(lx, fSpan.getMaxX());
      ly = Math.min(ly, fSpan.getMaxY());
         
      // Position of the south east corner of the bounds or span relative
      // to origin, whichever is more north westerly.
      float rx = Math.min(fSpan.getMaxX(), fBounds.getMaxX());
      float ry = Math.min(fSpan.getMaxY(), fBounds.getMaxY());
     
      // Ensure these points don't lie outside the span
      rx = Math.max(rx, fSpan.getX());
      ry = Math.max(ry, fSpan.getY());
     
      // Update the bounds, ensuring they lie within the span
      fBounds.setBounds(
          lx,
          ly,
          Math.max(rx - lx, 0),
          Math.max(ry - ly, 0)
          );
    }
   
  }
  */

  @Override
  public ISavable snapshot() throws CloneNotSupportedException {
    Entity clone = (Entity) super.clone();
    // Clone rectangles
    clone.fSpan = new Rectangle(fSpan.getX(), fSpan.getY(), fSpan.getWidth(), fSpan.getHeight());
    // Clone vectors
    clone.fPosition = fPosition.copy();
    clone.fScale = fScale.copy();
    // Ensure the movement is parented to the correct entity
    clone.fDispatcher = (EntityDispatcher) fDispatcher.snapshot();
    // Nullify parent and scene as this information is not retrievable here
    clone.fParent = null;
    clone.fScene = null;
   
    return clone;
  }
 
  @Override
  public String toString() {
    return "[Entity #" + fID + "]";
  }
 
  /**
   * A dispatcher for a particular entity
   * @author Hugheth
   * @since 3
   */
  public class EntityDispatcher extends Dispatcher<IEvent> {
    /**
     * Serial key
     */
    private static final long serialVersionUID = 786643740900375864L;

    @Override
    public void dispatchEvent(String type, IEvent event) {
      super.dispatchEvent(type, event);
    }
   
    @Override
    public int dispatchIterativeEvent(String type, IEvent event, int maxIterations) {
      return super.dispatchIterativeEvent(type, event, maxIterations);
    }
  }
 
  /**
   * An event that is dispatched by an entity when it is being rendered
   * @author Hugheth
   * @since 3
   */
  public class RenderEvent implements IEvent {
   
    protected Graphics fGraphics;
    protected long fCurrentTime;
   
    /**
     * The single type of this event
     */
    public static final String TYPE = "render";
   
    protected RenderEvent(Graphics graphics, long currentTime) {
      fGraphics = graphics;
      fCurrentTime = currentTime;
    }
   
    /**
     * @return The graphics being rendered to
     */
    public Graphics graphics() {
      return fGraphics;
    }
    /**
     * @return The current time at rendering
     */
    public long currentTime() {
      return fCurrentTime;
    }
  }
}
TOP

Related Classes of com.pointcliki.core.Entity$EntityDispatcher

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.