192 lines
6.6 KiB
Java
192 lines
6.6 KiB
Java
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
|
|
* <p>
|
|
* 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 <me@colinleverger.fr>
|
|
* @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);
|
|
}
|
|
}
|
|
|
|
|
|
}
|