BSP Map Test : BSP Map « 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 » BSP MapScreenshots 
BSP Map 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 BSPMapTest extends ShooterCore {

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

  protected BSPTree bspTree;

  protected String mapFile;

  public BSPMapTest(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() {
    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();
    }

    gameObjectManager = new SimpleGameObjectManager();
    gameObjectManager.addPlayer(new GameObject(new PolygonGroup("Player")));
    ((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 draw(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);

    super.drawText(g);
  }
}

/**
 * The PolygonRenderer class is an abstract class that transforms and draws
 * polygons onto the screen.
 */

abstract class PolygonRenderer {

  protected ScanConverter scanConverter;

  protected Transform3D camera;

  protected ViewWindow viewWindow;

  protected boolean clearViewEveryFrame;

  protected Polygon3D sourcePolygon;

  protected Polygon3D destPolygon;

  /**
   * Creates a new PolygonRenderer with the specified Transform3D (camera) and
   * ViewWindow. The view is cleared when startFrame() is called.
   */
  public PolygonRenderer(Transform3D camera, ViewWindow viewWindow) {
    this(camera, viewWindow, true);
  }

  /**
   * Creates a new PolygonRenderer with the specified Transform3D (camera) and
   * ViewWindow. If clearViewEveryFrame is true, the view is cleared when
   * startFrame() is called.
   */
  public PolygonRenderer(Transform3D camera, ViewWindow viewWindow,
      boolean clearViewEveryFrame) {
    this.camera = camera;
    this.viewWindow = viewWindow;
    this.clearViewEveryFrame = clearViewEveryFrame;
    init();
  }

  /**
   * Create the scan converter and dest polygon.
   */
  protected void init() {
    destPolygon = new Polygon3D();
    scanConverter = new ScanConverter(viewWindow);
  }

  /**
   * Gets the camera used for this PolygonRenderer.
   */
  public Transform3D getCamera() {
    return camera;
  }

  /**
   * Indicates the start of rendering of a frame. This method should be called
   * every frame before any polygons are drawn.
   */
  public void startFrame(Graphics2D g) {
    if (clearViewEveryFrame) {
      g.setColor(Color.black);
      g.fillRect(viewWindow.getLeftOffset(), viewWindow.getTopOffset(),
          viewWindow.getWidth(), viewWindow.getHeight());
    }
  }

  /**
   * Indicates the end of rendering of a frame. This method should be called
   * every frame after all polygons are drawn.
   */
  public void endFrame(Graphics2D g) {
    // do nothing, for now.
  }

  /**
   * Transforms and draws a polygon.
   */
  public boolean draw(Graphics2D g, Polygon3D poly) {
    if (poly.isFacing(camera.getLocation())) {
      sourcePolygon = poly;
      destPolygon.setTo(poly);
      destPolygon.subtract(camera);
      boolean visible = destPolygon.clip(-1);
      if (visible) {
        destPolygon.project(viewWindow);
        visible = scanConverter.convert(destPolygon);
        if (visible) {
          drawCurrentPolygon(g);
          return true;
        }
      }
    }
    return false;
  }

  /**
   * Draws the current polygon. At this point, the current polygon is
   * transformed, clipped, projected, scan-converted, and visible.
   */
  protected abstract void drawCurrentPolygon(Graphics2D g);
}

/**
 * The ScanConverter class converts a projected polygon into a series of
 * horizontal scans for drawing.
 */

class ScanConverter {

  private static final int SCALE_BITS = 16;

  private static final int SCALE = << SCALE_BITS;

  private static final int SCALE_MASK = SCALE - 1;

  protected ViewWindow view;

  protected Scan[] scans;

  protected int top;

  protected int bottom;

  /**
   * A horizontal scan line.
   */
  public static class Scan {
    public int left;

    public int right;

    /**
     * Sets the left and right boundary for this scan if the x value is
     * outside the current boundary.
     */
    public void setBoundary(int x) {
      if (x < left) {
        left = x;
      }
      if (x - > right) {
        right = x - 1;
      }
    }

    /**
     * Clears this scan line.
     */
    public void clear() {
      left = Integer.MAX_VALUE;
      right = Integer.MIN_VALUE;
    }

    /**
     * Determines if this scan is valid (if left <= right).
     */
    public boolean isValid() {
      return (left <= right);
    }

    /**
     * Sets this scan.
     */
    public void setTo(int left, int right) {
      this.left = left;
      this.right = right;
    }

    /**
     * Checks if this scan is equal to the specified values.
     */
    public boolean equals(int left, int right) {
      return (this.left == left && this.right == right);
    }
  }

  /**
   * Creates a new ScanConverter for the specified ViewWindow. The
   * ViewWindow's properties can change in between scan conversions.
   */
  public ScanConverter(ViewWindow view) {
    this.view = view;
  }

  /**
   * Gets the top boundary of the last scan-converted polygon.
   */
  public int getTopBoundary() {
    return top;
  }

  /**
   * Gets the bottom boundary of the last scan-converted polygon.
   */
  public int getBottomBoundary() {
    return bottom;
  }

  /**
   * Gets the scan line for the specified y value.
   */
  public Scan getScan(int y) {
    return scans[y];
  }

  /**
   * Ensures this ScanConverter has the capacity to scan-convert a polygon to
   * the ViewWindow.
   */
  protected void ensureCapacity() {
    int height = view.getTopOffset() + view.getHeight();
    if (scans == null || scans.length != height) {
      scans = new Scan[height];
      for (int i = 0; i < height; i++) {
        scans[inew Scan();
      }
      // set top and bottom so clearCurrentScan clears all
      top = 0;
      bottom = height - 1;
    }

  }

  /**
   * Clears the current scan.
   */
  private void clearCurrentScan() {
    for (int i = top; i <= bottom; i++) {
      scans[i].clear();
    }
    top = Integer.MAX_VALUE;
    bottom = Integer.MIN_VALUE;
  }

  /**
   * Scan-converts a projected polygon. Returns true if the polygon is visible
   * in the view window.
   */
  public boolean convert(Polygon3D polygon) {

    ensureCapacity();
    clearCurrentScan();

    int minX = view.getLeftOffset();
    int maxX = view.getLeftOffset() + view.getWidth() 1;
    int minY = view.getTopOffset();
    int maxY = view.getTopOffset() + view.getHeight() 1;

    int numVertices = polygon.getNumVertices();
    for (int i = 0; i < numVertices; i++) {
      Vector3D v1 = polygon.getVertex(i);
      Vector3D v2;
      if (i == numVertices - 1) {
        v2 = polygon.getVertex(0);
      else {
        v2 = polygon.getVertex(i + 1);
      }

      // ensure v1.y < v2.y
      if (v1.y > v2.y) {
        Vector3D temp = v1;
        v1 = v2;
        v2 = temp;
      }
      float dy = v2.y - v1.y;

      // ignore horizontal lines
      if (dy == 0) {
        continue;
      }

      int startY = Math.max(MoreMath.ceil(v1.y), minY);
      int endY = Math.min(MoreMath.ceil(v2.y1, maxY);
      top = Math.min(top, startY);
      bottom = Math.max(bottom, endY);
      float dx = v2.x - v1.x;

      // special case: vertical line
      if (dx == 0) {
        int x = MoreMath.ceil(v1.x);
        // ensure x within view bounds
        x = Math.min(maxX + 1, Math.max(x, minX));
        for (int y = startY; y <= endY; y++) {
          scans[y].setBoundary(x);
        }
      else {
        // scan-convert this edge (line equation)
        float gradient = dx / dy;

        // (slower version)
        /*
         * for (int y=startY; y <=endY; y++) { int x =
         * MoreMath.ceil(v1.x + (y - v1.y) * gradient); // ensure x
         * within view bounds x = Math.min(maxX+1, Math.max(x, minX));
         * scans[y].setBoundary(x); }
         */

        // (faster version)
        // trim start of line
        float startX = v1.x + (startY - v1.y* gradient;
        if (startX < minX) {
          int yInt = (int) (v1.y + (minX - v1.x/ gradient);
          yInt = Math.min(yInt, endY);
          while (startY <= yInt) {
            scans[startY].setBoundary(minX);
            startY++;
          }
        else if (startX > maxX) {
          int yInt = (int) (v1.y + (maxX - v1.x/ gradient);
          yInt = Math.min(yInt, endY);
          while (startY <= yInt) {
            scans[startY].setBoundary(maxX + 1);
            startY++;
          }
        }

        if (startY > endY) {
          continue;
        }

        // trim back of line
        float endX = v1.x + (endY - v1.y* gradient;
        if (endX < minX) {
          int yInt = MoreMath.ceil(v1.y + (minX - v1.x/ gradient);
          yInt = Math.max(yInt, startY);
          while (endY >= yInt) {
            scans[endY].setBoundary(minX);
            endY--;
          }
        else if (endX > maxX) {
          int yInt = MoreMath.ceil(v1.y + (maxX - v1.x/ gradient);
          yInt = Math.max(yInt, startY);
          while (endY >= yInt) {
            scans[endY].setBoundary(maxX + 1);
            endY--;
          }
        }

        if (startY > endY) {
          continue;
        }

        // line equation using integers
        int xScaled = (int) (SCALE * v1.x + SCALE * (startY - v1.y)
            * dx / dy)
            + SCALE_MASK;
        int dxScaled = (int) (dx * SCALE / dy);

        for (int y = startY; y <= endY; y++) {
          scans[y].setBoundary(xScaled >> SCALE_BITS);
          xScaled += dxScaled;
        }
      }
    }

    // check if visible (any valid scans)
    for (int i = top; i <= bottom; i++) {
      if (scans[i].isValid()) {
        return true;
      }
    }
    return false;
  }

}

/**
 * The MoreMath class provides functions not contained in the java.lang.Math or
 * java.lang.StrictMath classes.
 */

class MoreMath {

  /**
   * Returns the sign of the number. Returns -1 for negative, 1 for positive,
   * and 0 otherwise.
   */
  public static int sign(short v) {
    return (v > 0(v < 0? -0;
  }

  /**
   * Returns the sign of the number. Returns -1 for negative, 1 for positive,
   * and 0 otherwise.
   */
  public static int sign(int v) {
    return (v > 0(v < 0? -0;
  }

  /**
   * Returns the sign of the number. Returns -1 for negative, 1 for positive,
   * and 0 otherwise.
   */
  public static int sign(long v) {
    return (v > 0(v < 0? -0;
  }

  /**
   * Returns the sign of the number. Returns -1 for negative, 1 for positive,
   * and 0 otherwise.
   */
  public static int sign(float v) {
    return (v > 0(v < 0? -0;
  }

  /**
   * Returns the sign of the number. Returns -1 for negative, 1 for positive,
   * and 0 otherwise.
   */
  public static int sign(double v) {
    return (v > 0(v < 0? -0;
  }

  /**
   * Faster ceil function to convert a float to an int. Contrary to the
   * java.lang.Math ceil function, this function takes a float as an argument,
   * returns an int instead of a double, and does not consider special cases.
   */
  public static int ceil(float f) {
    if (f > 0) {
      return (intf + 1;
    else {
      return (intf;
    }
  }

  /**
   * Faster floor function to convert a float to an int. Contrary to the
   * java.lang.Math floor function, this function takes a float as an
   * argument, returns an int instead of a double, and does not consider
   * special cases.
   */
  public static int floor(float f) {
    if (f >= 0) {
      return (intf;
    else {
      return (intf - 1;
    }
  }

  /**
   * Returns true if the specified number is a power of 2.
   */
  public static boolean isPowerOfTwo(int n) {
    return ((n & (n - 1)) == 0);
  }

  /**
   * Gets the number of "on" bits in an integer.
   */
  public static int getBitCount(int n) {
    int count = 0;
    while (n > 0) {
      count += (n & 1);
      n >>= 1;
    }
    return count;
  }
}

/**
 * The ViewWindow class represents the geometry of a view window for 3D viewing.
 */

class ViewWindow {

  private Rectangle bounds;

  private float angle;

  private float distanceToCamera;

  /**
   * Creates a new ViewWindow with the specified bounds on the screen and
   * horizontal view angle.
   */
  public ViewWindow(int left, int top, int width, int height, float angle) {
    bounds = new Rectangle();
    this.angle = angle;
    setBounds(left, top, width, height);
  }

  /**
   * Sets the bounds for this ViewWindow on the screen.
   */
  public void setBounds(int left, int top, int width, int height) {
    bounds.x = left;
    bounds.y = top;
    bounds.width = width;
    bounds.height = height;
    distanceToCamera = (bounds.width / 2(floatMath.tan(angle / 2);
  }

  /**
   * Sets the horizontal view angle for this ViewWindow.
   */
  public void setAngle(float angle) {
    this.angle = angle;
    distanceToCamera = (bounds.width / 2(floatMath.tan(angle / 2);
  }

  /**
   * Gets the horizontal view angle of this view window.
   */
  public float getAngle() {
    return angle;
  }

  /**
   * Gets the width of this view window.
   */
  public int getWidth() {
    return bounds.width;
  }

  /**
   * Gets the height of this view window.
   */
  public int getHeight() {
    return bounds.height;
  }

  /**
   * Gets the y offset of this view window on the screen.
   */
  public int getTopOffset() {
    return bounds.y;
  }

  /**
   * Gets the x offset of this view window on the screen.
   */
  public int getLeftOffset() {
    return bounds.x;
  }

  /**
   * Gets the distance from the camera to to this view window.
   */
  public float getDistance() {
    return distanceToCamera;
  }

  /**
   * Converts an x coordinate on this view window to the corresponding x
   * coordinate on the screen.
   */
  public float convertFromViewXToScreenX(float x) {
    return x + bounds.x + bounds.width / 2;
  }

  /**
   * Converts a y coordinate on this view window to the corresponding y
   * coordinate on the screen.
   */
  public float convertFromViewYToScreenY(float y) {
    return -y + bounds.y + bounds.height / 2;
  }

  /**
   * Converts an x coordinate on the screen to the corresponding x coordinate
   * on this view window.
   */
  public float convertFromScreenXToViewX(float x) {
    return x - bounds.x - bounds.width / 2;
  }

  /**
   * Converts an y coordinate on the screen to the corresponding y coordinate
   * on this view window.
   */
  public float convertFromScreenYToViewY(float y) {
    return -y + bounds.y + bounds.height / 2;
  }

  /**
   * Projects the specified vector to the screen.
   */
  public void project(Vector3D v) {
    // project to view window
    v.x = distanceToCamera * v.x / -v.z;
    v.y = distanceToCamera * v.y / -v.z;

    // convert to screen coordinates
    v.x = convertFromViewXToScreenX(v.x);
    v.y = con