Collision Test : Game Object « Game « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Collections Data Structure
8. Database SQL JDBC
9. Design Pattern
10. Development Class
11. Email
12. Event
13. File Input Output
14. Game
15. Hibernate
16. J2EE
17. J2ME
18. JDK 6
19. JSP
20. JSTL
21. Language Basics
22. Network Protocol
23. PDF RTF
24. Regular Expressions
25. Security
26. Servlets
27. Spring
28. Swing Components
29. Swing JFC
30. SWT JFace Eclipse
31. Threads
32. Tiny Application
33. Velocity
34. Web Services SOA
35. XML
Microsoft Office Word 2007 Tutorial
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java » Game » Game ObjectScreenshots 
Collision Test

       /*
DEVELOPING GAME IN JAVA 

Caracteristiques

Editeur : NEW RIDERS 
Auteur : BRACKEEN 
Parution : 09 2003 
Pages : 972 
Isbn : 1-59273-005-1 
Reliure : Paperback 
Disponibilite : Disponible a la librairie 
*/


import java.awt.AWTException;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.DisplayMode;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferUShort;
import java.awt.image.IndexColorModel;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class CollisionTest extends ShooterCore {

  public static void main(String[] args) {
    new CollisionTest(args).run();
  }

  protected BSPTree bspTree;

  protected String mapFile;

  public CollisionTest(String[] args) {
    super(args);
    for (int i = 0; mapFile == null && i < args.length; i++) {
      if (mapFile == null && !args[i].startsWith("-")) {
        mapFile = args[i];
      }
    }
    if (mapFile == null) {
      mapFile = "../images/sample.map";
    }
  }

  public void createPolygons() {
    Graphics2D g = screen.getGraphics();
    g.setColor(Color.BLACK);
    g.fillRect(00, screen.getWidth(), screen.getHeight());
    g.setColor(Color.WHITE);
    g.drawString("Loading..."5, screen.getHeight() 5);
    screen.update();

    float ambientLightIntensity = .2f;
    List lights = new LinkedList();
    lights.add(new PointLight3D(-100100100.3f, -1));
    lights.add(new PointLight3D(1001000.3f, -1));

    MapLoader loader = new MapLoader();
    loader.setObjectLights(lights, ambientLightIntensity);

    try {
      bspTree = loader.loadMap(mapFile);
    catch (IOException ex) {
      ex.printStackTrace();
    }

    CollisionDetection collisionDetection = new CollisionDetection(bspTree);
    gameObjectManager = new GridGameObjectManager(bspTree.calcBounds(),
        collisionDetection);
    gameObjectManager.addPlayer(new GameObject(new PolygonGroup("Player")));

    // set up player bounds
    PolygonGroupBounds playerBounds = gameObjectManager.getPlayer()
        .getBounds();
    playerBounds.setTopHeight(Player.DEFAULT_PLAYER_HEIGHT);
    playerBounds.setRadius(Player.DEFAULT_PLAYER_RADIUS);

    ((BSPRendererpolygonRenderer).setGameObjectManager(gameObjectManager);

    createGameObjects(loader.getObjectsInMap());
    Transform3D start = loader.getPlayerStartLocation();
    gameObjectManager.getPlayer().getTransform().setTo(start);
  }

  private void createGameObjects(List mapObjects) {
    Iterator i = mapObjects.iterator();
    while (i.hasNext()) {
      PolygonGroup group = (PolygonGroupi.next();
      String filename = group.getFilename();
      if ("robot.obj".equals(filename)) {
        gameObjectManager.add(new Bot(group));
      else {
        // static object
        gameObjectManager.add(new GameObject(group));
      }
    }
  }

  public void drawPolygons(Graphics2D g) {

    polygonRenderer.startFrame(g);

    // draw polygons in bsp tree (set z buffer)
    ((BSPRendererpolygonRenderer).draw(g, bspTree);

    // draw game object polygons (check and set z buffer)
    gameObjectManager.draw(g, (GameObjectRendererpolygonRenderer);

    polygonRenderer.endFrame(g);

  }
}

/**
 * A GameObject that can jump.
 */

class JumpingGameObject extends GameObject {

  public static final float DEFAULT_JUMP_HEIGHT = 64;

  protected float jumpVelocity;

  public JumpingGameObject(PolygonGroup group) {
    super(group);
    setJumpHeight(DEFAULT_JUMP_HEIGHT);
  }

  /**
   * Sets how high this GameObject can jump.
   */
  public void setJumpHeight(float jumpHeight) {
    jumpVelocity = Physics.getInstance().getJumpVelocity(jumpHeight);
  }

  /**
   * Causes this GameObject to jump if the jumping flag is set and this object
   * is not already jumping.
   */
  public void setJumping(boolean isJumping) {
    if (isJumping() != isJumping) {
      super.setJumping(isJumping);
      if (isJumping) {
        Physics.getInstance().jump(this, jumpVelocity);
      }
    }
  }

  public void notifyFloorCollision() {
    // the object has landed.
    setJumping(false);
  }

}
/**
 * The Physics class is a singleton that represents various attributes (like
 * gravity) and the functions to manipulate objects based on those physical
 * attributes. Currently, only gravity and scoot-up (acceleration when traveling
 * up stairs) are supported.
 */

class Physics {

  /**
   * Default gravity in units per millisecond squared
   */
  public static final float DEFAULT_GRAVITY_ACCEL = -.002f;

  /**
   * Default scoot-up (acceleration traveling up stairs) in units per
   * millisecond squared.
   */
  public static final float DEFAULT_SCOOT_ACCEL = .006f;

  private static Physics instance;

  private float gravityAccel;

  private float scootAccel;

  private Vector3D velocity = new Vector3D();

  /**
   * Gets the Physics instance. If a Physics instance does not yet exist, one
   * is created with the default attributes.
   */
  public static synchronized Physics getInstance() {
    if (instance == null) {
      instance = new Physics();
    }
    return instance;
  }

  protected Physics() {
    gravityAccel = DEFAULT_GRAVITY_ACCEL;
    scootAccel = DEFAULT_SCOOT_ACCEL;
  }

  /**
   * Gets the gravity acceleration in units per millisecond squared.
   */
  public float getGravityAccel() {
    return gravityAccel;
  }

  /**
   * Sets the gravity acceleration in units per millisecond squared.
   */
  public void setGravityAccel(float gravityAccel) {
    this.gravityAccel = gravityAccel;
  }

  /**
   * Gets the scoot-up acceleration in units per millisecond squared. The
   * scoot up acceleration can be used for smoothly traveling up stairs.
   */
  public float getScootAccel() {
    return scootAccel;
  }

  /**
   * Sets the scoot-up acceleration in units per millisecond squared. The
   * scoot up acceleration can be used for smoothly traveling up stairs.
   */
  public void setScootAccel(float scootAccel) {
    this.scootAccel = scootAccel;
  }

  /**
   * Applies gravity to the specified GameObject according to the amount of
   * time that has passed.
   */
  public void applyGravity(GameObject object, long elapsedTime) {
    velocity.setTo(0, gravityAccel * elapsedTime, 0);
    object.getTransform().addVelocity(velocity);
  }

  /**
   * Applies the scoot-up acceleration to the specified GameObject according
   * to the amount of time that has passed.
   */
  public void scootUp(GameObject object, long elapsedTime) {
    velocity.setTo(0, scootAccel * elapsedTime, 0);
    object.getTransform().addVelocity(velocity);
  }

  /**
   * Applies the negative scoot-up acceleration to the specified GameObject
   * according to the amount of time that has passed.
   */
  public void scootDown(GameObject object, long elapsedTime) {
    velocity.setTo(0, -scootAccel * elapsedTime, 0);
    object.getTransform().addVelocity(velocity);
  }

  /**
   * Sets the specified GameObject's vertical velocity to jump to the
   * specified height. Calls getJumpVelocity() to calculate the velocity,
   * which uses the Math.sqrt() function.
   */
  public void jumpToHeight(GameObject object, float jumpHeight) {
    jump(object, getJumpVelocity(jumpHeight));
  }

  /**
   * Sets the specified GameObject's vertical velocity to the specified jump
   * velocity.
   */
  public void jump(GameObject object, float jumpVelocity) {
    velocity.setTo(0, jumpVelocity, 0);
    object.getTransform().getVelocity().y = 0;
    object.getTransform().addVelocity(velocity);
  }

  /**
   * Returns the vertical velocity needed to jump the specified height (based
   * on current gravity). Uses the Math.sqrt() function.
   */
  public float getJumpVelocity(float jumpHeight) {
    // use velocity/acceleration formal: v*v = -2 * a(y-y0)
    // (v is jump velocity, a is accel, y-y0 is max height)
    return (floatMath.sqrt(-* gravityAccel * jumpHeight);
  }
}

/**
 * A Player object.
 */

class Player extends JumpingGameObject {

  public static final float DEFAULT_PLAYER_RADIUS = 32;

  public static final float DEFAULT_PLAYER_HEIGHT = 128;

  public Player() {
    this(new PolygonGroup("Player"));

    // set up player bounds
    PolygonGroupBounds playerBounds = getBounds();
    playerBounds.setTopHeight(DEFAULT_PLAYER_HEIGHT);
    playerBounds.setRadius(DEFAULT_PLAYER_RADIUS);
  }

  public Player(PolygonGroup group) {
    super(group);
  }

}

/**
 * The GridGameObjectManager is a GameObjectManager that integrally arranges
 * GameObjects on a 2D grid for visibility determination and to limit the number
 * of tests for collision detection.
 */

class GridGameObjectManager implements GameObjectManager {

  /**
   * Default grid size of 512. The grid size should be larger than the largest
   * object's diameter.
   */
  private static final int GRID_SIZE_BITS = 9;

  private static final int GRID_SIZE = << GRID_SIZE_BITS;

  /**
   * The Cell class represents a cell in the grid. It contains a list of game
   * objects and a visible flag.
   */
  private static class Cell {
    List objects;

    boolean visible;

    Cell() {
      objects = new ArrayList();
      visible = false;
    }
  }

  private Cell[] grid;

  private Rectangle mapBounds;

  private int gridWidth;

  private int gridHeight;

  private List allObjects;

  private GameObject player;

  private Vector3D oldLocation;

  private CollisionDetection collisionDetection;

  /**
   * Creates a new GridGameObjectManager with the specified map bounds and
   * collision detection handler. GameObjects outside the map bounds will
   * never be shown.
   */
  public GridGameObjectManager(Rectangle mapBounds,
      CollisionDetection collisionDetection) {
    this.mapBounds = mapBounds;
    this.collisionDetection = collisionDetection;
    gridWidth = (mapBounds.width >> GRID_SIZE_BITS1;
    gridHeight = (mapBounds.height >> GRID_SIZE_BITS1;
    grid = new Cell[gridWidth * gridHeight];
    for (int i = 0; i < grid.length; i++) {
      grid[inew Cell();
    }
    allObjects = new ArrayList();
    oldLocation = new Vector3D();
  }

  /**
   * Converts a map x-coordinate to a grid x-coordinate.
   */
  private int convertMapXtoGridX(int x) {
    return (x - mapBounds.x>> GRID_SIZE_BITS;
  }

  /**
   * Converts a map y-coordinate to a grid y-coordinate.
   */
  private int convertMapYtoGridY(int y) {
    return (y - mapBounds.y>> GRID_SIZE_BITS;
  }

  /**
   * Marks all objects as potentially visible (should be drawn).
   */
  public void markAllVisible() {
    for (int i = 0; i < grid.length; i++) {
      grid[i].visible = true;
    }
  }

  /**
   * Marks all objects within the specified 2D bounds as potentially visible
   * (should be drawn).
   */
  public void markVisible(Rectangle bounds) {
    int x1 = Math.max(0, convertMapXtoGridX(bounds.x));
    int y1 = Math.max(0, convertMapYtoGridY(bounds.y));
    int x2 = Math.min(gridWidth - 1, convertMapXtoGridX(bounds.x
        + bounds.width));
    int y2 = Math.min(gridHeight - 1, convertMapYtoGridY(bounds.y
        + bounds.height));

    for (int y = y1; y <= y2; y++) {
      int offset = y * gridWidth;
      for (int x = x1; x <= x2; x++) {
        grid[offset + x].visible = true;
      }
    }
  }

  /**
   * Adds a GameObject to this manager.
   */
  public void add(GameObject object) {
    if (object != null) {
      if (object == player) {
        // ensure player always moves first
        allObjects.add(0, object);
      else {
        allObjects.add(object);
      }
      Cell cell = getCell(object);
      if (cell != null) {
        cell.objects.add(object);
      }

    }
  }

  /**
   * Removes a GameObject from this manager.
   */
  public void remove(GameObject object) {
    if (object != null) {
      allObjects.remove(object);
      Cell cell = getCell(object);
      if (cell != null) {
        cell.objects.remove(object);
      }
    }
  }

  /**
   * Adds a GameObject to this manager, specifying it as the player object. An
   * existing player object, if any, is not removed.
   */
  public void addPlayer(GameObject player) {
    this.player = player;
    if (player != null) {
      player.notifyVisible(true);
      add(player);
    }
  }

  /**
   * Gets the object specified as the Player object, or null if no player
   * object was specified.
   */
  public GameObject getPlayer() {
    return player;
  }

  /**
   * Gets the cell the specified GameObject is in, or null if the GameObject
   * is not within the map bounds.
   */
  private Cell getCell(GameObject object) {
    int x = convertMapXtoGridX((intobject.getX());
    int y = convertMapYtoGridY((intobject.getZ());
    return getCell(x, y);
  }

  /**
   * Gets the cell of the specified grid location, or null if the grid
   * location is invalid.
   */
  private Cell getCell(int x, int y) {

    // check bounds
    if (x < || y < || x >= gridWidth || y >= gridHeight) {
      return null;
    }

    // get the cell at the x,y location
    return grid[x + y * gridWidth];
  }

  /**
   * Updates all objects based on the amount of time passed from the last
   * update and applied collision detection.
   */
  public void update(long elapsedTime) {
    for (int i = 0; i < allObjects.size(); i++) {
      GameObject object = (GameObjectallObjects.get(i);

      // save the object's old position
      Cell oldCell = getCell(object);
      oldLocation.setTo(object.getLocation());

      // move the object
      object.update(player, elapsedTime);

      // remove the object if destroyed
      if (object.isDestroyed()) {
        allObjects.remove(i);
        i--;
        if (oldCell != null) {
          oldCell.objects.remove(object);
        }
        continue;
      }

      // if the object moved, do collision detection
      if (!object.getLocation().equals(oldLocation)) {

        // check walls, floors, and ceilings
        collisionDetection.checkBSP(object, oldLocation, elapsedTime);

        // check other objects
        if (checkObjectCollision(object, oldLocation)) {
          // revert to old position
          object.getLocation().setTo(oldLocation);
        }

        // update grid location
        Cell cell = getCell(object);
        if (cell != oldCell) {
          if (oldCell != null) {
            oldCell.objects.remove(object);
          }
          if (cell != null) {
            cell.objects.add(object);
          }
        }
      }

    }
  }

  /**
   * Checks to see if the specified object collides with any other object.
   */
  public boolean checkObjectCollision(GameObject object, Vector3D oldLocation) {

    boolean collision = false;

    // use the object's (x,z) position (ground plane)
    int x = convertMapXtoGridX((intobject.getX());
    int y = convertMapYtoGridY((intobject.getZ());

    // check the object's surrounding 9 cells
    for (int i = x - 1; i <= x + 1; i++) {
      for (int j = y - 1; j <= y + 1; j++) {
        Cell cell = getCell(i, j);
        if (cell != null) {
          collision |= collisionDetection.checkObject(object,
              cell.objects, oldLocation);
        }
      }
    }

    return collision;
  }

  /**
   * Draws all visible objects and marks all objects as not visible.
   */
  public void draw(Graphics2D g, GameObjectRenderer r) {
    for (int i = 0; i < grid.length; i++) {
      List objects = grid[i].objects;
      for (int j = 0; j < objects.size(); j++) {
        GameObject object = (GameObjectobjects.get(j);
        boolean visible = false;
        if (grid[i].visible) {
          visible = r.draw(g, object);
        }
        if (object != player) {
          // notify objects if they are visible
          object.notifyVisible(visible);
        }
      }
      grid[i].visible = false;
    }
  }
}

/**
 * The CollisionDetection class handles collision detection between the
 * GameObjects, and between GameObjects and a BSP tree. When a collision occurs,
 * the GameObject stops.
 */

class CollisionDetection {

  /**
   * Bounding game object corners used to test for intersection with the BSP
   * tree. Corners are in either clockwise or counter-clockwise order.
   */
  private static final Point2D.Float[] CORNERS = new Point2D.Float(-1, -1),
      new Point2D.Float(-11)new Point2D.Float(11),
      new Point2D.Float(1, -1)};

  private BSPTree bspTree;

  private BSPLine path;

  private Point2D.Float intersection;

  /**
   * Creates a new CollisionDetection object for the specified BSP tree.
   */
  public CollisionDetection(BSPTree bspTree) {
    this.bspTree = bspTree;
    path = new BSPLine();
    intersection = new Point2D.Float();
  }

  /**
   * Checks a GameObject against the BSP tree. Returns true if a wall
   * collision occurred.
   */
  public boolean checkBSP(GameObject object, Vector3D oldLocation,
      long elapsedTime) {

    boolean wallCollision = false;

    // check walls if x or z position changed
    if (object.getX() != oldLocation.x || object.getZ() != oldLocation.z) {
      wallCollision = (checkWalls(object, oldLocation, elapsedTime!= null);
    }

    getFloorAndCeiling(object);
    checkFloorAndCeiling(object, elapsedTime);

    return wallCollision;
  }

  /**
   * Gets the floor and ceiling values for the specified GameObject. Calls
   * object.setFloorHeight() and object.setCeilHeight() to set the floor and
   * ceiling values.
   */
  public void getFloorAndCeiling(GameObject object) {
    float x = object.getX();
    float z = object.getZ();
    float r = object.getBounds().getRadius() 1;
    float floorHeight = Float.MIN_VALUE;
    float ceilHeight = Float.MAX_VALUE;
    BSPTree.Leaf leaf = bspTree.getLeaf(x, z);
    if (leaf != null) {
      floorHeight = leaf.floorHeight;
      ceilHeight = leaf.ceilHeight;
    }

    // check surrounding four points
    for (int i = 0; i < CORNERS.length; i++) {
      float xOffset = r * CORNERS[i].x;
      float zOffset = r * CORNERS[i].y;
      leaf = bspTree.getLeaf(x + xOffset, z + zOffset);
      if (leaf != null) {
        floorHeight = Math.max(floorHeight, leaf.floorHeight);
        ceilHeight = Math.min(ceilHeight, leaf.ceilHeight);
      }
    }

    object.setFloorHeight(floorHeight);
    object.setCeilHeight(ceilHeight