Compare commits

...

4 Commits

Author SHA1 Message Date
8c05ed2a67
Task 2 2025-01-23 15:48:54 +01:00
ce055e4377
Task 1 - minor 2025-01-23 14:28:27 +01:00
0nlineSam
2cd827bdab Task 1 - Improved Factory pattern 2025-01-23 13:43:50 +01:00
0nlineSam
12d4bb3c4d Task 1 2025-01-23 13:26:59 +01:00
10 changed files with 150 additions and 168 deletions

View File

@ -0,0 +1,6 @@
package fr.enssat.BoulderDash.bridges;
public interface SoundBridge {
void play();
void stop();
}

View File

@ -0,0 +1,5 @@
package fr.enssat.BoulderDash.bridges;
public abstract class SoundBridgeFactory {
public abstract SoundBridge createSoundBridgeFromFilePath(String filePath);
}

View File

@ -14,7 +14,7 @@ import javazoom.jl.player.FactoryRegistry;
* @author Valerian Saliou <valerian@valeriansaliou.name>
* @since 2015-06-19
*/
public class SoundJLayerBridge extends PlaybackListener implements Runnable {
public class SoundJLayerBridge extends PlaybackListener implements Runnable, SoundBridge {
private String filePath;
private AdvancedPlayer player;
private Thread playerThread;
@ -31,6 +31,7 @@ public class SoundJLayerBridge extends PlaybackListener implements Runnable {
/**
* Play the target sound
*/
@Override
public void play() {
try {
String urlAsString = "file:///"
@ -55,6 +56,7 @@ public class SoundJLayerBridge extends PlaybackListener implements Runnable {
/**
* Stops the target sound
*/
@Override
public void stop() {
try {
this.playerThread.stop();
@ -66,6 +68,7 @@ public class SoundJLayerBridge extends PlaybackListener implements Runnable {
/**
* Runs the player thread
*/
@Override
public void run() {
try {
this.player.play();

View File

@ -0,0 +1,10 @@
package fr.enssat.BoulderDash.bridges;
public class SoundJLayerBridgeFactory extends SoundBridgeFactory {
public SoundJLayerBridgeFactory() {}
@Override
public SoundBridge createSoundBridgeFromFilePath(String filePath) {
return new SoundJLayerBridge(filePath);
}
}

View File

@ -2,7 +2,7 @@ package fr.enssat.BoulderDash.controllers;
import fr.enssat.BoulderDash.models.LevelModel;
import fr.enssat.BoulderDash.helpers.AudioLoadHelper;
import fr.enssat.BoulderDash.controllers.NavigationBetweenViewController;
import fr.enssat.BoulderDash.models.LevelModelFactory;
import fr.enssat.BoulderDash.views.MenuView;
import fr.enssat.BoulderDash.views.GameView;
@ -86,7 +86,7 @@ public class GameController implements ActionListener {
this.gameView.dispose();
if(source.equals("restart")){
this.levelModel = new LevelModel(this.navigationBetweenViewController.getPickedLevelIdentifier(), audioLoadHelper);
this.levelModel = LevelModelFactory.createLevelModel(this.navigationBetweenViewController.getPickedLevelIdentifier(), audioLoadHelper);
this.gameView = new GameView(this, levelModel);
this.gameView.setVisible(true);
}

View File

@ -3,11 +3,11 @@ package fr.enssat.BoulderDash.controllers;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import fr.enssat.BoulderDash.bridges.SoundJLayerBridgeFactory;
import fr.enssat.BoulderDash.helpers.AudioLoadHelper;
import fr.enssat.BoulderDash.models.LevelModel;
import fr.enssat.BoulderDash.models.LevelModelFactory;
import fr.enssat.BoulderDash.views.MenuView;
import fr.enssat.BoulderDash.controllers.LevelEditorController;
import fr.enssat.BoulderDash.controllers.GameController;
/**
* Controller to navigate between the different views
@ -27,7 +27,7 @@ public class NavigationBetweenViewController implements ActionListener {
* Class constructor
*/
public NavigationBetweenViewController() {
this.audioLoadHelper = new AudioLoadHelper();
this.audioLoadHelper = new AudioLoadHelper(new SoundJLayerBridgeFactory());
// Play game music
this.getAudioLoadHelper().startMusic("game");
@ -50,7 +50,7 @@ public class NavigationBetweenViewController implements ActionListener {
case "editor":
// New blank model for editor
this.levelModelForEditor = new LevelModel(audioLoadHelper);
this.levelModelForEditor = LevelModelFactory.createLevelModel(audioLoadHelper);
this.levelEditorController = new LevelEditorController(this.levelModelForEditor, this);
this.levelEditorController.getLevelEditorView().setVisible(true);
@ -66,7 +66,7 @@ public class NavigationBetweenViewController implements ActionListener {
// Reinit the levelModelForGame...
pickedLevelIdentifier = this.menuView.getLevelIdentifier();
this.levelModelForGame = new LevelModel(pickedLevelIdentifier, audioLoadHelper);
this.levelModelForGame = LevelModelFactory.createLevelModel(pickedLevelIdentifier, audioLoadHelper);
this.gameController = new GameController(levelModelForGame, audioLoadHelper, this);
if (levelEditorController != null) {

View File

@ -1,6 +1,7 @@
package fr.enssat.BoulderDash.helpers;
import fr.enssat.BoulderDash.bridges.SoundJLayerBridge;
import fr.enssat.BoulderDash.bridges.SoundBridge;
import fr.enssat.BoulderDash.bridges.SoundBridgeFactory;
import java.io.File;
import java.io.FilenameFilter;
@ -17,13 +18,15 @@ import java.util.HashMap;
public class AudioLoadHelper {
private static String pathToAudioStore = "./res/audio";
private SoundJLayerBridge musicToPlay;
private HashMap<String, SoundJLayerBridge> preloadedSounds;
private final SoundBridgeFactory soundBridgeFactory;
private SoundBridge musicToPlay;
private HashMap<String, SoundBridge> preloadedSounds;
/**
* Class constructor
*/
public AudioLoadHelper() {
public AudioLoadHelper(SoundBridgeFactory soundBridgeFactory) {
this.soundBridgeFactory = soundBridgeFactory;
this.preloadSounds();
}
@ -47,9 +50,8 @@ public class AudioLoadHelper {
this.stopMusic();
}
this.musicToPlay = new SoundJLayerBridge(
this.getMusicPathInAudioStore(musicId)
);
String filePath = this.getMusicPathInAudioStore(musicId);
this.musicToPlay = soundBridgeFactory.createSoundBridgeFromFilePath(filePath);
this.musicToPlay.play();
}
@ -66,7 +68,7 @@ public class AudioLoadHelper {
private void preloadSounds() {
// Initialize
String curSoundIdPrep;
this.preloadedSounds = new HashMap<String, SoundJLayerBridge>();
this.preloadedSounds = new HashMap<>();
// List sound files
File soundsDir = new File(AudioLoadHelper.pathToAudioStore + "/sounds/");
@ -77,14 +79,13 @@ public class AudioLoadHelper {
}
});
// Cache them all!
// Cache them all!^
for (File curSoundId : soundFiles) {
curSoundIdPrep = curSoundId.getName();
curSoundIdPrep = curSoundIdPrep.substring(0, curSoundIdPrep.lastIndexOf('.'));
this.preloadedSounds.put(curSoundIdPrep, new SoundJLayerBridge(
curSoundId.getPath()
));
this.preloadedSounds.put(curSoundIdPrep,
soundBridgeFactory.createSoundBridgeFromFilePath(curSoundId.getPath()));
}
}
@ -94,7 +95,7 @@ public class AudioLoadHelper {
* @param soundId Sound identifier
* @return Preloaded sound instance
*/
private SoundJLayerBridge getPreloadedSound(String soundId) {
private SoundBridge getPreloadedSound(String soundId) {
return this.preloadedSounds.get(soundId);
}

View File

@ -2,19 +2,8 @@ package fr.enssat.BoulderDash.models;
import fr.enssat.BoulderDash.exceptions.LevelConstraintNotRespectedException;
import fr.enssat.BoulderDash.exceptions.UnknownModelException;
import fr.enssat.BoulderDash.helpers.LevelLoadHelper;
import fr.enssat.BoulderDash.helpers.AudioLoadHelper;
import fr.enssat.BoulderDash.helpers.ModelConvertHelper;
import fr.enssat.BoulderDash.models.DisplayableElementModel;
import fr.enssat.BoulderDash.models.RockfordModel;
import fr.enssat.BoulderDash.models.GameInformationModel;
import fr.enssat.BoulderDash.models.SteelWallModel;
import fr.enssat.BoulderDash.models.EmptyModel;
import fr.enssat.BoulderDash.models.DiamondModel;
import fr.enssat.BoulderDash.models.DoorModel;
import fr.enssat.BoulderDash.models.DirtModel;
import fr.enssat.BoulderDash.models.ExpandingWallModel;
import fr.enssat.BoulderDash.models.CursorModel;
import java.awt.image.BufferedImage;
import java.util.Observable;
@ -32,7 +21,6 @@ import java.util.Observable;
*/
public class LevelModel extends Observable implements Runnable {
private DisplayableElementModel[][] groundGrid;
private String levelName;
private AudioLoadHelper audioLoadHelper;
private int sizeWidth = 0;
private int sizeHeight = 0;
@ -40,7 +28,6 @@ public class LevelModel extends Observable implements Runnable {
private int cursorYPosition = 0;
private boolean showCursor = false;
private CursorModel cursorModel;
private LevelLoadHelper levelLoadHelper;
private RockfordModel rockford;
private GameInformationModel gameInformationModel;
private int rockfordPositionX, rockfordPositionY;
@ -49,120 +36,34 @@ public class LevelModel extends Observable implements Runnable {
// Are we in editor or game mode ?
private String mode;
/**
* Sprite animation thread
*/
private Thread spriteAnimator;
/**
* Animation speed
*/
private final int DELAY = 25;
/**
* Class constructor
*
* @param levelName Level name
* @param audioLoadHelper Audio load helper
* @param mode Instance mode
*/
public LevelModel(String levelName, AudioLoadHelper audioLoadHelper, String mode) {
this.levelName = levelName;
LevelModel(AudioLoadHelper audioLoadHelper,
String mode,
boolean gameRunning,
CursorModel cursorModel,
GameInformationModel gameInformationModel,
DisplayableElementModel[][] groundGrid,
int sizeWidth,
int sizeHeight,
int rockfordPositionX,
int rockfordPositionY,
RockfordModel rockford){
this.audioLoadHelper = audioLoadHelper;
this.gamePaused = false;
this.gameRunning = true;
this.gameRunning = gameRunning;
this.mode = mode;
this.levelLoadHelper = new LevelLoadHelper(this.levelName);
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.createLimits();
if(this.mode.equals("game")) {
this.initRockford();
this.initThreadAnimator();
}
}
/**
* Class constructor
*
* @param levelName Level name
* @param audioLoadHelper Audio load helper
*/
public LevelModel(String levelName, AudioLoadHelper audioLoadHelper) {
this(levelName, audioLoadHelper, "game");
}
/**
* Class constructor (editor mode)
*
* @param audioLoadHelper Audio load helper
*/
public LevelModel(AudioLoadHelper audioLoadHelper) {
this.audioLoadHelper = audioLoadHelper;
this.gameRunning = false;
this.mode = "editor";
this.sizeWidth = 25 + 2;
this.sizeHeight = 25 + 2;
// 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();
}
}
this.createLimits();
}
/**
* 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();
}
/**
* 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();
}
}
public void resetLevelModel() {
this.groundGrid = this.levelLoadHelper.getGroundGrid();
this.gameRunning = true;
this.gameInformationModel.resetInformations();
this.groundGrid = groundGrid;
this.sizeWidth = sizeWidth;
this.sizeHeight = sizeHeight;
this.cursorModel = cursorModel;
this.gameInformationModel = gameInformationModel;
this.rockfordPositionX = rockfordPositionX;
this.rockfordPositionY = rockfordPositionY;
this.rockford = rockford;
}
/**
@ -183,11 +84,7 @@ public class LevelModel extends Observable implements Runnable {
* @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 posX <= 0 || posY <= 0 || posX >= this.sizeHeight || posY >= this.sizeWidth;
}
/**
@ -509,22 +406,6 @@ public class LevelModel extends Observable implements Runnable {
}
}
/**
* 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
*
@ -825,5 +706,4 @@ public class LevelModel extends Observable implements Runnable {
public void setMode(String mode) {
this.mode = mode;
}
}

View File

@ -0,0 +1,79 @@
package fr.enssat.BoulderDash.models;
import fr.enssat.BoulderDash.helpers.AudioLoadHelper;
import fr.enssat.BoulderDash.helpers.LevelLoadHelper;
public class LevelModelFactory {
public static LevelModel createLevelModel(String levelName, AudioLoadHelper audioLoadHelper, String mode) {
LevelLoadHelper levelLoadHelper = new LevelLoadHelper(levelName);
CursorModel cursorModel = new CursorModel();
GameInformationModel gameInformationModel = new GameInformationModel(levelLoadHelper.getDiamondsToCatch());
int sizeWidth = levelLoadHelper.getWidthSizeValue();
int sizeHeight = levelLoadHelper.getHeightSizeValue();
DisplayableElementModel[][] groundGrid = levelLoadHelper.getGroundGrid();
createLimits(groundGrid, sizeWidth, sizeHeight);
int rockfordPositionX = 0;
int rockfordPositionY = 0;
RockfordModel rockford = null;
if(mode.equals("game")) {
// initRockford
rockfordPositionX = levelLoadHelper.getRockfordPositionX();
rockfordPositionY = levelLoadHelper.getRockfordPositionY();
rockford = levelLoadHelper.getRockfordInstance();
}
LevelModel levelModel = new LevelModel(audioLoadHelper, mode, true, cursorModel, gameInformationModel, groundGrid, sizeWidth, sizeHeight,
rockfordPositionX, rockfordPositionY, rockford);
if(mode.equals("game")) {
// initThreadAnimator
Thread spriteAnimator = new Thread(levelModel);
spriteAnimator.start();
}
return levelModel;
}
public static LevelModel createLevelModel(String levelName, AudioLoadHelper audioLoadHelper) {
return createLevelModel(levelName, audioLoadHelper, "game");
}
public static LevelModel createLevelModel(AudioLoadHelper audioLoadHelper) {
CursorModel cursorModel = new CursorModel();
int sizeWidth = 25 + 2;
int sizeHeight = 25 + 2;
DisplayableElementModel[][] groundGrid = new DisplayableElementModel[sizeWidth][sizeHeight];
for (int x = 0; x < sizeWidth; x++) {
for (int y = 0; y < sizeHeight; y++) {
groundGrid[x][y] = new DirtModel();
}
}
createLimits(groundGrid, sizeWidth, sizeHeight);
return new LevelModel(audioLoadHelper, "editor", false, cursorModel, null, groundGrid, sizeWidth, sizeHeight,
0, 0, null);
}
private static void createLimits(DisplayableElementModel[][] groundGrid,
int sizeWidth,
int sizeHeight) {
int maxWidth = sizeWidth - 1;
int maxHeight = sizeHeight - 1;
for (int x = 0; x < sizeWidth; x++) {
groundGrid[x][0] = new SteelWallModel();
groundGrid[x][maxHeight] = new SteelWallModel();
}
for (int y = 0; y < sizeHeight; y++) {
groundGrid[0][y] = new SteelWallModel();
groundGrid[maxWidth][y] = new SteelWallModel();
}
}
}

View File

@ -9,9 +9,7 @@ import fr.enssat.BoulderDash.helpers.LevelSelectorHelper;
import fr.enssat.BoulderDash.controllers.LevelEditorController;
import fr.enssat.BoulderDash.controllers.NavigationBetweenViewController;
import fr.enssat.BoulderDash.models.LevelModel;
import fr.enssat.BoulderDash.views.LevelEditorGroundView;
import fr.enssat.BoulderDash.views.AssetsLevelEditorComponent;
import fr.enssat.BoulderDash.views.MenuLevelSelector;
import fr.enssat.BoulderDash.models.LevelModelFactory;
/**
@ -169,10 +167,10 @@ public class LevelEditorView extends JFrame implements Observer {
if(selectedLevelValue != null && !selectedLevelValue.isEmpty()) {
// Load existing model
pickedLevelModel = new LevelModel(selectedLevelValue, this.nav.getAudioLoadHelper(), "editor");
pickedLevelModel = LevelModelFactory.createLevelModel(selectedLevelValue, this.nav.getAudioLoadHelper(), "editor");
} else {
// New blank model for editor
pickedLevelModel = new LevelModel(this.nav.getAudioLoadHelper());
pickedLevelModel = LevelModelFactory.createLevelModel(this.nav.getAudioLoadHelper());
}
pickedLevelModel.setShowCursor(true);