예제 #1
0
파일: Entity.java 프로젝트: kmeaw/ultraworm
  /**
   * Collision detection.
   *
   * @param dest The entity to check for collision with.
   * @return true if this entity is touching the destination entity; note that an entity can never
   *     be touching itself
   */
  public final boolean isTouching(Entity dest) {
    if (dest == this) {
      return false;
    }

    if (isRound() && getRadius() == 0) {
      return false;
    }

    if (dest.isRound() && dest.getRadius() == 0) {
      return false;
    }

    if (!isRound() && getBounds(BOUNDS).isEmpty()) {
      return false;
    }

    if (!dest.isRound() && dest.getBounds(TEMP).isEmpty()) {
      return false;
    }

    // At this point, BOUNDS and TEMP hold bounding rectangles, which we might
    // use if it's a rect-rect collision

    if (isRound() && dest.isRound()) {
      // Round-Round collision check
      float dx = dest.mapX + dest.getCollisionX() - (this.mapX + this.getCollisionX());
      float dy = dest.mapY + dest.getCollisionY() - (this.mapY + this.getCollisionY());
      dx *= dx;
      dy *= dy;

      return Math.sqrt(dx + dy) < getRadius() + dest.getRadius();
    } else if (isRound() && !dest.isRound()) {
      // Round-Rect collison check
      return rectRoundCollisionCheck(
          mapX + getCollisionX(), mapY + getCollisionY(), getRadius(), TEMP);
    } else if (!isRound() && dest.isRound()) {
      // Rect-round collision check
      return rectRoundCollisionCheck(
          dest.mapX + dest.getCollisionX(),
          dest.mapY + dest.getCollisionY(),
          dest.getRadius(),
          BOUNDS);
    } else {
      // Rect-rect collision check
      return BOUNDS.intersects(TEMP);
    }
  }
예제 #2
0
파일: Entity.java 프로젝트: kmeaw/ultraworm
  /**
   * Can we see this location?
   *
   * @param mapX
   * @param mapY
   * @param positive If non null, if this entity is detected, algorithm returns true
   * @param targetFlying If true, and positive is a flying gidrah, we ignore walls and simply return
   *     true
   * @return true if there is a LOS to the specified map location
   */
  public boolean canSee(float mapX, float mapY, Entity positive, boolean targetFlying) {
    if (targetFlying && positive != null && positive.isFlying()) {
      return true;
    }
    WormGameState gameState = Worm.getGameState();
    GameMap map = gameState.getMap();
    ArrayList<Entity> entities = gameState.getEntities();
    int n = entities.size();
    // Create a list of solid entities we think are somewhere in the LOS
    ENTITYCACHE.clear();
    for (int i = 0; i < n; i++) {
      Entity e = entities.get(i);
      if (e != this && e.isActive() && e.isSolid()) {
        double dist = Util.distanceFromLineToPoint(getX(), getY(), mapX, mapY, e.getX(), e.getY());
        if (dist >= 0.0 && dist <= e.getRadius()) {
          ENTITYCACHE.add(e);
        }
      }
    }
    int numCachedEntities = ENTITYCACHE.size();
    BRESENHAM.plot((int) getX(), (int) getY(), (int) mapX, (int) mapY);
    int oldMapX = -1, oldMapY = -1;
    while (BRESENHAM.next()) {
      int x = BRESENHAM.getX() / MapRenderer.TILE_SIZE;
      int y = BRESENHAM.getY() / MapRenderer.TILE_SIZE;
      if (x != oldMapX || y != oldMapY) {
        for (int z = 0; z < GameMap.LAYERS; z++) {
          Tile tile = map.getTile(x, y, z);
          if (tile != null && !tile.isBulletThrough()) {
            // Tile blocks LOS
            return false;
          }
        }
        oldMapX = x;
        oldMapY = y;
      }

      // Check entity list
      if (positive != null) {
        for (int i = 0; i < numCachedEntities; i++) {
          Entity e = ENTITYCACHE.get(i);
          if (e == positive
              && e.getDistanceTo(BRESENHAM.getX(), BRESENHAM.getY()) < e.getRadius()) {
            return true;
          }
        }
      }

      // Skip 4 pixels at a time
      if (!BRESENHAM.next()) {
        break;
      }
      if (!BRESENHAM.next()) {
        break;
      }
      if (!BRESENHAM.next()) {
        break;
      }
    }
    return true;
  }