Esempio n. 1
0
  /**
   * 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);
  }