diff --git a/.idea/misc.xml b/.idea/misc.xml index 291e70f5..9b2ea2a4 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,7 +3,7 @@ - + \ No newline at end of file diff --git a/src/fr/enssat/BoulderDash/controllers/BoulderAndDiamondController.java b/src/fr/enssat/BoulderDash/controllers/BoulderAndDiamondController.java index d06354c9..d780c795 100644 --- a/src/fr/enssat/BoulderDash/controllers/BoulderAndDiamondController.java +++ b/src/fr/enssat/BoulderDash/controllers/BoulderAndDiamondController.java @@ -17,146 +17,156 @@ import static fr.enssat.BoulderDash.helpers.AudioLoadHelper.AUDIO_LOAD_HELPER; * @since 2015-06-19 */ public class BoulderAndDiamondController extends AbstractLevelController implements Runnable { - private Thread elementMovingThread; + private Thread elementMovingThread; - /** - * Class constructor - * - * @param levelModel Level model - */ - public BoulderAndDiamondController(LevelModel levelModel) { - super(levelModel); + /** + * Class constructor + * + * @param levelModel Level model + */ + public BoulderAndDiamondController(LevelModel levelModel) { + super(levelModel); - // Start thread - this.elementMovingThread = new Thread(this); - this.elementMovingThread.start(); - } + // Start thread + this.elementMovingThread = new Thread(this); + this.elementMovingThread.start(); + } - /** - * Watches for elements to be moved - */ - public void run() { - while (this.levelModel.isGameRunning()) { - if (!this.levelModel.getGamePaused()) { - this.manageFallingObject(); - } - try { - Thread.sleep(250); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } + /** + * Watches for elements to be moved + */ + public void run() { + while (this.levelModel.isGameRunning()) { + if(!this.levelModel.getGamePaused()){ + this.manageFallingObject(); + } + try { + Thread.sleep(250); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } - /** - * Scan the ground to detect the boulders & the diamonds, then make them - * fall if necessary - * Note: scan of the ground upside down: we want things to fall slowly ! - */ - private void manageFallingObject() { - for (int x = this.levelModel.getSizeWidth() - 1; x >= 0; x--) { - for (int y = this.levelModel.getSizeHeight() - 1; y >= 0; y--) { - // Gets the spriteName of actual DisplayableElementModel object scanned - DisplayableElementModel elementModel = this.levelModel.getGroundLevelModel()[x][y]; + /** + * Scan the ground to detect the boulders & the diamonds, then make them + * fall if necessary + * Note: scan of the ground upside down: we want things to fall slowly ! + */ + private void manageFallingObject() { + for (int x = this.levelModel.getSizeWidth() - 1; x >= 0; x--) { + for (int y = this.levelModel.getSizeHeight() - 1; y >= 0; y--) { + // Gets the spriteName of actual DisplayableElementModel object scanned + DisplayableElementModel elementModel = this.levelModel.getElement(x, y); - if (elementModel == null) { - elementModel = new DirtModel(); - } + if(elementModel == null) { + elementModel = new DirtModel(); + } - String spriteName = elementModel.getSpriteName(); + String spriteName = elementModel.getSpriteName(); + + // If it is a boulder or a diamond... + if (spriteName == "boulder" || spriteName == "diamond") { + this.manageFallingObjectBehavior(x, y); + } else if(spriteName == "expandingwall"){ + if(this.expandWall(x,y).equals("left")){ + x -= 1; + } + } + } + } + } - // If it is a boulder or a diamond... - if (spriteName == "boulder" || spriteName == "diamond") { - this.manageFall(x, y); - } else if (spriteName == "expandingwall") { - if (this.expandWall(x, y).equals("left")) { - x -= 1; - } - } - } - } - } + /** + * Expand the wall at left & right + * + * @param x Horizontal position + * @param y Vertical position + */ + private String expandWall(int x, int y) { + DisplayableElementModel elementLeft = this.levelModel.getElementLeft(x, y); + DisplayableElementModel elementRight = this.levelModel.getElementRight(x, y); - /** - * Expand the wall at left & right - * - * @param x Horizontal position - * @param y Vertical position - */ - private String expandWall(int x, int y) { - DisplayableElementModel elementLeft = this.levelModel.getGroundLevelModel()[x - 1][y]; - DisplayableElementModel elementRight = this.levelModel.getGroundLevelModel()[x + 1][y]; - String spriteNameLeft = elementLeft.getSpriteName(); - String spriteNameRight = elementRight.getSpriteName(); + String spriteNameLeft = elementLeft.getSpriteName(); + String spriteNameRight = elementRight.getSpriteName(); + + String way = ""; + if(spriteNameLeft == "black"){ + this.levelModel.expandThisWallToLeft(x,y); + way = "left"; + } + if(spriteNameRight == "black"){ + this.levelModel.expandThisWallToRight(x,y); + way = "right"; + } + return way; + } - String way = ""; - if (spriteNameLeft == "black") { - this.levelModel.expandThisWallToLeft(x, y); - way = "left"; - } - if (spriteNameRight == "black") { - this.levelModel.expandThisWallToRight(x, y); - way = "right"; - } - return way; - } + /** + * Manages the fall of elements + * + * @param x Horizontal position + * @param y Vertical position + */ + private void manageFallingObjectBehavior(int x, int y) { - /** - * Manages the fall of elements - * - * @param x Horizontal position - * @param y Vertical position - */ - private void manageFall(int x, int y) { - // Get informed about Rockford surroundings - DisplayableElementModel elementBelow = this.levelModel.getGroundLevelModel()[x][y + 1]; - DisplayableElementModel elementLeft = this.levelModel.getGroundLevelModel()[x - 1][y]; - DisplayableElementModel elementRight = this.levelModel.getGroundLevelModel()[x + 1][y]; + // Task3 - Variable to get rig of calling one Method in if-clause several times + DisplayableElementModel element = this.levelModel.getElement(x, y); + DisplayableElementModel elementTwoBelow = this.levelModel.getElementTwoBelow(x, y); - String spriteNameBelow = elementBelow.getSpriteName(); - String spriteNameLeft = elementLeft.getSpriteName(); - String spriteNameRight = elementRight.getSpriteName(); + // Get informed about Rockford surroundings + DisplayableElementModel elementBelow = this.levelModel.getElementBelow(x, y); + DisplayableElementModel elementLeft = this.levelModel.getElementLeft(x, y); + DisplayableElementModel elementRight = this.levelModel.getElementRight(x, y); - // Then, process in case of the surrounding - if (spriteNameBelow == "black") { - this.levelModel.makeThisDisplayableElementFall(x, y); - } else if (spriteNameBelow == "boulder") { - // Boulders have to roll if they hit another boulder - if (this.levelModel.getGroundLevelModel()[x - 1][y + 1].getSpriteName() == "black") { - this.levelModel.makeThisBoulderSlideLeft(x, y); - } else if (this.levelModel.getGroundLevelModel()[x + 1][y + 1].getSpriteName() == "black") { - this.levelModel.makeThisBoulderSlideRight(x, y); - } - } else if (spriteNameBelow == "rockford" && this.levelModel.getGroundLevelModel()[x][y].isFalling()) { - this.levelModel.exploseGround(x, y + 1); + String spriteNameBelow = elementBelow.getSpriteName(); + String spriteNameLeft = elementLeft.getSpriteName(); + String spriteNameRight = elementRight.getSpriteName(); + + // Then, process in case of the surrounding + if (spriteNameBelow == "black") { + this.levelModel.makeThisDisplayableElementFall(x, y); + } else if (spriteNameBelow == "boulder") { + // Boulders have to roll if they hit another boulder + if (this.levelModel.getElementBelowLeft(x, y).getSpriteName() == "black") { + this.levelModel.makeThisBoulderSlideLeft(x, y); + } else if (this.levelModel.getElementBelowRight(x, y).getSpriteName() == "black") { + this.levelModel.makeThisBoulderSlideRight(x, y); + } + } else { + if (spriteNameBelow == "rockford" && element.isFalling()) { + this.levelModel.exploseGround(x, y + 1); AUDIO_LOAD_HELPER.playSound("die"); - try { - Thread.sleep(25); - } catch (InterruptedException e) { - e.printStackTrace(); - } + try { + Thread.sleep(25); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + this.levelModel.setGameRunning(false); + } else if (spriteNameBelow == "magicwall") { + if (element.getSpriteName() == "boulder" + && (elementTwoBelow.getSpriteName() == "dirt" || + elementTwoBelow.getSpriteName() == "black")) { + if(element.isConvertible()) { + this.levelModel.transformThisBoulderIntoADiamond(x, y); + } else { + this.levelModel.deleteThisBoulder(x, y); + } + } + } else if (elementBelow.isDestructible() && spriteNameBelow != "dirt" && element.isFalling()) { + this.levelModel.exploseThisBrickWall(x, y); + } else if (spriteNameLeft == "rockford" && this.levelModel.getRockford().isRunningRight() && elementRight.getSpriteName() == "black") { + this.levelModel.moveThisBoulderToRight(x, y); + } else if (spriteNameRight == "rockford" && this.levelModel.getRockford().isRunningLeft() && elementLeft.getSpriteName() == "black") { + this.levelModel.moveThisBoulderToLeft(x, y); + } else { + element.setFalling(false); + } + } + } + - this.levelModel.setGameRunning(false); - } else if (spriteNameBelow == "magicwall") { - if (this.levelModel.getGroundLevelModel()[x][y].getSpriteName() == "boulder" - && (this.levelModel.getGroundLevelModel()[x][y + 2].getSpriteName() == "dirt" || - this.levelModel.getGroundLevelModel()[x][y + 2].getSpriteName() == "black")) { - if (this.levelModel.getGroundLevelModel()[x][y].isConvertible()) { - this.levelModel.transformThisBoulderIntoADiamond(x, y); - } else { - this.levelModel.deleteThisBoulder(x, y); - } - } - } else if (elementBelow.isDestructible() && spriteNameBelow != "dirt" && this.levelModel.getGroundLevelModel()[x][y].isFalling()) { - this.levelModel.exploseThisBrickWall(x, y); - } else if (spriteNameLeft == "rockford" && this.levelModel.getRockford().isRunningRight() && this.levelModel.getGroundLevelModel()[x + 1][y].getSpriteName() == "black") { - this.levelModel.moveThisBoulderToRight(x, y); - } else if (spriteNameRight == "rockford" && this.levelModel.getRockford().isRunningLeft() && this.levelModel.getGroundLevelModel()[x - 1][y].getSpriteName() == "black") { - this.levelModel.moveThisBoulderToLeft(x, y); - } else { - this.levelModel.getGroundLevelModel()[x][y].setFalling(false); - } - } } diff --git a/src/fr/enssat/BoulderDash/models/LevelModel.java b/src/fr/enssat/BoulderDash/models/LevelModel.java index 796a1798..db921e8b 100644 --- a/src/fr/enssat/BoulderDash/models/LevelModel.java +++ b/src/fr/enssat/BoulderDash/models/LevelModel.java @@ -13,7 +13,7 @@ import static fr.enssat.BoulderDash.helpers.AudioLoadHelper.AUDIO_LOAD_HELPER; /** * LevelModel - *

+ * * Levels are loaded from XML file. The view knows the model, the controller is * going to modify the model in function of the game panel. The model notifies * the view when there are changes on it. @@ -22,792 +22,824 @@ import static fr.enssat.BoulderDash.helpers.AudioLoadHelper.AUDIO_LOAD_HELPER; * @since 2015-06-19 */ public class LevelModel extends Observable implements Runnable { - private DisplayableElementModel[][] groundGrid; - private String levelName; - private int sizeWidth = 0; - private int sizeHeight = 0; - private int cursorXPosition = 0; - private int cursorYPosition = 0; - private boolean showCursor = false; - private CursorModel cursorModel; - private LevelLoadHelper levelLoadHelper; - private RockfordModel rockford; - private GameInformationModel gameInformationModel; - private int rockfordPositionX, rockfordPositionY; - private boolean gameRunning; - private boolean gamePaused; - // Are we in editor or game mode ? - private String mode; + private DisplayableElementModel[][] groundGrid; + private String levelName; + private int sizeWidth = 0; + private int sizeHeight = 0; + private int cursorXPosition = 0; + private int cursorYPosition = 0; + private boolean showCursor = false; + private CursorModel cursorModel; + private LevelLoadHelper levelLoadHelper; + private RockfordModel rockford; + private GameInformationModel gameInformationModel; + private int rockfordPositionX, rockfordPositionY; + private boolean gameRunning; + private boolean gamePaused; + // Are we in editor or game mode ? + private String mode; - /** - * Sprite animation thread - */ - private Thread spriteAnimator; + /** + * Sprite animation thread + */ + private Thread spriteAnimator; - /** - * Animation speed - */ - private final int DELAY = 25; + /** + * Animation speed + */ + private final int DELAY = 25; - /** - * Class constructor - * - * @param levelName Level name - * @param mode Instance mode - */ + /** + * Class constructor + * + * @param levelName Level name + * @param mode Instance mode + */ public LevelModel(String levelName, String mode) { - this.levelName = levelName; - this.gamePaused = false; - this.gameRunning = true; - this.mode = mode; + this.levelName = levelName; + this.gamePaused = false; + this.gameRunning = true; + this.mode = mode; - this.levelLoadHelper = new LevelLoadHelper(this.levelName); + this.levelLoadHelper = new LevelLoadHelper(this.levelName); - this.groundGrid = this.levelLoadHelper.getGroundGrid(); - this.sizeWidth = this.levelLoadHelper.getWidthSizeValue(); - this.sizeHeight = this.levelLoadHelper.getHeightSizeValue(); + this.groundGrid = this.levelLoadHelper.getGroundGrid(); + this.sizeWidth = this.levelLoadHelper.getWidthSizeValue(); + this.sizeHeight = this.levelLoadHelper.getHeightSizeValue(); - this.cursorModel = new CursorModel(); - this.gameInformationModel = new GameInformationModel(this.levelLoadHelper.getDiamondsToCatch()); + this.cursorModel = new CursorModel(); + this.gameInformationModel = new GameInformationModel(this.levelLoadHelper.getDiamondsToCatch()); - this.createLimits(); + this.createLimits(); - if (this.mode.equals("game")) { - this.initRockford(); - this.initThreadAnimator(); - } - } + if(this.mode.equals("game")) { + this.initRockford(); + this.initThreadAnimator(); + } + } - /** - * Class constructor - * - * @param levelName Level name - */ + /** + * Class constructor + * + * @param levelName Level name + */ public LevelModel(String levelName) { this(levelName, "game"); - } + } - /** - * Class constructor (editor mode) - */ + /** + * Class constructor (editor mode) + */ public LevelModel() { - this.gameRunning = false; - this.mode = "editor"; + this.gameRunning = false; + this.mode = "editor"; - this.sizeWidth = 25 + 2; - this.sizeHeight = 25 + 2; + this.sizeWidth = 25 + 2; + this.sizeHeight = 25 + 2; - // Generate dirt - this.groundGrid = new DisplayableElementModel[this.sizeWidth][this.sizeHeight]; + // Generate dirt + this.groundGrid = new DisplayableElementModel[this.sizeWidth][this.sizeHeight]; - for (int x = 0; x < this.sizeWidth; x++) { - for (int y = 0; y < this.sizeHeight; y++) { - this.groundGrid[x][y] = new DirtModel(); - } - } + for (int x = 0; x < this.sizeWidth; x++) { + for (int y = 0; y < this.sizeHeight; y++) { + this.groundGrid[x][y] = new DirtModel(); + } + } - this.createLimits(); - } + this.createLimits(); + } - /** - * Initializes the animator thread - */ - private void initThreadAnimator() { - this.spriteAnimator = new Thread(this); - this.spriteAnimator.start(); - } + /** + * Initializes the animator thread + */ + private void initThreadAnimator() { + this.spriteAnimator = new Thread(this); + this.spriteAnimator.start(); + } - /** - * Initializes the Rockford position attributes - */ - private void initRockford() { - this.rockfordPositionX = this.levelLoadHelper.getRockfordPositionX(); - this.rockfordPositionY = this.levelLoadHelper.getRockfordPositionY(); - this.rockford = this.levelLoadHelper.getRockfordInstance(); - } + /** + * Initializes the Rockford position attributes + */ + private void initRockford() { + this.rockfordPositionX = this.levelLoadHelper.getRockfordPositionX(); + this.rockfordPositionY = this.levelLoadHelper.getRockfordPositionY(); + this.rockford = this.levelLoadHelper.getRockfordInstance(); + } - /** - * Creates the limits Puts steel walls all around the game panel - */ - private void createLimits() { - int maxWidth = this.sizeWidth - 1; - int maxHeight = this.sizeHeight - 1; + /** + * Creates the limits Puts steel walls all around the game panel + */ + private void createLimits() { + int maxWidth = this.sizeWidth - 1; + int maxHeight = this.sizeHeight - 1; - for (int x = 0; x < this.sizeWidth; x++) { - this.groundGrid[x][0] = new SteelWallModel(); - this.groundGrid[x][maxHeight] = new SteelWallModel(); - } - for (int y = 0; y < this.sizeHeight; y++) { - this.groundGrid[0][y] = new SteelWallModel(); - this.groundGrid[maxWidth][y] = new SteelWallModel(); - } - } + for (int x = 0; x < this.sizeWidth; x++) { + this.groundGrid[x][0] = new SteelWallModel(); + this.groundGrid[x][maxHeight] = new SteelWallModel(); + } + for (int y = 0; y < this.sizeHeight; y++) { + this.groundGrid[0][y] = new SteelWallModel(); + this.groundGrid[maxWidth][y] = new SteelWallModel(); + } + } - public void resetLevelModel() { - this.groundGrid = this.levelLoadHelper.getGroundGrid(); - this.gameRunning = true; - this.gameInformationModel.resetInformations(); - } + public void resetLevelModel() { + this.groundGrid = this.levelLoadHelper.getGroundGrid(); + this.gameRunning = true; + this.gameInformationModel.resetInformations(); + } - /** - * Updates the horizontal & vertical positions of Rockford in the model - * - * @param posX Horizontal position of Rockford - * @param posY Vertical position of Rockford - */ - public void updateRockfordPosition(int posX, int posY) { - this.rockfordPositionY = posY; - this.rockfordPositionX = posX; - } + /** + * Updates the horizontal & vertical positions of Rockford in the model + * + * @param posX Horizontal position of Rockford + * @param posY Vertical position of Rockford + */ + public void updateRockfordPosition(int posX, int posY) { + this.rockfordPositionY = posY; + this.rockfordPositionX = posX; + } - /** - * Checks whether position is out-of-bounds or not - * - * @param posX Horizontal position - * @param posY Vertical position - */ - private boolean isOutOfBounds(int posX, int posY) { - if (posX > 0 && posY > 0 && posX < this.getLevelLoadHelper().getHeightSizeValue() && posY < this.getLevelLoadHelper().getWidthSizeValue()) { - return false; - } + /** + * Checks whether position is out-of-bounds or not + * + * @param posX Horizontal position + * @param posY Vertical position + */ + private boolean isOutOfBounds(int posX, int posY) { + if (posX > 0 && posY > 0 && posX < this.getLevelLoadHelper().getHeightSizeValue() && posY < this.getLevelLoadHelper().getWidthSizeValue()) { + return false; + } - return true; - } + return true; + } - /** - * Plays collision sound - */ - private void playCollisionSound(int posX, int posY) { - String collisionSound = null; + /** + * Plays collision sound + */ + private void playCollisionSound(int posX, int posY) { + String collisionSound = null; - if (this.getRockford().isCollisionDone() == false) { - // Out of bounds? - if (this.isOutOfBounds(posX, posY) == true) { - collisionSound = "touch"; - } else { - DisplayableElementModel nextElement = this.groundGrid[posX][posY]; - collisionSound = nextElement.getCollideSound(); - } + if (this.getRockford().isCollisionDone() == false) { + // Out of bounds? + if (this.isOutOfBounds(posX, posY) == true) { + collisionSound = "touch"; + } else { + DisplayableElementModel nextElement = this.groundGrid[posX][posY]; + collisionSound = nextElement.getCollideSound(); + } - this.getRockford().setCollisionDone(true); - } + this.getRockford().setCollisionDone(true); + } - if (collisionSound != null) { + if (collisionSound != null) { AUDIO_LOAD_HELPER.playSound(collisionSound); - } - } + } + } - /** - * Gets the horizontal position of Rockford from the model - * - * @return Horizontal position of Rockford - */ - public int getRockfordPositionX() { - return this.rockfordPositionX; - } + /** + * Gets the horizontal position of Rockford from the model + * + * @return Horizontal position of Rockford + */ + public int getRockfordPositionX() { + return this.rockfordPositionX; + } - /** - * Sets the new Rockford position - * - * @param posX Next horizontal position on the grid - * @param posY Next vertical position on the grid - */ - public void setPositionOfRockford(int posX, int posY) { - int oldX = this.getRockfordPositionX(); - int oldY = this.getRockfordPositionY(); + /** + * Sets the new Rockford position + * + * @param posX Next horizontal position on the grid + * @param posY Next vertical position on the grid + */ + public void setPositionOfRockford(int posX, int posY) { + int oldX = this.getRockfordPositionX(); + int oldY = this.getRockfordPositionY(); - if (this.groundGrid[posX][posY].getSpriteName() == "diamond") { - this.gameInformationModel.incrementScore(); - this.gameInformationModel.decrementRemainingsDiamonds(); - if (this.gameInformationModel.getRemainingsDiamonds() == 0) { - this.spawnExit(); - } - } - if (this.groundGrid[posX][posY].getSpriteName() == "door") { - this.gameRunning = false; - } + if (this.groundGrid[posX][posY].getSpriteName() == "diamond") { + this.gameInformationModel.incrementScore(); + this.gameInformationModel.decrementRemainingsDiamonds(); + if (this.gameInformationModel.getRemainingsDiamonds() == 0) { + this.spawnExit(); + } + } + if (this.groundGrid[posX][posY].getSpriteName() == "door") { + this.gameRunning = false; + } - this.playCollisionSound(posX, posY); + this.playCollisionSound(posX, posY); - // Check that we are not out of bound... - if (this.isOutOfBounds(posX, posY) == false) { - // Create a new empty model in the old pos of Rockford - this.groundGrid[oldX][oldY] = new EmptyModel(); + // Check that we are not out of bound... + if (this.isOutOfBounds(posX, posY) == false) { + // Create a new empty model in the old pos of Rockford + this.groundGrid[oldX][oldY] = new EmptyModel(); - // Save the x / y pos of Rockford in the levelModel only - this.updateRockfordPosition(posX, posY); + // Save the x / y pos of Rockford in the levelModel only + this.updateRockfordPosition(posX, posY); - this.groundGrid[posX][posY] = this.getRockford(); - } - } + this.groundGrid[posX][posY] = this.getRockford(); + } + } - /** - * When there is no more diamonds to catch, spawn a exit door randomly in - * the game - */ - private void spawnExit() { - int x = (int) (Math.random() * (this.getSizeHeight() - 2)); - int y = (int) (Math.random() * (this.getSizeWidth() - 2)); - this.groundGrid[x + 1][y + 1] = new DoorModel(); - } + /** + * When there is no more diamonds to catch, spawn a exit door randomly in + * the game + */ + private void spawnExit() { + int x = (int) (Math.random() * (this.getSizeHeight() - 2)); + int y = (int) (Math.random() * (this.getSizeWidth() - 2)); + this.groundGrid[x + 1][y + 1] = new DoorModel(); + } - /** - * Trigger block change with provided value - * - * @param blockValue New value - */ - public void triggerBlockChange(String blockValue) { - // No block value? - if (blockValue == null || blockValue.isEmpty()) { - return; - } - - // Cancel if Rockford is already in model - if ((blockValue.equals("Rockford") || blockValue.equals("rockford")) && this.isRockfordInModel()) { - return; - } - - // Grab model value - ModelConvertHelper modelConverter = new ModelConvertHelper(); - DisplayableElementModel targetModel; - int xPos, yPos; - - xPos = this.getCursorXPosition(); - yPos = this.getCursorYPosition(); - - try { - targetModel = modelConverter.toModel(blockValue, false); - - // Apply new model in place of cursor - this.groundGrid[xPos + 1][yPos + 1] = targetModel; - - // Disable cursor (important) - //this.setShowCursor(false); - } catch (UnknownModelException e) { - e.printStackTrace(); - } - } - - /** - * Gets the vertical position of Rockford from the model - * - * @return Vertical position of Rockford - */ - public int getRockfordPositionY() { - return this.rockfordPositionY; - } - - /** - * Gets the Rockford object instance - * - * @return Rockford object - */ - public RockfordModel getRockford() { - return this.rockford; - } - - /** - * Gets the displayable element at given positions - * - * @param x Block horizontal position - * @param y Block vertical position - * @return Displayable element at given positions - */ - public DisplayableElementModel getDisplayableElement(int x, int y) { - return this.groundGrid[x][y]; - } - - /** - * Gets the image at given positions - * - * @param x Block horizontal position - * @param y Block vertical position - * @return Image at given positions - */ - public BufferedImage getImage(int x, int y) { - DisplayableElementModel elementModel = this.getDisplayableElement(x, y); - - if (elementModel == null) { - return new DirtModel().getSprite(); - } - - return elementModel.getSprite(); - } - - /** - * Gets the cursor image image - * - * @return Cursor image - */ - public BufferedImage getCursorImage() { - - if (this.cursorModel == null) { - this.cursorModel = new CursorModel(); - } - - return this.cursorModel.getSprite(); - } - - /** - * Return whether rockford is in model or not - * Notice: not optimized, be careful - * - * @return Whether rockford is in model or not - */ - public boolean isRockfordInModel() { - boolean isInModel = false; - - // Iterate and catch it! - for (int x = 0; x < this.getSizeWidth() && !isInModel; x++) { - for (int y = 0; y < this.getSizeHeight() && !isInModel; y++) { - if (this.groundGrid[x][y] != null && this.groundGrid[x][y].getSpriteName() == "rockford") { - isInModel = true; + /** + * Trigger block change with provided value + * + * @param blockValue New value + */ + public void triggerBlockChange(String blockValue) { + // No block value? + if(blockValue == null || blockValue.isEmpty()) { + return; } - } - } - return isInModel; - } - - /** - * Returns number of diamonds - * - * @return Number of diamonds - */ - public int countDiamonds() { - int numberOfDiamonds = 0; - - // Iterate and catch it! - for (int x = 0; x < this.getSizeWidth(); x++) { - for (int y = 0; y < this.getSizeHeight(); y++) { - if (this.groundGrid[x][y] != null && this.groundGrid[x][y].getSpriteName() == "diamond") { - numberOfDiamonds += 1; + // Cancel if Rockford is already in model + if((blockValue.equals("Rockford") || blockValue.equals("rockford")) && this.isRockfordInModel()) { + return; } - } + + // Grab model value + ModelConvertHelper modelConverter = new ModelConvertHelper(); + DisplayableElementModel targetModel; + int xPos, yPos; + + xPos = this.getCursorXPosition(); + yPos = this.getCursorYPosition(); + + try { + targetModel = modelConverter.toModel(blockValue, false); + + // Apply new model in place of cursor + this.groundGrid[xPos + 1][yPos + 1] = targetModel; + + // Disable cursor (important) + //this.setShowCursor(false); + } catch (UnknownModelException e) { + e.printStackTrace(); + } + } + + /** + * Gets the vertical position of Rockford from the model + * + * @return Vertical position of Rockford + */ + public int getRockfordPositionY() { + return this.rockfordPositionY; + } + + /** + * Gets the Rockford object instance + * + * @return Rockford object + */ + public RockfordModel getRockford() { + return this.rockford; + } + + /** + * Gets the displayable element at given positions + * + * @param x Block horizontal position + * @param y Block vertical position + * @return Displayable element at given positions + */ + public DisplayableElementModel getDisplayableElement(int x, int y) { + return this.groundGrid[x][y]; + } + + /** + * Gets the image at given positions + * + * @param x Block horizontal position + * @param y Block vertical position + * @return Image at given positions + */ + public BufferedImage getImage(int x, int y) { + DisplayableElementModel elementModel = this.getDisplayableElement(x, y); + + if(elementModel == null) { + return new DirtModel().getSprite(); + } + + return elementModel.getSprite(); + } + + /** + * Gets the cursor image image + * + * @return Cursor image + */ + public BufferedImage getCursorImage() { + + if (this.cursorModel == null) { + this.cursorModel = new CursorModel(); + } + + return this.cursorModel.getSprite(); + } + + /** + * Return whether rockford is in model or not + * Notice: not optimized, be careful + * + * @return Whether rockford is in model or not + */ + public boolean isRockfordInModel() { + boolean isInModel = false; + + // Iterate and catch it! + for (int x = 0; x < this.getSizeWidth() && !isInModel; x++) { + for (int y = 0; y < this.getSizeHeight() && !isInModel; y++) { + if(this.groundGrid[x][y] != null && this.groundGrid[x][y].getSpriteName() == "rockford") { + isInModel = true; + } + } + } + + return isInModel; } - return numberOfDiamonds; - } + /** + * Returns number of diamonds + * + * @return Number of diamonds + */ + public int countDiamonds() { + int numberOfDiamonds = 0; - /** - * Returns whether constraints on model are respected or not - */ - public void checkConstraints() throws LevelConstraintNotRespectedException { - // Diamonds number? - if (this.countDiamonds() < 3) { - throw new LevelConstraintNotRespectedException("Add at least 3 diamonds!"); - } - - // Rockford in model? - if (!this.isRockfordInModel()) { - throw new LevelConstraintNotRespectedException("Add Rockford on the map!"); - } - } - - /** - * Gets the level horizontal size - * - * @return Horizontal size - */ - public int getSizeWidth() { - return this.sizeWidth; - } - - /** - * Sets the level horizontal size - * - * @param sizeWidth Horizontal size - */ - public void setSizeWidth(int sizeWidth) { - this.sizeWidth = sizeWidth; - } - - /** - * Gets the level vertical size - * - * @return Vertical size - */ - public int getSizeHeight() { - return this.sizeHeight; - } - - /** - * Sets the level vertical size - * - * @return sizeHeight Vertical size - */ - public void setSizeHeight(int sizeHeight) { - this.sizeHeight = sizeHeight; - } - - /** - * Gets the ground level model - * - * @return Ground level model - */ - public DisplayableElementModel[][] getGroundLevelModel() { - return groundGrid; - } - - /** - * Notify observers about a model change - */ - private void localNotifyObservers() { - this.notifyObservers(); - this.setChanged(); - } - - /** - * Update the current sprite Notifies the observers - * - * @param x Sprite block horizontal position - * @param y Sprite block vertical position - */ - public void updateSprites(int x, int y) { - if (groundGrid[x][y] == null) { - groundGrid[x][y] = new DirtModel(); - } - - groundGrid[x][y].update(System.currentTimeMillis()); - this.localNotifyObservers(); - } - - /** - * Update all the sprites So that they can be animated - */ - public void run() { - while (gameRunning) { - if (!gamePaused) { + // Iterate and catch it! for (int x = 0; x < this.getSizeWidth(); x++) { - for (int y = 0; y < this.getSizeHeight(); y++) { - this.updateSprites(x, y); - } + for (int y = 0; y < this.getSizeHeight(); y++) { + if(this.groundGrid[x][y] != null && this.groundGrid[x][y].getSpriteName() == "diamond") { + numberOfDiamonds += 1; + } + } } - } - try { - Thread.sleep(DELAY); - } catch (InterruptedException e) { - System.out.println("Interrupted: " + e.getMessage()); - } - } - } - - /** - * Increments the user score - */ - public void incrementScore() { - this.gameInformationModel.incrementScore(); - } - - /** - * Gets the associated level load helper - * - * @return Level load helper - */ - public LevelLoadHelper getLevelLoadHelper() { - return this.levelLoadHelper; - } - - /** - * Gets the cursor position X value - * - * @return Cursor position X value - */ - public int getCursorXPosition() { - return this.cursorXPosition; - } - - /** - * Gets the cursor position Y value - * - * @return Cursor position Y value - */ - public int getCursorYPosition() { - return this.cursorYPosition; - } - - /** - * Increaments the cursor position X value - * - * @return Cursor position new X value - */ - public int incrementCursorXPosition() { - if (this.cursorXPosition < (this.getSizeWidth() - 1 - 2)) { - this.cursorXPosition = this.cursorXPosition + 1; + return numberOfDiamonds; } - this.localNotifyObservers(); - return this.getCursorXPosition(); - } + /** + * Returns whether constraints on model are respected or not + */ + public void checkConstraints() throws LevelConstraintNotRespectedException { + // Diamonds number? + if(this.countDiamonds() < 3) { + throw new LevelConstraintNotRespectedException("Add at least 3 diamonds!"); + } - /** - * Decrements the cursor position X value - * - * @return Cursor position new X value - */ - public int decrementCursorXPosition() { - if (this.cursorXPosition > 0) { - this.cursorXPosition = this.cursorXPosition - 1; + // Rockford in model? + if(!this.isRockfordInModel()) { + throw new LevelConstraintNotRespectedException("Add Rockford on the map!"); + } } - this.localNotifyObservers(); - return this.getCursorXPosition(); - } + /** + * Gets the level horizontal size + * + * @return Horizontal size + */ + public int getSizeWidth() { + return this.sizeWidth; + } - /** - * Increaments the cursor position Y value - * - * @return Cursor position new Y value - */ - public int incrementCursorYPosition() { - if (this.cursorYPosition < (this.getSizeHeight() - 1 - 2)) { - this.cursorYPosition = this.cursorYPosition + 1; - } + /** + * Sets the level horizontal size + * + * @param sizeWidth Horizontal size + */ + public void setSizeWidth(int sizeWidth) { + this.sizeWidth = sizeWidth; + } - this.localNotifyObservers(); - return this.getCursorYPosition(); - } + /** + * Gets the level vertical size + * + * @return Vertical size + */ + public int getSizeHeight() { + return this.sizeHeight; + } - /** - * Decrements the cursor position Y value - * - * @return Cursor position new Y value - */ - public int decrementCursorYPosition() { - if (this.cursorYPosition > 0) { - this.cursorYPosition = this.cursorYPosition - 1; - } + /** + * Sets the level vertical size + * + * @return sizeHeight Vertical size + */ + public void setSizeHeight(int sizeHeight) { + this.sizeHeight = sizeHeight; + } - this.localNotifyObservers(); - return this.getCursorYPosition(); - } + /** + * Gets the ground level model + * + * @return Ground level model + */ + public DisplayableElementModel[][] getGroundLevelModel() { + return groundGrid; + } - /** - * sets the game to a defined state - * - * @param gameRunning Whether game is running or not - */ - public void setGameRunning(boolean gameRunning) { - this.gameRunning = gameRunning; - // Timer to refresh the view properly... - try { - Thread.sleep(200); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - this.localNotifyObservers(); - } + /** + * Task 3c - move methods to LevelModel + * + * @return position according to specific + */ + public DisplayableElementModel getElement(int x, int y) { + return getGroundLevelModel()[x][y]; + } - /** - * tells if the game is running - * - * @return whether the game is running or not - */ - public boolean isGameRunning() { - return gameRunning; - } + public DisplayableElementModel getElementTwoBelow(int x, int y) { + return getElement(x, y + 2); + } - /** - * Gets whether cursor is to be shown or not - * - * @return whether cursor needs to be shown or not - */ - public boolean getShowCursor() { - return this.showCursor; - } + public DisplayableElementModel getElementBelowRight(int x, int y) { + return getElement(x + 1, y + 1); + } - /** - * Sets whether cursor is to be shown or not - * - * @param showCursor whether cursor needs to be shown or not - */ - public void setShowCursor(boolean showCursor) { - this.showCursor = showCursor; - } + public DisplayableElementModel getElementBelowLeft(int x, int y) { + return getElement(x - 1, y + 1); + } - /** - * When a boulder is falling on Rockford there is an explosion around him - * - * @param x Object horizontal position - * @param y Object vertical position - */ - public void exploseGround(int x, int y) { - this.groundGrid[x][y] = new EmptyModel(); - this.groundGrid[x + 1][y] = new EmptyModel(); - this.groundGrid[x - 1][y] = new EmptyModel(); - this.groundGrid[x][y + 1] = new EmptyModel(); - this.groundGrid[x + 1][y + 1] = new EmptyModel(); - this.groundGrid[x - 1][y + 1] = new EmptyModel(); - this.groundGrid[x][y - 1] = new EmptyModel(); - this.groundGrid[x + 1][y - 1] = new EmptyModel(); - this.groundGrid[x - 1][y - 1] = new EmptyModel(); - this.rockford.setHasExplosed(true); + public DisplayableElementModel getElementRight(int x, int y) { + return getElement(x + 1, y); + } - // Again a sleep to notify the observers properly - try { - Thread.sleep(50); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - this.localNotifyObservers(); - } + public DisplayableElementModel getElementLeft(int x, int y) { + return getElement(x - 1, y); + } - /** - * Makes the DisplayableElement[x][y] fall one box down - * - * @param x Object horizontal position - * @param y Object vertical position - */ - public void makeThisDisplayableElementFall(int x, int y) { - this.groundGrid[x][y].setFalling(true); - this.groundGrid[x][y + 1] = this.groundGrid[x][y]; - this.groundGrid[x][y] = new EmptyModel(); - } + public DisplayableElementModel getElementBelow(int x, int y) { + return getElement(x, y + 1); + } + /** + * Notify observers about a model change + */ + private void localNotifyObservers() { + this.notifyObservers(); + this.setChanged(); + } - /** - * Makes the BoulderModel[x][y] slide left - * - * @param x Object horizontal position - * @param y Object vertical position - */ - public void makeThisBoulderSlideLeft(int x, int y) { - this.groundGrid[x][y].setFalling(true); - this.groundGrid[x - 1][y + 1] = this.groundGrid[x][y]; - this.groundGrid[x][y] = new EmptyModel(); - } + /** + * Update the current sprite Notifies the observers + * + * @param x Sprite block horizontal position + * @param y Sprite block vertical position + */ + public void updateSprites(int x, int y) { + if(groundGrid[x][y] == null) { + groundGrid[x][y] = new DirtModel(); + } - /** - * Makes the BoulderModel[x][y] slide right - * - * @param x Object horizontal position - * @param y Object vertical position - */ - public void makeThisBoulderSlideRight(int x, int y) { - this.groundGrid[x][y].setFalling(true); - this.groundGrid[x + 1][y + 1] = this.groundGrid[x][y]; - this.groundGrid[x][y] = new EmptyModel(); - } + groundGrid[x][y].update(System.currentTimeMillis()); + this.localNotifyObservers(); + } - /** - * Makes the BoulderModel[x][y] transform into a diamond - * - * @param x Object horizontal position - * @param y Object vertical position - */ - public void transformThisBoulderIntoADiamond(int x, int y) { - this.groundGrid[x][y + 2] = new DiamondModel(); - this.groundGrid[x][y] = new EmptyModel(); - } + /** + * Update all the sprites So that they can be animated + */ + public void run() { + while (gameRunning) { + if (!gamePaused) { + for (int x = 0; x < this.getSizeWidth(); x++) { + for (int y = 0; y < this.getSizeHeight(); y++) { + this.updateSprites(x, y); + } + } + } - /** - * Makes the BoulderModel[x][y] moving to right - * - * @param x Object horizontal position - * @param y Object vertical position - */ - public void moveThisBoulderToRight(int x, int y) { - this.groundGrid[x + 1][y] = this.groundGrid[x][y]; - this.groundGrid[x][y] = new EmptyModel(); - } + try { + Thread.sleep(DELAY); + } catch (InterruptedException e) { + System.out.println("Interrupted: " + e.getMessage()); + } + } + } - /** - * Makes the BoulderModel[x][y] moving to left - * - * @param x Object horizontal position - * @param y Object vertical position - */ - public void moveThisBoulderToLeft(int x, int y) { - this.groundGrid[x - 1][y] = this.groundGrid[x][y]; - this.groundGrid[x][y] = new EmptyModel(); - } + /** + * Increments the user score + */ + public void incrementScore() { + this.gameInformationModel.incrementScore(); + } - /** - * Deletes the BoulderModel[x][y] - * - * @param x Object horizontal position - * @param y Object vertical position - */ - public void deleteThisBoulder(int x, int y) { - this.groundGrid[x][y] = new EmptyModel(); - } + /** + * Gets the associated level load helper + * + * @return Level load helper + */ + public LevelLoadHelper getLevelLoadHelper() { + return this.levelLoadHelper; + } - /** - * Gets gameInformationModel - * - * @return gameInfos like score, remainings Diamonds etc - */ - public GameInformationModel getGameInformationModel() { - return this.gameInformationModel; - } + /** + * Gets the cursor position X value + * + * @return Cursor position X value + */ + public int getCursorXPosition() { + return this.cursorXPosition; + } - /** - * Explose the brick wall - * - * @param x - * @param y - */ - public void exploseThisBrickWall(int x, int y) { - this.groundGrid[x][y] = new EmptyModel(); - this.groundGrid[x][y + 1] = new EmptyModel(); - } + /** + * Gets the cursor position Y value + * + * @return Cursor position Y value + */ + public int getCursorYPosition() { + return this.cursorYPosition; + } - /** - * Expand the ExpandingWallModel to left - * - * @param x - * @param y - */ - public void expandThisWallToLeft(int x, int y) { - this.groundGrid[x - 1][y] = new ExpandingWallModel(); - } + /** + * Increaments the cursor position X value + * + * @return Cursor position new X value + */ + public int incrementCursorXPosition() { + if (this.cursorXPosition < (this.getSizeWidth() - 1 - 2)) { + this.cursorXPosition = this.cursorXPosition + 1; + } - /** - * Expand the ExpandingWallModel to right - * - * @param x - * @param y - */ - public void expandThisWallToRight(int x, int y) { - this.groundGrid[x + 1][y] = new ExpandingWallModel(); - } + this.localNotifyObservers(); + return this.getCursorXPosition(); + } - /** - * Set the gamePaused variable - * - * @param gamePaused - */ - public void setGamePaused(boolean gamePaused) { - this.gamePaused = gamePaused; - } + /** + * Decrements the cursor position X value + * + * @return Cursor position new X value + */ + public int decrementCursorXPosition() { + if (this.cursorXPosition > 0) { + this.cursorXPosition = this.cursorXPosition - 1; + } - /** - * Get the gamePaused variable - * - * @return gamePaused - */ - public boolean getGamePaused() { - return this.gamePaused; - } + this.localNotifyObservers(); + return this.getCursorXPosition(); + } - /** - * Get the mode where this levelModel is used - * - * @return mode - */ - public String getMode() { - return mode; - } + /** + * Increaments the cursor position Y value + * + * @return Cursor position new Y value + */ + public int incrementCursorYPosition() { + if (this.cursorYPosition < (this.getSizeHeight() - 1 - 2)) { + this.cursorYPosition = this.cursorYPosition + 1; + } - /** - * Set the mode where this levelModel is used - * - * @param mode - */ - public void setMode(String mode) { - this.mode = mode; - } + this.localNotifyObservers(); + return this.getCursorYPosition(); + } + + /** + * Decrements the cursor position Y value + * + * @return Cursor position new Y value + */ + public int decrementCursorYPosition() { + if (this.cursorYPosition > 0) { + this.cursorYPosition = this.cursorYPosition - 1; + } + + this.localNotifyObservers(); + return this.getCursorYPosition(); + } + + /** + * sets the game to a defined state + * + * @param gameRunning Whether game is running or not + */ + public void setGameRunning(boolean gameRunning) { + this.gameRunning = gameRunning; + // Timer to refresh the view properly... + try { + Thread.sleep(200); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + this.localNotifyObservers(); + } + + /** + * tells if the game is running + * + * @return whether the game is running or not + */ + public boolean isGameRunning() { + return gameRunning; + } + + /** + * Gets whether cursor is to be shown or not + * + * @return whether cursor needs to be shown or not + */ + public boolean getShowCursor() { + return this.showCursor; + } + + /** + * Sets whether cursor is to be shown or not + * + * @param showCursor whether cursor needs to be shown or not + */ + public void setShowCursor(boolean showCursor) { + this.showCursor = showCursor; + } + + /** + * When a boulder is falling on Rockford there is an explosion around him + * + * @param x Object horizontal position + * @param y Object vertical position + */ + public void exploseGround(int x, int y) { + this.groundGrid[x][y] = new EmptyModel(); + this.groundGrid[x + 1][y] = new EmptyModel(); + this.groundGrid[x - 1][y] = new EmptyModel(); + this.groundGrid[x][y + 1] = new EmptyModel(); + this.groundGrid[x + 1][y + 1] = new EmptyModel(); + this.groundGrid[x - 1][y + 1] = new EmptyModel(); + this.groundGrid[x][y - 1] = new EmptyModel(); + this.groundGrid[x + 1][y - 1] = new EmptyModel(); + this.groundGrid[x - 1][y - 1] = new EmptyModel(); + this.rockford.setHasExplosed(true); + + // Again a sleep to notify the observers properly + try { + Thread.sleep(50); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + this.localNotifyObservers(); + } + + /** + * Makes the DisplayableElement[x][y] fall one box down + * + * @param x Object horizontal position + * @param y Object vertical position + */ + public void makeThisDisplayableElementFall(int x, int y) { + this.groundGrid[x][y].setFalling(true); + this.groundGrid[x][y + 1] = this.groundGrid[x][y]; + this.groundGrid[x][y] = new EmptyModel(); + } + + /** + * Makes the BoulderModel[x][y] slide left + * + * @param x Object horizontal position + * @param y Object vertical position + */ + public void makeThisBoulderSlideLeft(int x, int y) { + this.groundGrid[x][y].setFalling(true); + this.groundGrid[x - 1][y + 1] = this.groundGrid[x][y]; + this.groundGrid[x][y] = new EmptyModel(); + } + + /** + * Makes the BoulderModel[x][y] slide right + * + * @param x Object horizontal position + * @param y Object vertical position + */ + public void makeThisBoulderSlideRight(int x, int y) { + this.groundGrid[x][y].setFalling(true); + this.groundGrid[x + 1][y + 1] = this.groundGrid[x][y]; + this.groundGrid[x][y] = new EmptyModel(); + } + + /** + * Makes the BoulderModel[x][y] transform into a diamond + * + * @param x Object horizontal position + * @param y Object vertical position + */ + public void transformThisBoulderIntoADiamond(int x, int y) { + this.groundGrid[x][y + 2] = new DiamondModel(); + this.groundGrid[x][y] = new EmptyModel(); + } + + /** + * Makes the BoulderModel[x][y] moving to right + * + * @param x Object horizontal position + * @param y Object vertical position + */ + public void moveThisBoulderToRight(int x, int y) { + this.groundGrid[x + 1][y] = this.groundGrid[x][y]; + this.groundGrid[x][y] = new EmptyModel(); + } + + /** + * Makes the BoulderModel[x][y] moving to left + * + * @param x Object horizontal position + * @param y Object vertical position + */ + public void moveThisBoulderToLeft(int x, int y) { + this.groundGrid[x - 1][y] = this.groundGrid[x][y]; + this.groundGrid[x][y] = new EmptyModel(); + } + + /** + * Deletes the BoulderModel[x][y] + * + * @param x Object horizontal position + * @param y Object vertical position + */ + public void deleteThisBoulder(int x, int y) { + this.groundGrid[x][y] = new EmptyModel(); + } + + /** + * Gets gameInformationModel + * + * @return gameInfos like score, remainings Diamonds etc + */ + public GameInformationModel getGameInformationModel() { + return this.gameInformationModel; + } + + /** + * Explose the brick wall + * + * @param x + * @param y + */ + public void exploseThisBrickWall(int x, int y) { + this.groundGrid[x][y] = new EmptyModel(); + this.groundGrid[x][y + 1] = new EmptyModel(); + } + + /** + * Expand the ExpandingWallModel to left + * + * @param x + * @param y + */ + public void expandThisWallToLeft(int x, int y) { + this.groundGrid[x - 1][y] = new ExpandingWallModel(); + } + + /** + * Expand the ExpandingWallModel to right + * + * @param x + * @param y + */ + public void expandThisWallToRight(int x, int y) { + this.groundGrid[x + 1][y] = new ExpandingWallModel(); + } + + /** + * Set the gamePaused variable + * + * @param gamePaused + */ + public void setGamePaused(boolean gamePaused) { + this.gamePaused = gamePaused; + } + + /** + * Get the gamePaused variable + * + * @return gamePaused + */ + public boolean getGamePaused() { + return this.gamePaused; + } + + /** + * Get the mode where this levelModel is used + * + * @return mode + */ + public String getMode() { + return mode; + } + + /** + * Set the mode where this levelModel is used + * + * @param mode + */ + public void setMode(String mode) { + this.mode = mode; + } } \ No newline at end of file