
Кроме того, на консоль выдается ошибка выхода за пределы массива, исходящая из класса CollisionDetection, сообщающая, что он достиг границ карты, которые равны 5x5 (для целей тестирования).
Исключение в потоке «Thread-0» java.lang.ArrayIndexOutOfBoundsException: индекс 5 из 5 выходит за пределы для длины 5
в lu.embellishedduck.liminalmurmurs.engine.CollisionDetection.checkTileCollision (CollisionDetection.java:134)
...
Вот код класса CollisionDetection, отмечена строка, которая выдает ошибку. по заголовку
Код: Выделить всё
public class CollisionDetection {
//=======================
// INSTANTIATE VARIABLES
//=======================
GamePanel gamePanel;
//=============
// CONSTRUCTOR
//=============
public CollisionDetection(GamePanel gamePanel) {
this.gamePanel = gamePanel;
}//End of Constructor
//=======================================================
// METHOD TO CHECK A TILE TO SEE IF IT WILL COLLIDE WITH
// THE ENTITY PASSED IN
//=======================================================
public void checkTileCollision(Entity entity) {
//----------------------------------------------------
// FIRST UP THE ROW AND COL OF THE HIT-BOX ARE NEEDED
//----------------------------------------------------
int entityLeftWorldX = entity.getWorldX() + entity.getHitBox().x;
int entityRightWorldX = entity.getWorldX() + entity.getHitBox().x + entity.getHitBox().width;
int entityTopWorldY = entity.getWorldY() + entity.getHitBox().y;
int entityBottomWorldY = entity.getWorldY() + entity.getHitBox().y + entity.getHitBox().height;
int entityLeftCol = entityLeftWorldX / gamePanel.getTILE_SIZE();
int entityRightCol = entityRightWorldX / gamePanel.getTILE_SIZE();
int entityTopRow = entityTopWorldY / gamePanel.getTILE_SIZE();
int entityBottomRow = entityBottomWorldY / gamePanel.getTILE_SIZE();
int tileNum1, tileNum2;
//-----------------------
// SWITCH STATEMENT TIME
//-----------------------
switch (entity.getDirection()) {
case "up-left" :
entityTopRow = (entityTopWorldY - entity.getMovementSpeed()) / gamePanel.getTILE_SIZE();
tileNum1 = gamePanel.getTileManager().getMapTileNum()[entityLeftCol][entityTopRow];
if (gamePanel.getTileManager().getTiles()[tileNum1].isCollision()) {
entity.setCollisionOn(true);
}//End of If Statement
break;
case "up-right" :
entityTopRow = (entityTopWorldY - entity.getMovementSpeed()) / gamePanel.getTILE_SIZE();
tileNum1 = gamePanel.getTileManager().getMapTileNum()[entityRightCol][entityTopRow];
if (gamePanel.getTileManager().getTiles()[tileNum1].isCollision()) {
entity.setCollisionOn(true);
}//End of If Statement
break;
case "down-left" :
entityBottomRow = (entityBottomWorldY + entity.getMovementSpeed()) / gamePanel.getTILE_SIZE();
tileNum1 = gamePanel.getTileManager().getMapTileNum()[entityLeftCol][entityBottomRow];
if (gamePanel.getTileManager().getTiles()[tileNum1].isCollision()) {
entity.setCollisionOn(true);
}//End of If Statement
break;
case "down-right" :
entityBottomRow = (entityBottomWorldY + entity.getMovementSpeed()) / gamePanel.getTILE_SIZE();
tileNum1 = gamePanel.getTileManager().getMapTileNum()[entityRightCol][entityBottomRow];
if (gamePanel.getTileManager().getTiles()[tileNum1].isCollision()) {
entity.setCollisionOn(true);
}//End of If-Statement
break;
case "up" :
entityTopRow = (entityTopWorldY - entity.getMovementSpeed()) / gamePanel.getTILE_SIZE();
//This essentially predicts where the player will be and checks for collision with the if statement
tileNum1 = gamePanel.getTileManager().getMapTileNum()[entityLeftCol][entityTopRow];
tileNum2 = gamePanel.getTileManager().getMapTileNum()[entityRightCol][entityTopRow];
if (gamePanel.getTileManager().getTiles()[tileNum1].isCollision() || gamePanel.getTileManager().getTiles()[tileNum2].isCollision()) {
entity.setCollisionOn(true);
}//End of If Statement
break;
case "down" :
entityBottomRow = (entityBottomWorldY + entity.getMovementSpeed()) / gamePanel.getTILE_SIZE();
// The line below is the erroneous one
tileNum1 = gamePanel.getTileManager().getMapTileNum()[entityLeftCol][entityBottomRow]; // THIS LINE
tileNum2 = gamePanel.getTileManager().getMapTileNum()[entityRightCol][entityBottomRow];
if (gamePanel.getTileManager().getTiles()[tileNum1].isCollision() || gamePanel.getTileManager().getTiles()[tileNum2].isCollision()) {
entity.setCollisionOn(true);
}//End of If Statement
break;
case "right" :
entityRightCol = (entityRightWorldX + entity.getMovementSpeed()) / gamePanel.getTILE_SIZE();
//This essentially predicts where the player will be and checks for collision with the if statement
tileNum1 = gamePanel.getTileManager().getMapTileNum()[entityRightCol][entityTopRow];
tileNum2 = gamePanel.getTileManager().getMapTileNum()[entityRightCol][entityBottomRow];
if (gamePanel.getTileManager().getTiles()[tileNum1].isCollision() || gamePanel.getTileManager().getTiles()[tileNum2].isCollision()) {
entity.setCollisionOn(true);
}//End of If Statement
break;
case "left" :
entityLeftCol = (entityLeftWorldX - entity.getMovementSpeed()) / gamePanel.getTILE_SIZE();
//This essentially predicts where the player will be and checks for collision with the if statement
tileNum1 = gamePanel.getTileManager().getMapTileNum()[entityLeftCol][entityTopRow];
tileNum2 = gamePanel.getTileManager().getMapTileNum()[entityLeftCol][entityBottomRow];
if (gamePanel.getTileManager().getTiles()[tileNum1].isCollision() || gamePanel.getTileManager().getTiles()[tileNum2].isCollision()) {
entity.setCollisionOn(true);
}//End of If Statement
break;
}//End of Switch-Case Statement
}//End of Method
}//End of Class
Кроме того, может возникнуть проблема с обработкой движений в классе Player, как показано ниже:
Код: Выделить всё
public class Player extends Entity {
//======================
// Instantiate Variables
//======================
GamePanel gamePanel;
KeyHandler keyHandler;
//These are hardcoded values that tell the program where on the screen the player character should start when they enter the game
private final int screenX;
private final int screenY;
//=============
// CONSTRUCTOR
//=============
public Player(GamePanel gp, KeyHandler keyHandler) {
this.gamePanel = gp;
this.keyHandler = keyHandler;
//This logic makes that player always start in the middle of the screen
screenX = gp.getSCREEN_WIDTH() / 2 - (gp.getTILE_SIZE() / 2);
screenY = gp.getSCREEN_HEIGHT() / 2 - (gp.getREAL_TILE_SIZE() / 2);
setHitBox(new Rectangle());
getHitBox().x = 16;
getHitBox().y = 32;
getHitBox().width = 64;
getHitBox().height = 64;
setDefaultValues();
getPlayerImage();
}//End of Constructor
//===========================================================
// Method to set the default values for the player variables
//===========================================================
public void setDefaultValues() {
//Obviously there will be more stats here in the future but those will have to be loaded to and from a save file
setMovementSpeed(4);
//Here the player's position is set relative to tile location on the world map
//for now I'm just setting this to 100 because I haven't made any world yet.
//Also, eventually there will be a save file system which will let the player
//continue from where they left off on the map.
//Should be mainPanel.getTileSize() * row/col
setWorldX(gamePanel.getTILE_SIZE() * 1);
setWorldY(gamePanel.getTILE_SIZE() * 2);
}//End of Method
//=======================================
// Method to get the image of the player
//=======================================
public void getPlayerImage() {
//Eventually there will be image IO things in here
}//End of Class
//==============================================================
// Method which handles the updating of the player's key inputs
//==============================================================
public void update() {
//-----------------
// Local Variables
//-----------------
int diagonalSpeed = (int) Math.round(getMovementSpeed() / Math.sqrt(2));
//----------------------------------------------------
// If Statement barrage! This time handling all cases
//----------------------------------------------------
if (keyHandler.isUpPressed() || keyHandler.isLeftPressed() || keyHandler.isRightPressed() || keyHandler.isDownPressed()
|| keyHandler.isUpLeftPressed() || keyHandler.isUpRightPressed() || keyHandler.isDownLeftPressed() || keyHandler. isDownRightPressed()) {
if (keyHandler.isUpLeftPressed()) {
setDirection("up-left");
} else if (keyHandler.isUpRightPressed()) {
setDirection("up-right");
} else if (keyHandler.isDownLeftPressed()) {
setDirection("down-left");
} else if (keyHandler.isDownRightPressed()) {
setDirection("down-right");
} else {
//Handling the primary movement
if (keyHandler.isUpPressed()) {
setDirection("up");
}
if (keyHandler.isDownPressed()) {
setDirection("down");
worldY += getMovementSpeed();
}
if (keyHandler.isRightPressed()) {
setDirection("right");
}
if (keyHandler.isLeftPressed()) {
setDirection("left");
}
}//End of Primary Movement Else Statement
//CHECK TILE COLLISION
setCollisionOn(false);
gamePanel.getCollisionDetector().checkTileCollision(this);
//IF COLLISION IS FALSE PLAYER CAN MOVE
if (!isCollisionOn()) {
//Another switch case which will deal with the player movement speed
switch (getDirection()) {
case "up-left" :
worldX -= diagonalSpeed;
worldY -= diagonalSpeed;
break;
case "up-right" :
worldX += diagonalSpeed;
worldY -= diagonalSpeed;
break;
case "down-left" :
worldX -= diagonalSpeed;
worldY += diagonalSpeed;
break;
case "down-right" :
worldX += diagonalSpeed;
worldY += diagonalSpeed;
break;
case "up" :
worldY -= getMovementSpeed();
break;
case "down" :
worldY += getMovementSpeed();
break;
case "right" :
worldX += getMovementSpeed();
break;
case "left" :
worldX -= getMovementSpeed();
break;
}//End of Switch-Case Statement
}//End of If Statement
}//End of If Statement Barrage
}//End of Method
//============================================================================
// Method which handles the drawing of the player to whichever panel calls it
//============================================================================
public void draw (Graphics2D graphics2D){
graphics2D.setColor(Color.WHITE);
graphics2D.fillRect(screenX, screenY, gamePanel.getTILE_SIZE(), gamePanel.getTILE_SIZE());
graphics2D.setColor(Color.RED);
graphics2D.fillRect(screenX + 16, screenY + 32, 64, 64);
}//End of Method
//=========
// GETTERS
//=========
public GamePanel getGamePanel() {
return gamePanel;
}
public KeyHandler getKeyHandler() {
return keyHandler;
}
public int getScreenX() {
return screenX;
}
public int getScreenY() {
return screenY;
}
//=========
// SETTERS
//=========
public void setGamePanel(GamePanel gamePanel) {
this.gamePanel = gamePanel;
}
public void setKeyHandler(KeyHandler keyHandler) {
this.keyHandler = keyHandler;
}
//=================
// toString METHOD
//=================
@Override
public String toString() {
return "Player{" +
"gp=" + gamePanel +
", keyHandler=" + keyHandler +
", screenX=" + screenX +
", screenY=" + screenY +
'}';
}//End of toString Method
}//End of Class
Я пробовал настроить фактическую скорость игрока и поменять местами некоторые математические операторы в полях tileNum, но они просто сгенерировали больше ошибки, и поэтому я их удалил. Помимо этого, я обнаружил несколько недостающих операторовbreak; для случая переключателя. Я просмотрел другие источники в Интернете, но ничего не нашел.
Глюк у меня нет понятия, что может быть причиной этого.
Подробнее здесь: https://stackoverflow.com/questions/788 ... d-is-doubl