/** * 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); }
/** * 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); }