コード例 #1
0
ファイル: DungeonGame.java プロジェクト: qmpzaltb/cptgame
  /**
   * intersectsCircleMapTile: This method checks whether a circle intersects a specified map tile.
   * Pre: The map tile must exist. Post: A boolean will be returned indicating whether the shapes
   * collide (true) or do not collide (false)
   */
  private static boolean intersectsCircleMapTile(
      double circleX, double circleY, double circleRadius, int mapX, int mapY) {

    // Distance from circle center to map tile center (non-negative)
    double dCircleTileDistanceX = Math.abs(circleX - (mapX + 0.5));
    double dCircleTileDistanceY = Math.abs(circleY - (mapY + 0.5));

    // Case: no intersection when the circle's bounding box does not intersect the tile's bounding
    // box.
    if (dCircleTileDistanceX > (0.5 + circleRadius)) {
      return false;
    }
    if (dCircleTileDistanceY > (0.5 + circleRadius)) {
      return false;
    }

    // Case: Intersection when the circle's center lies inside the box
    if (dCircleTileDistanceX <= 0.5) {
      return true;
    }
    if (dCircleTileDistanceY <= 0.5) {
      return true;
    }

    // Case: Intersection if an identical circle placed on the map-tile's corners intersects the
    // original circle. //Variable left squared to save processor speed.
    double dCornerCircleIntersectionDistance =
        (dCircleTileDistanceX - 0.5) * (dCircleTileDistanceX - 0.5)
            + (dCircleTileDistanceY - 0.5) * (dCircleTileDistanceY - 0.5);
    return (dCornerCircleIntersectionDistance <= circleRadius * circleRadius);
  }
コード例 #2
0
ファイル: DungeonGame.java プロジェクト: qmpzaltb/cptgame
 /**
  * valueInBoundsY: This method returns the closest value within the y-coordinates of the map. Pre:
  * The map must exist. Post: Returns the closest value to the parameters that is in the
  * y-coordinates.
  */
 public static int valueInBoundsY(int value) {
   return Math.max(Math.min(dngCurrentDungeon.iDungeonYSize, value), 0);
 }
コード例 #3
0
ファイル: DungeonGame.java プロジェクト: qmpzaltb/cptgame
  /**
   * moveEntity: This method moves an entity and checks the potential move for collisions. Pre: The
   * game must have been initialized. The entity at the index must not be null. Post: The entity
   * will have been moved accordingly.
   */
  public static void moveEntity(int iEntityID) {

    boolean bXHandled = false;
    boolean bYHandled = false;
    boolean bCollidesWithWalls = handleEntity(iEntityID).collidesWithWalls();
    // X and Y displacements of the entity, provided that there will be no collisions.
    double dEntityXShift =
        Math.sin(handleEntity(iEntityID).getMovementDirection())
            * handleEntity(iEntityID).dMovementMagnitude;
    double dEntityYShift =
        (-1)
            * Math.cos(handleEntity(iEntityID).getMovementDirection())
            * handleEntity(iEntityID).dMovementMagnitude;

    // The pre-movement xposition, yposition, and circle radius.
    double dCurrentXPos = handleEntity(iEntityID).getXPos();
    double dCurrentYPos = handleEntity(iEntityID).getYPos();
    double dCurrentSize = handleEntity(iEntityID).getSize();

    // Hypothetical post-movement coordinates of the circle's bounding box
    double dNewXPosCenter = dCurrentXPos + dEntityXShift;
    double dNewXPosRight = dNewXPosCenter + dCurrentSize;
    double dNewXPosLeft = dNewXPosCenter - dCurrentSize;
    double dNewYPosCenter = dCurrentYPos + dEntityYShift;
    double dNewYPosTop = dNewYPosCenter - dCurrentSize;
    double dNewYPosBot = dNewYPosCenter + dCurrentSize;

    // Handling right-way movement
    if (dNewXPosCenter < dngCurrentDungeon.getXSize() - dCurrentSize) {
      if (dEntityXShift > 0 && !bXHandled && bCollidesWithWalls) { // Entity is moving right
        rightMovingCollisions:
        for (int iuP1 = (int) dNewXPosLeft; iuP1 <= (int) dNewXPosRight; iuP1 += 1) {
          for (int iuP2 = valueInBoundsY((int) (dCurrentYPos - dCurrentSize));
              iuP2 <= valueInBoundsY((int) (dCurrentYPos + dCurrentSize));
              iuP2 += 1) {
            if (!isWalkable(handleTile(iuP1, iuP2).getTileType())) {
              if (intersectsCircleMapTile(dNewXPosCenter, dCurrentYPos, dCurrentSize, iuP1, iuP2)) {
                dEntityXShift =
                    Math.max(
                        (iuP1 - dCurrentXPos) - (dCurrentSize + DISTANCE_TO_KEEP_FROM_WALL), 0);
                break rightMovingCollisions;
              }
            }
          }
        }
        bXHandled = true;
      }
    } else {
      dEntityXShift = 0;
    }

    // Handling left-way movement
    if (dNewXPosCenter > 0 + dCurrentSize) {
      if (dEntityXShift < 0 && !bXHandled && bCollidesWithWalls) { // Entity is moving left
        leftMovingCollisions:
        for (int iuP1 = (int) dNewXPosRight; iuP1 >= (int) dNewXPosLeft; iuP1 -= 1) {
          for (int iuP2 = valueInBoundsY((int) (dCurrentYPos - dCurrentSize));
              iuP2 <= valueInBoundsY((int) (dCurrentYPos + dCurrentSize));
              iuP2 += 1) {
            if (!isWalkable(handleTile(iuP1, iuP2).getTileType())) {
              if (intersectsCircleMapTile(dNewXPosCenter, dCurrentYPos, dCurrentSize, iuP1, iuP2)) {
                dEntityXShift =
                    Math.min(
                        (iuP1 + 1 - dCurrentXPos) + (dCurrentSize + DISTANCE_TO_KEEP_FROM_WALL), 0);
                break leftMovingCollisions;
              }
            }
          }
        }
        bXHandled = true;
      }
    } else {
      dEntityXShift = 0;
    }

    // Handling down-way movement
    if (dNewYPosCenter < dngCurrentDungeon.getYSize() - dCurrentSize) {
      if (dEntityYShift > 0 && !bYHandled && bCollidesWithWalls) { // Entity is moving down
        downMovingCollisions:
        for (int iuP1 = (int) dNewYPosTop; iuP1 <= (int) dNewYPosBot; iuP1 += 1) {
          for (int iuP2 = valueInBoundsX((int) (dCurrentXPos - dCurrentSize));
              iuP2 <= valueInBoundsX((int) (dCurrentXPos + dCurrentSize));
              iuP2 += 1) {
            if (!isWalkable(handleTile(iuP2, iuP1).getTileType())) {
              if (intersectsCircleMapTile(dCurrentXPos, dNewYPosCenter, dCurrentSize, iuP2, iuP1)) {
                dEntityYShift =
                    Math.max(
                        (iuP1 - dCurrentYPos) - (dCurrentSize + DISTANCE_TO_KEEP_FROM_WALL), 0);
                break downMovingCollisions;
              }
            }
          }
        }
        bYHandled = true;
      }
    } else {
      dEntityYShift = 0;
    }

    // Handling up-way movement
    if (dNewYPosCenter > 0 + dCurrentSize) {
      if (dEntityYShift < 0 && !bYHandled && bCollidesWithWalls) { // Entity is moving up
        upMovingCollisions:
        for (int iuP1 = (int) dNewYPosBot; iuP1 >= (int) dNewYPosTop; iuP1 -= 1) {
          for (int iuP2 = valueInBoundsX((int) (dCurrentXPos - dCurrentSize));
              iuP2 <= valueInBoundsX((int) (dCurrentXPos + dCurrentSize));
              iuP2 += 1) {
            if (!isWalkable(handleTile(iuP2, iuP1).getTileType())) {
              if (intersectsCircleMapTile(dCurrentXPos, dNewYPosCenter, dCurrentSize, iuP2, iuP1)) {
                dEntityYShift =
                    Math.min(
                        (iuP1 + 1 - dCurrentYPos) + (dCurrentSize + DISTANCE_TO_KEEP_FROM_WALL), 0);
                break upMovingCollisions;
              }
            }
          }
        }
        bYHandled = true;
      }
    } else {
      dEntityYShift = 0;
    }

    dNewXPosCenter = dCurrentXPos + dEntityXShift;
    dNewYPosCenter = dCurrentYPos + dEntityYShift;
    if (handleEntity(iEntityID).collidesWithEntities()) {
      for (int iuP1 = 0; iuP1 < entveCurrentEntities.size(); iuP1++) {
        if (iuP1 != iEntityID) {
          if (handleEntity(iuP1).collidesWithEntities()) {
            double distance =
                (dNewXPosCenter - handleEntity(iuP1).getXPos())
                        * (dNewXPosCenter - handleEntity(iuP1).getXPos())
                    + (dNewYPosCenter - handleEntity(iuP1).getYPos())
                        * (dNewYPosCenter - handleEntity(iuP1).getYPos());
            if (distance
                < (dCurrentSize + handleEntity(iuP1).getSize())
                    * (dCurrentSize + handleEntity(iuP1).getSize())) {
              dEntityXShift = 0;
              dEntityYShift = 0;
            }
          }
        }
      }
    }

    // Moves the character by shifting their X and Y coordinates.
    handleEntity(iEntityID).shiftXPos(dEntityXShift);
    handleEntity(iEntityID).shiftYPos(dEntityYShift);
  }