CollisionDetection.java :  » Game » Arianne-RPG-0.83 » games » stendhal » common » Java Open Source

Java Open Source » Game » Arianne RPG 0.83 
Arianne RPG 0.83 » games » stendhal » common » CollisionDetection.java
/* $Id: CollisionDetection.java,v 1.50 2009/10/17 11:47:42 nhnb Exp $ */
/***************************************************************************
 *                      (C) Copyright 2003 - Marauroa                      *
 ***************************************************************************
 ***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
package games.stendhal.common;

import games.stendhal.tools.tiled.LayerDefinition;

import java.awt.geom.Rectangle2D;

/**
 * This class loads the map and allow you to determine if a player collides or
 * not with any of the non trespasable areas of the world.
 */
public class CollisionDetection {
  CollisionMap map;

  private int width;

  private int height;

  public void clear() {
    if (map == null) {
      map = new CollisionMap(width, height);
    }
  }

  public void init(final int width, final int height) {
    if (this.width != width || this.height != height) {
      map = null;
    }
    
    
    this.width = width;
    this.height = height;
    
    clear();
  }

  public void setCollide(final int x, final int y) {
    
    if ((x < 0) || (x >= width) || (y < 0) || (y >= height)) {
      return;
    }
    map.set(x, y);
  }

  public void setCollide(final Rectangle2D shape, final boolean value) {
    final double x = shape.getX();
    final double y = shape.getY();
    final double w = shape.getWidth();
    final double h = shape.getHeight();
  
    
    if ((x < 0) || (x/* +w */ >= width)) {
      return;
    }

    if ((y < 0) || (y/* +h */ >= height)) {
      return;
    }

    int startx = 0;
    if ((x >= 0)) {
      startx = (int) x;
    } 
    
    final int endx;
    if (x + w < width) {
      endx = (int) (x + w);
    } else {
      endx = width;
    }
    int starty = 0;
    if (y >= 0) {
      starty = (int) y;
    }
     
    final int endy;
    if (y + h < height) {
      endy = (int) (y + h);
    } else {
      endy = height;
    }

    for (int k = starty; k < endy; k++) {
      for (int i = startx; i < endx; i++) {
        if (value) {
          map.set(i, k);
        } else {
          map.unset(i, k);
        }
      }
    }
  }

  public void setCollisionData(final LayerDefinition collisionLayer) {
    /* First we build the int array. */
    collisionLayer.build();

    width = collisionLayer.getWidth();
    height = collisionLayer.getHeight();
    map = new CollisionMap(width, height);
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        /*
         * NOTE: Right now our collision detection system is binary, so
         * something or is blocked or is not.
         */
        boolean b = collisionLayer.getTileAt(x, y) != 0;
        if (b) {
          map.set(x, y);
        }
        
        
      }
    }
  }

  /** Print the area around the (x,y) useful for debugging. 
   * @param x 
   * @param y 
   * @param size */
  public void printaround(final int x, final int y, final int size) {
    for (int j = y - size; j < y + size; j++) {
      for (int i = x - size; i < x + size; i++) {
        if ((j >= 0) && (j < height) && (i >= 0) && (i < width)) {
          if ((j == y) && (i == x)) {
            System.out.print("O");
          } else if (map.get(i, j)) {
            System.out.print("X");
          } else {
            System.out.print(".");
          }
        }
      }
      System.out.println();
    }
  }

  public boolean walkable(final double x, final double y) {
    return !map.get((int) x, (int) y);
  }

  public boolean leavesZone(final Rectangle2D shape) {
    final double x = shape.getX();
    final double y = shape.getY();
    // double w=shape.getWidth();
    // double h=shape.getHeight();

    if ((x < 0) || (x/* +w */ >= width)) {
      return true;
    }

    if ((y < 0) || (y/* +h */ >= height)) {
      return true;
    }

    return false;
  }

  /**
   * @param shape 
   * @return true if the shape enters in any of the non trespasable areas of
   * the map.
   */
  public boolean collides(final Rectangle2D shape) {
    final double x = shape.getX();
    final double y = shape.getY();
    double w = shape.getWidth();
    double h = shape.getHeight();
    if ((x < 0) || (x/* +w */ >= width)) {
      return true;
    }

    if ((y < 0) || (y/* +h */ >= height)) {
      return true;
    }

    final double startx;
    if (x >= 0) {
      startx = x;
    } else {
      startx = 0;
    }
    final double endx;
    if (x + w < width) {
      endx = x + w;
    } else {
      endx = width;
    }
    final double starty;
    if (y >= 0) {
      starty = y;
    } else {
      starty = 0;
    }
    final double endy;
    if (y + h < height) {
      endy = y + h;
    } else {
      endy = height;
    }

    /*
     * TODO: the advantages from using bitset in collissionmapare lost here
     * the weird behaviour with clientside player when using map.collides (x,y,width, height)
     * is caused by the delta calculation for 2dviewtiles; 
     */
    
    for (int k = (int) starty; k < endy; k++) {
      
      for (int i = (int) startx; i < endx; i++) {
        if (map.get(i, k)) {
          return true;
        }
      }
    }

    return false;
  }

  public boolean collides(final int x, final int y) {
    if ((x < 0) || (x >= width)) {
      return true;
    }

    if ((y < 0) || (y >= height)) {
      return true;
    }
    return map.get(x, y);
  }

  public int getWidth() {
    return width;
  }

  public int getHeight() {
    return height;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.