Package org.newdawn.fizzy

Source Code of org.newdawn.fizzy.Body

package org.newdawn.fizzy;

import java.util.ArrayList;
import java.util.List;

import org.jbox2d.collision.AABB;
import org.jbox2d.common.Transform;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.BodyDef;

/**
* A single body in the world. A body holds a shape which collide with
* the rest of the world. It also holds properties about the shapes once
* they have been created.
*
* The generic T represents the type of the userData.
*
* @author kglass
*/
abstract public class Body<T> {
  /** The body held by JBox2D */
  protected org.jbox2d.dynamics.Body jboxBody;
  /** The body definition held by JBox2D */
  protected BodyDef jboxBodyDef;
  /** The list of bodies this body is touching */
  private List<Body<?>> touching = new ArrayList<Body<?>>();
  /** The shape used to represent this body */
  private Shape shape;
  /** The userdata assigned to this body if any */
  private T userData;
  /** Whether the body has been attached to a world */
  private boolean attached;
 
  /**
   * Create a new body
   *
   * @param shape The shape the body should have
   * @param x The x axis location of the body
   * @param y The y axis location of the body
   */
  public Body(Shape shape, float x, float y) {
    jboxBodyDef = new BodyDef();
    jboxBodyDef.position = new Vec2(x,y);
    this.shape = shape;
  }
 
  /**
   * Check if this body was declared as static
   *
   * @return True if this body was declared as static
   */
  public boolean isStatic() {
    return false;
  }
 
  /**
   * Get the user data assigned to this body if any
   *
   * @return Get the user data assigned to this body (or null if none is defined);
   */
  public T getUserData() {
    return userData;
  }
 
  /**
   * Set the user data assigned to this body
   *
   * @param object The user data to be assigned to this body
   */
  public void setUserData(T object) {
    this.userData = object;
  }
 
  /**
   * Check if this body is touching another
   *
   * @param other The other body to check against
   * @return True if the bodies are touching
   */
  public boolean isTouching(Body<?> other) {
    return touching.contains(other);
  }
 
  /**
   * Check how many contact points there are between two bodies
   *
   * @param other The other body to check against
   * @return The number of contact points
   */
  public int touchCount(Body<?> other) {
    int count = 0;
   
    for(Body<?> touched : touching){
      if(touched == other){
        count++;
      }
    }
   
    return count;
  }
 
  /**
   * Indicate that this body touches another at a *new* contact
   * point.
   *
   * @param other The other body that is touched
   */
  void touch(Body<?> other) {
    touching.add(other);
  }
 
  /**
   * Indicate that one contact point between the bodies has been removed
   *
   * @param other The other body that is no longer touched by a particular
   * contact point.
   */
  void untouch(Body<?> other) {
    touching.remove(other);
  }
 
  /**
   * Reset all touch-related data -- disappear from other objects' touch information.
   */
  void resetTouching(){
    for(Body<?> touched : touching){
      touched.untouch(this);
    }
    touching.clear();
  }
 
  /**
   * Checks to see if this body is touching anything.
   * @return true if something is touching
   */
  public boolean isTouchingAnything(){
    return !touching.isEmpty();
  }
 
  /**
   * Apply force to the body at its center.
   *
   * @param x The amount of force on the X axis
   * @param y The amount of force on the Y axis
   */
  public void applyForce(float x, float y) {
    assertBodyAttached();
    jboxBody.applyForce(new Vec2(x,y), jboxBody.getWorldCenter());
  }
 
  /**
   * Apple force to the body at an arbitrary location.
   *
   * @param xMagnitude The amount of force on the X axis
   * @param yMagnitude The amount of force on the Y axis
   * @param xAt The x-coordinate at which to apply the force
   * @param yAt The y-coordinate at which to apply the force
   * @param isLocalPoint if true, assume the *At params are local to the body.  otherwise, they're world coordinates.
   */
  public void applyForce(float xMagnitude, float yMagnitude, float xAt, float yAt, boolean isLocalPoint){
    assertBodyAttached();
    Vec2 position = new Vec2(xAt, yAt);
    if(isLocalPoint)
      position = jboxBody.getWorldPoint(position);
    jboxBody.applyForce(new Vec2(xMagnitude, yMagnitude), position);
  }

  /**
   * (from JBox2d): Apply a torque. This affects the angular velocity without
   * affecting the linear velocity of the center of mass. This wakes up the
   * body.
   *
   * @param torque about the z-axis (out of the screen), usually in N-m.
   */
  public void applyTorque(float torque){
    assertBodyAttached();
    jboxBody.applyTorque(torque);
  }
 
  /**
   * Get the X position of the body
   *
   * @return The x position of the body
   */
  public float getX() {
    return attached ? jboxBody.getPosition().x : jboxBodyDef.position.x;
  }

 
  /**
   * Get the Y position of the body
   *
   * @return The y position of the body
   */
  public float getY() {
    return attached ? jboxBody.getPosition().y : jboxBodyDef.position.y;
  }
 
  /**
   * Get the X position of the body in local coordinates
   * @return The x position of the body in local coordinates
   */
  public float getLocalX(){
    assertBodyAttached();
    return jboxBody.getLocalCenter().x;
  }
 
  /**
   * Get the Y position of the body in local coordinates
   * @return The y position of the body in local coordinates
   */
  public float getLocalY(){
    assertBodyAttached();
    return jboxBody.getLocalCenter().y;
  }
 
  /**
   * Get the rotation of the body
   *
   * @return The rotation of the body
   */
  public float getRotation() {
    assertBodyAttached();
    return jboxBody.getAngle();
  }

  /**
   * Get the X velocity of the body
   *
   * @return The x velocity of the body
   */
  public float getXVelocity() {
    assertBodyAttached();
    return jboxBody.getLinearVelocity().x;   
  }

 
  /**
   * Get the Y velocity of the body
   *
   * @return The y velocity of the body
   */
  public float getYVelocity() {
    assertBodyAttached();
    return jboxBody.getLinearVelocity().y;   
  }
 
  /**
   * Get the angular velocity of the body
   *
   * @return The angular velocity of the body
   */
  public float getAngularVelocity() {
    assertBodyAttached();
    return jboxBody.getAngularVelocity();
  }
 
  /**
   * Set the restitution applied when this body collides
   *
   * @param rest The restitution applied when this body collides
   */
  public void setRestitution(float rest) {
    shape.setRestitution(rest);
  }

  /**
   * Set the friction applied when this body collides
   *
   * @param f The friction applied when this body collides
   */
  public void setFriction(float f) {
    shape.setFriction(f);
  }
 
  /**
   * Set the density of this body
   *
   * @param den The density of this body
   */
  public void setDensity(float den) {
    shape.setDensity(den);
  }
 
  /**
   * @return true if the body is attached to a world and is marked "active"
   */
  public boolean isActive() {
    return attached && jboxBody.isActive();
  }
 
  /**
   * Tests whether this body is out of bounds.
   * Since the world no longer tracks which objects is out of bounds,
   * this just checks whether the body is still active...which will actually
   * work as expected if the world's {@link World.OutOfBoundsBehavior} is set
   * to DESTROY or DEACTIVATE.
   * @deprecated use {@link #isActive()}, {@link #isAttached()}, and {@link World#setOutOfBoundsBehavior(org.newdawn.fizzy.World.OutOfBoundsBehavior)} instead.
   * @return true if body is inactive
   */
  @Deprecated
  public boolean isOutOfBounds() {
    return !isActive();
  }
 
  /**
   * @return true if the body is currently attached to a world
   */
  public boolean isAttached() {
    return attached;
  }
 
  /**
   * Notification that this body is being added to the world
   *
   * @param world The world this body is being added to
   */
  void addToWorld(World world) {
    org.jbox2d.dynamics.World jboxWorld = world.getJBoxWorld();
       
    jboxBody = jboxWorld.createBody(jboxBodyDef);
    shape.createInBody(this);
    attached = true;
  }

  /**
   * Notification that this body is being removed from the world
   *
   * @param world The world this body is being removed from
   */
  void removeFromWorld(World world) {
    org.jbox2d.dynamics.World jboxWorld = world.getJBoxWorld();
    jboxWorld.destroyBody(jboxBody);
    resetTouching();
    attached = false;
  }
 
  /**
   * Get the JBox2D body that is wrapped by this class
   *
   * @return The body that is wrapped by this proxy class
   */
  org.jbox2d.dynamics.Body getJBoxBody() {
    return jboxBody;
  }
 
  /**
   * Get the Fizzy shape representing this body
   *
   * @return The fizzy shape representing this body
   */
  public Shape getShape() {
    return shape;
  }
 
  /**
   * Set the position of the body. This can only be called after the body has been added
   * to the world.
   *
   * @param x The new x coordinate of the body
   * @param y The new y coordinate of the body
   */
  public void setPosition(float x, float y) {
    assertBodyAttached();
    jboxBody.setTransform(new Vec2(x,y), jboxBody.getAngle());
  }
 
  /**
   * Set the rotation of the body. This can only be called after the body has been added
   * to the world.
   *
   * @param rotation The new rotation of the body
   */
  public void setRotation(float rotation) {
    assertBodyAttached();
    jboxBody.setTransform(jboxBody.getPosition(), rotation);
  }
 
  /**
   * Check the body has been added to the world
   */
  private void assertBodyAttached() {
    if (!attached) {
      throw new NotAttachedToWorldException();
    }
  }

  /**
   * Check if this body is "sleeping", i.e. its not moving any more
   *
   * @return True if this body is sleeping
   */
  public boolean isSleeping() {
    assertBodyAttached();
    return !jboxBody.isAwake();
  }

  /**
   * Translate this body by the given amount
   *
   * @param x The amount to move the body on the x axis
   * @param y The amount to move the body on the y axis
   */
  public void translate(float x, float y) {
    setPosition(getX()+x, getY()+y);
  }

  /**
   * Set the linear damping to apply to this body. Higher
   * value slows the body acceleration. Maximum is 1.0.
   *
   * @param damping The amount to dampen the movement by
   * @deprecated use {@link #setLinearDamping(float)} instead
   */
  public void setDamping(float damping) {
    setLinearDamping(damping);
  }
 
  /**
   * Set the linear damping to apply to this body. Higher
   * value slows the body acceleration. Maximum is 1.0.
   *
   * @param damping The amount to dampen the movement by
   */
  public void setLinearDamping(float damping){
    if (jboxBody != null) throw new AlreadyAddedToWorldException();
    jboxBodyDef.linearDamping = damping;
  }
 
  /**
   * Set the angular damping to apply to this body.  Higher
   * value slows the angular velocity faster.  Maximum is 1.0.
   *
   * @param damping The amount to dampen the rotation by
   */
  public void setAngularDamping(float damping){
    if (jboxBody != null) throw new AlreadyAddedToWorldException();
    jboxBodyDef.angularDamping = damping;
  }

  /**
   * Set the linear velocity of this body
   *
   * @param xVelocity The x component of the velocity
   * @param yVelocity The y component of the velocity
   */
  public void setVelocity(float xVelocity, float yVelocity) {
    assertBodyAttached();
    Vec2 vel = jboxBody.getLinearVelocity();
    vel.x = xVelocity;
    vel.y = yVelocity;
    jboxBody.setLinearVelocity(vel);
  }

  /**
   * Set the angular velocity (the speed at which it rotates)
   *
   * @param vel The angular velocity to apply
   */
  public void setAngularVelocity(float vel) {
    assertBodyAttached();
    jboxBody.setAngularVelocity(vel);
  }
 
  /**
   * Sets whether this body has fixed rotation enabled.
   * Bodies with Fixed Rotation can't rotate...in case that wasn't obvious.
   * @param fixedRotation true if fixed rotation mode should be enabled.
   */
  public void setFixedRotation(boolean fixedRotation){
    if(attached){
      jboxBody.setFixedRotation(fixedRotation);
    } else {
      jboxBodyDef.fixedRotation = fixedRotation;
    }
  }
 
  /**
   * Get the bounding box that encloses this body and all of its constituent shapes
   * @return bounding box of all shapes enclosed in this body
   */
  public BoundingBox getBoundingBox(){
    AABB bodyAABB = new AABB(new AABB(new Vec2(Float.MAX_VALUE, Float.MAX_VALUE), new Vec2(Float.MIN_VALUE, Float.MIN_VALUE)));
    AABB shapeAABB = new AABB();
    for(org.jbox2d.collision.shapes.Shape jshape : shape.getJBoxShapes()){
      jshape.computeAABB(shapeAABB, jboxBody.m_xf);
      if(shapeAABB.lowerBound.x < bodyAABB.lowerBound.x){
        bodyAABB.lowerBound.x = shapeAABB.lowerBound.x;
      }
      if(shapeAABB.lowerBound.y < bodyAABB.lowerBound.y){
        bodyAABB.lowerBound.y = shapeAABB.lowerBound.y;
      }
      if(shapeAABB.upperBound.x > bodyAABB.upperBound.x){
        bodyAABB.upperBound.x = shapeAABB.upperBound.x;
      }
      if(shapeAABB.upperBound.y > bodyAABB.upperBound.y){
        bodyAABB.upperBound.y = shapeAABB.upperBound.y;
      }
    }
    return BoundingBox.fromAABB(bodyAABB);
  }
 
  private boolean bullet = false;
  /**
   * Sets whether this body is to be considered a bullet.
   * @see #getBullet()
   * @param bullet
   */
  public void setBullet(boolean bullet){
    this.bullet = bullet;
    if(attached){
      jboxBody.setBullet(bullet);
    } else {
      jboxBodyDef.bullet = bullet;
    }
  }
  /**
   * Is the current body considered a "bullet" (at high risk of passing through
   * other objects due to velocity).  This is on by default for Dynamic<->Static interactions
   * but not Dynamic<->Dynamic interactions.
   * @see http://www.box2d.org/manual.html
   * @return true if the object is a "bullet", false otherwise.
   */
  public boolean getBullet(){
    return bullet;
  }

  /**
   * Sets the body to active (or inactive).  Inactive objects are essentially
   * non-existent, as far as the physics world is concerned.
   * @see http://www.box2d.org/manual.html
   * @param flag true if body is to be active, false otherwise.
   */
  public void setActive(boolean flag) {
    assertBodyAttached();
    jboxBody.setActive(flag);
  }
}
TOP

Related Classes of org.newdawn.fizzy.Body

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.