Package com.skyleanderson.util

Source Code of com.skyleanderson.util.Prop

package com.skyleanderson.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;

import org.newdawn.slick.Animation;
import org.newdawn.slick.Color;
import org.newdawn.slick.Game;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.geom.Vector2f;

/**
* A Prop is the fundamental display unit in a game. Everything in the game
* world from the characters to the powerups and bullets should be derived from
* prop.
*
* @author ska
*
*/
public class Prop
{
  // the bounding box of the represented object, does not have to match the
  // size of the associated sprite
  public BoundingBox             boundingBox      = new BoundingBox();

  public LinkedList<Integer>     mapIndexes       = new LinkedList<Integer>();

  // a list of the animations that this prop can use for representation (i.e.
  // stand, walk,jump, etc)
  protected ArrayList<Animation> animations       = new ArrayList<Animation>(1);

  protected int                  animationState   = 0;

  protected Vector2f             position         = new Vector2f();
  protected Vector2f             velocity         = new Vector2f();             // note: units for velocity are in pixels /
  // frame
  protected Vector2f             acceleration     = new Vector2f();             // note: units for acceleration are in
  // pixels / frame*frame
  protected boolean              onGround         = false;

  protected Vector2f             center           = new Vector2f();              ;

  public static final int        DIRECTION_LEFT   = 0;
  public static final int        DIRECTION_RIGHT  = 1;
  public static final int        DIRECTION_UP     = 2;
  public static final int        DIRECTION_DOWN   = 3;

  protected int                  currentDirection = DIRECTION_RIGHT;

  protected float                gravity;

  public Prop( )
  {}

  public Prop( Color c, float width, float height )
  {
    boundingBox.setWidth(width);
    boundingBox.setHeight(height);
    boundingBox.setColor(c);
    boundingBox.setFillOnRender(true);
  }

  public Prop( ArrayList<Animation> animations )
  {
    this.animations = animations;
    boundingBox = new BoundingBox(animations.get(0).getWidth(), animations.get(0).getHeight());
    position = new Vector2f();
    velocity = new Vector2f();
    acceleration = new Vector2f();
    mapIndexes = new LinkedList<Integer>();
    center = new Vector2f();
  }

  public Prop( Animation animation )
  {
    this.animations = new ArrayList<Animation>(1);
    this.animations.add(0, animation);
    boundingBox = new BoundingBox(animations.get(0).getWidth(), animations.get(0).getHeight());
    position = new Vector2f();
    velocity = new Vector2f();
    acceleration = new Vector2f();
    mapIndexes = new LinkedList<Integer>();
    center = new Vector2f();
  }

  public Prop( Color c, float width, float height, ArrayList<Animation> animations )
  {
    this.animations = animations;
    boundingBox = new BoundingBox(width, height, 0, 0, c);
    position = new Vector2f();
    velocity = new Vector2f();
    acceleration = new Vector2f();
    mapIndexes = new LinkedList<Integer>();
    center = new Vector2f();
  }

  public Prop( Color c, float width, float height, Animation animation )
  {
    this.animations = new ArrayList<Animation>(1);
    this.animations.add(animation);
    boundingBox = new BoundingBox(width, height, 0, 0, c);
    position = new Vector2f();
    velocity = new Vector2f();
    acceleration = new Vector2f();
    mapIndexes = new LinkedList<Integer>();
    center = new Vector2f();
  }

  public void setCurrentAnimationState( int state )
  {
    this.animationState = state;
    // if (this.animations.get(animationState) != null) this.animations.get(animationState).restart();
  }

  public Animation getCurrentAnimation( )
  {
    return this.animations.get(this.animationState);
  }

  public ArrayList<Animation> getAllAnimations( )
  {
    return this.animations;
  }

  public float top( )
  {
    return position.getY() + this.boundingBox.offsetY;
  }

  public float bottom( )
  {
    return position.getY() + this.boundingBox.height + this.boundingBox.offsetY;
  }

  public float left( )
  {
    return position.getX() + this.boundingBox.offsetX;
  }

  public float right( )
  {
    return position.getX() + this.boundingBox.width + this.boundingBox.offsetX;
  }

  public Vector2f center( )
  {
    center.x = this.left() + ((this.right() - this.left()) / 2.0f);
    center.y = this.top() + ((this.bottom() - this.top()) / 2.0f);
    return center;
  }

  /**
   * Radius is used for quick collision tests when the Prop is roughly
   * circular. The radius is assumed to be the smaller of the bounding box
   * width or height.
   *
   * @return
   */
  public float getRadius( )
  {
    float diameter;
    diameter = (boundingBox.width > boundingBox.height) ? boundingBox.height : boundingBox.width;
    return .5f * diameter;
  }

  public void setPosition( float x, float y )
  {
    position.x = x;
    position.y = y;
  }

  public void setPosition( Vector2f position )
  {
    this.position.set(position);
  }

  public Vector2f getPosition( )
  {
    return this.position;
  }

  public void setVelocity( float x, float y )
  {
    velocity.x = x;
    velocity.y = y;
  }

  public void setVelocity( Vector2f velocity )
  {
    this.velocity.set(velocity);
  }

  public void setVelocityX( float x )
  {
    velocity.x = x;
  }

  public void setVelocityY( float y )
  {
    velocity.y = y;
  }

  public float getVelocityX( )
  {
    return velocity.getX();
  }

  public float getVelocityY( )
  {
    return velocity.getY();
  }

  public Vector2f getVelocity( )
  {
    return this.velocity;
  }

  public void setAcceleration( float x, float y )
  {
    acceleration.x = x;
    acceleration.y = y;
  }

  public void setAcceleration( Vector2f v )
  {
    acceleration.set(v);
  }

  public boolean isOnGround( )
  {
    return onGround;
  }

  public void setOffGround( )
  {
    onGround = false;
  }

  public void setGravity( float g )
  {
    gravity = g;
  }

  public float getGravity( )
  {
    return gravity;
  }

  public void addAnimation( Animation anim )
  {
    this.animations.add(anim);
  }

  public void addAnimations( Collection<Animation> animations )
  {
    this.animations.addAll(animations);
  }

  // this function updates the velocity based on the current acceleration and
  // the position based on the
  // resulting velocity
  public void update( )
  {
    if (!isOnGround()) acceleration.y += gravity;
    velocity.add(acceleration);
    if (onGround) velocity.y = 0;
    position.add(velocity);
  }

  @SuppressWarnings( "deprecation" )
  public void render( GameContainer gc, Game game, Graphics g, float offsetX, float offsetY )
  {
    if (animations.size() == 0 || animations.get(animationState) == null)
    {
      // only draw bounding box instead
      this.boundingBox.render(g, position.x - offsetX, position.y - offsetY);
      // g.setColor(Color.white);
      // g.drawOval(this.position.x - offsetX, this.position.y - offsetY,
      // 2*getRadius(), 2*getRadius());
    } else
    {
      if (currentDirection == DIRECTION_RIGHT)
        animations.get(this.animationState).draw(position.x - offsetX, position.y - offsetY);
      else
      {
        // Animation currAnim = animations.get(0);
        // Image currImage = currAnim.getImage(currAnim.getFrame());
        // currImage.getFlippedCopy(true, false).draw(position.x,
        // position.y);
        animations.get(animationState).getCurrentFrame().getFlippedCopy(true, false).draw(position.x - offsetX, position.y - offsetY);
        animations.get(animationState).updateNoDraw();

      }
    }
  }

  public void render( GameContainer gc, Game game, Graphics g )
  {
    this.render(gc, game, g, 0, 0);
  }

  /**
   * Check for collisions with the given list.
   *
   * @param list
   *            the list of Prop items to check for collisions with
   * @return true if there is a collision
   */
  public boolean checkCollisions( Collection<Prop> list )
  {
    Iterator<Prop> it = list.iterator();
    while (it.hasNext())
    {
      Prop p = it.next();
      if (this.checkSingleCollision(p)) return true;
    }
    return false;
  }

  // fail-first collision test
  public boolean checkSingleCollision( Prop p )
  {
    if (this.right() < p.left() || this.left() > p.right()) return false;
    if (this.bottom() < p.top() || this.top() > p.bottom()) return false;
    return true;
  }

  // fail-first collision test
  public boolean checkSingleCollision( float left, float top, float right, float bottom )
  {
    if (this.right() < left || this.left() > right) return false;
    if (this.bottom() < top || this.top() > bottom) return false;
    return true;
  }

  public boolean checkRadialCollision( Prop p )
  {
    return (this.center().distance(p.center()) < (this.getRadius() + p.getRadius()));
  }

  public boolean updatePositionX( Collection<Prop> relevant )
  {
    boolean collision = false;
    position.x += velocity.x;

    // check if you ran into something -- horizontal
    Iterator<Prop> it = relevant.iterator();
    while (it.hasNext())
    {
      Prop p = it.next();
      if (this.checkSingleCollision(p)) // find collisions
      {
        // check for walls:
        if (!(this.bottom() == p.top() || this.top() == p.bottom())) // make sure it's not just the ground
        {
          if (velocity.getX() > 0)
          {
            if (this.right() >= p.left() && this.right() <= p.right())
            {
              // x collision, stop short of the wall
              this.position.x = (p.left() - this.boundingBox.getWidth() - this.boundingBox.getOffsetX());
              collision = true;
              // this.velocity.x = 0;
            }
          } else if (velocity.getX() < 0) if (this.left() <= p.right() && this.left() >= p.left())
          {
            // x collision, stop short of the wall
            this.position.x = p.right();
            collision = true;
            // this.velocity.x = 0;
          }
        } // end x collisions
      } // end ifcollision
    }// end while
    return collision;
  }

  public boolean updatePositionY( Collection<Prop> relevant )
  {
    boolean collision = false;
    this.position.y += velocity.y;
    Iterator<Prop> it = relevant.iterator();
    this.onGround = false;
    while (it.hasNext())
    {
      Prop p = it.next();
      if (this.checkSingleCollision(p))
      {
        // check for walls:
        if (!(this.left() == p.right() || this.right() == p.left())) // same as before, no bump-ups
        {
          if (velocity.getY() < 0) // hit head on ceiling?
          {
            if (this.top() <= p.bottom() && this.top() >= p.top())
            {
              // y collision, stop at ceiling
              this.position.y = p.bottom();
              this.velocity.y = 0;
              collision = true;
            }
          } else if (velocity.getY() > 0) // landed on ground?
          {
            if (this.bottom() >= p.top() && this.bottom() <= p.bottom())
            {
              // y collision, stop on ground
              this.position.y = p.top() - this.boundingBox.getHeight();
              this.velocity.y = 0;
              this.onGround = true;
              collision = true;
            }
          } else // if velocity.y == 0, see if you're standing on
                 // something
          if (this.bottom() == p.top()) this.onGround = true;
        } // end y collision check
      } // end if singlecollision
    } // end while it.hasnext()
    return collision;
  }
}
TOP

Related Classes of com.skyleanderson.util.Prop

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.