package fr.enssat.BoulderDash.controllers; import fr.enssat.BoulderDash.models.LevelModel; import fr.enssat.BoulderDash.models.DirtModel; import fr.enssat.BoulderDash.models.DisplayableElementModel; import static fr.enssat.BoulderDash.helpers.AudioLoadHelper.AUDIO_LOAD_HELPER; /** * ElementPositionUpdateHelper *

* Updates position of all elements displayed on the map, according to their * next potential position. Each object has a weight, which is used to compare * their power to destroy in the food chain. Sorry for that Darwinism. * * @author Colin Leverger * @since 2015-06-19 */ public class BoulderAndDiamondController extends AbstractLevelController implements Runnable { private Thread elementMovingThread; /** * Class constructor * * @param levelModel Level model */ public BoulderAndDiamondController(LevelModel levelModel) { super(levelModel); // 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(); } } } /** * 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(); } 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; } } } } } /** * 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); 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; } /** * Manages the fall of elements * * @param x Horizontal position * @param y Vertical position */ private void manageFallingObjectBehavior(int x, int y) { // Get surrounding elements DisplayableElementModel element = this.levelModel.getElement(x, y); DisplayableElementModel elementTwoBelow = this.levelModel.getElementTwoBelow(x, y); DisplayableElementModel elementBelow = this.levelModel.getElementBelow(x, y); DisplayableElementModel elementLeft = this.levelModel.getElementLeft(x, y); DisplayableElementModel elementRight = this.levelModel.getElementRight(x, y); String spriteNameBelow = elementBelow.getSpriteName(); String spriteNameLeft = elementLeft.getSpriteName(); String spriteNameRight = elementRight.getSpriteName(); // Handle different cases based on the element's surroundings handleFalling(x, y, spriteNameBelow, element); handleBoulder(x, y, spriteNameBelow, element, elementTwoBelow); handleRockfordCollision(x, y, spriteNameBelow, element); handleMagicWall(x, y, spriteNameBelow, element, elementTwoBelow); handleDestructibleWalls(x, y, elementBelow, element); handleRockfordMovement(x, y,element, spriteNameLeft, spriteNameRight, elementLeft, elementRight); } private void handleFalling(int x, int y, String spriteNameBelow, DisplayableElementModel element) { if (spriteNameBelow.equals("black")) { this.levelModel.makeThisDisplayableElementFall(x, y); } } private void handleBoulder(int x, int y, String spriteNameBelow, DisplayableElementModel element, DisplayableElementModel elementTwoBelow) { if (spriteNameBelow.equals("boulder")) { if (this.levelModel.getElementBelowLeft(x, y).getSpriteName().equals("black")) { this.levelModel.makeThisBoulderSlideLeft(x, y); } else if (this.levelModel.getElementBelowRight(x, y).getSpriteName().equals("black")) { this.levelModel.makeThisBoulderSlideRight(x, y); } } } private void handleRockfordCollision(int x, int y, String spriteNameBelow, DisplayableElementModel element) { if (spriteNameBelow.equals("rockford") && element.isFalling()) { this.levelModel.exploseGround(x, y + 1); AUDIO_LOAD_HELPER.playSound("die"); try { Thread.sleep(25); } catch (InterruptedException e) { e.printStackTrace(); } this.levelModel.setGameRunning(false); } } private void handleMagicWall(int x, int y, String spriteNameBelow, DisplayableElementModel element, DisplayableElementModel elementTwoBelow) { if (spriteNameBelow.equals("magicwall")) { if (element.getSpriteName().equals("boulder") && (elementTwoBelow.getSpriteName().equals("dirt") || elementTwoBelow.getSpriteName().equals("black"))) { if (element.isConvertible()) { this.levelModel.transformThisBoulderIntoADiamond(x, y); } else { this.levelModel.deleteThisBoulder(x, y); } } } } private void handleDestructibleWalls(int x, int y, DisplayableElementModel elementBelow, DisplayableElementModel element) { if (elementBelow.isDestructible() && !elementBelow.getSpriteName().equals("dirt") && element.isFalling()) { this.levelModel.exploseThisBrickWall(x, y); } } private void handleRockfordMovement(int x, int y,DisplayableElementModel element ,String spriteNameLeft, String spriteNameRight, DisplayableElementModel elementLeft, DisplayableElementModel elementRight) { if (spriteNameLeft.equals("rockford") && this.levelModel.getRockford().isRunningRight() && elementRight.getSpriteName().equals("black")) { this.levelModel.moveThisBoulderToRight(x, y); } else if (spriteNameRight.equals("rockford") && this.levelModel.getRockford().isRunningLeft() && elementLeft.getSpriteName().equals("black")) { this.levelModel.moveThisBoulderToLeft(x, y); } else { element.setFalling(false); } } }