package vooga.scroller.level_editor.controllerSuite; import games.scroller.marioGame.spritesDefinitions.players.Mario; import java.awt.Dimension; import java.io.File; import java.util.HashMap; import java.util.Map; import javax.swing.JOptionPane; import vooga.scroller.level_editor.ILevelEditor; import vooga.scroller.level_editor.Level; import vooga.scroller.level_editor.LevelEditing; import vooga.scroller.level_editor.library.IBackgroundLibrary; import vooga.scroller.level_editor.library.ISpriteLibrary; import vooga.scroller.level_editor.model.EditableGrid; import vooga.scroller.level_editor.model.LevelEditor; import vooga.scroller.level_editor.model.LevelParser; import vooga.scroller.level_editor.model.LevelWriter; import vooga.scroller.level_editor.view.LEGridView; import vooga.scroller.level_editor.view.LEView; import vooga.scroller.level_editor.view.LEWorkspaceView; import vooga.scroller.level_management.splash_page.SplashPage; import vooga.scroller.level_management.splash_page.TestSplashPage; import vooga.scroller.model.Model; import vooga.scroller.scrollingmanager.OmniScrollingManager; import vooga.scroller.scrollingmanager.ScrollingManager; import vooga.scroller.sprites.superclasses.Player; import vooga.scroller.util.PlatformerConstants; import vooga.scroller.util.Renderable; import vooga.scroller.util.mvc.IController; import vooga.scroller.util.mvc.IWindow; import vooga.scroller.util.mvc.SimpleView; import vooga.scroller.util.mvc.vcFramework.WorkspaceView; import vooga.scroller.view.GameView; /** * The controller is responsible for interfacing between an IView and an IModel. * Among other things, it is responsible for <LI>Instantiating a generic model and a view</LI> <LI> * Keeping track of multiple high-level domain-specific objects (eg. Room, Level...)</LI> <LI>Send * Renderable versions to the adequate IView workspace</LI> <LI>Send an "Editable" versions to the * Model</LI> <LI>Ensuring that all high-level domain instances are kept in sync. * * @author SLogo team 3, Dagbedji F. * */ public class LEController implements IController<LevelEditing> { private static final String SAVE_ERROR = "All levels need a StartPoint, Portal, and Background"; public static void runLevelEditor (ISpriteLibrary lib, IBackgroundLibrary bgLib, Player samp) { LEController con = new LEController(lib, bgLib, samp); con.start(); } public static final int DEFAULT_SPRITE_GRID_SIZE = 30; private LevelEditing myDomainInfo; private LevelParser myLevelReader; private LevelWriter myLevelWriter; private ILevelEditor myModel; private Map<WorkspaceView<LevelEditing>, EditableGrid> myTab2Workspace; private LETools myTools; private ToolsManager myToolsManager; private IWindow<LEWorkspaceView, LevelEditing, LEGridView, LETools> myView; private Map<EditableGrid, WorkspaceView<LevelEditing>> myWorkspace2Tab; private GridSpinner myGridSpinner; public static final int MIN_SPRITE_GRID_SIZE = 20; public static final int MAX_SPRITE_GRID_SIZE = 1000; private Player mySamplePlayer; /** * Preferred constructor, specifies sprites and background to be availed in the * Level Editor. * * @param lib - A sprite Library for the editor * @param bgLib - A background Library to be used in the editor */ public LEController (ISpriteLibrary lib, IBackgroundLibrary bgLib, Player samp) { myDomainInfo = new LevelEditing(); myToolsManager = new ToolsManager(lib, bgLib); myTools = myToolsManager.getViewTools(); initLevelEditor(); myModel.setSpriteMap(myToolsManager.getSpriteMap()); myModel.setBackgroundMap(bgLib.getBackgrounds()); // myView.setDefaultWorkspaceTools(myTools); myWorkspace2Tab = new HashMap<EditableGrid, WorkspaceView<LevelEditing>>(); myTab2Workspace = new HashMap<WorkspaceView<LevelEditing>, EditableGrid>(); myLevelWriter = new LevelWriter(this); myLevelReader = new LevelParser(this); myGridSpinner = new GridSpinner(); mySamplePlayer = samp; } /** * @param id * @param m */ private void createWorkspaceView (int id, LEGrid m) { LEWorkspaceView associatedWorkspaceView = myView.initializeWorkspaceView(id, (Renderable<LevelEditing>) m); myWorkspace2Tab.put(m, associatedWorkspaceView); myTab2Workspace.put(associatedWorkspaceView, m); myView.showWorkspace(associatedWorkspaceView, (Renderable<LevelEditing>) m); } @Override public LevelEditing getDomainInfo () { return myDomainInfo; } private void initLevelEditor () { String language = getLanguage(); myView = new LEView(language, this, myTools); myModel = new LevelEditor(this); } private String getLanguage () { String[] languages = {"English", "French"}; int n = JOptionPane.showOptionDialog(null, "Choose a language", "Language Selection", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, languages, languages[0]); String language = languages[n]; return language; } /** * return the Room Object corresponding to the input TabView * * @param t * @return */ private EditableGrid getModelForWorkspace (WorkspaceView<LevelEditing> v) { return myTab2Workspace.get(v); } /** * This allows the user to specify the number of blocks needed for the level. * * @return [width, height] in blocks */ private int[] getNumBlocks () { int[] res = new int[2]; int a = (int) JOptionPane.showConfirmDialog(null, myGridSpinner, "Grid Height and Width", JOptionPane.OK_CANCEL_OPTION); if (a == 0) { res[0] = myGridSpinner.getGridWidth(); res[1] = myGridSpinner.getGridHeight(); } else { res[0] = DEFAULT_SPRITE_GRID_SIZE; res[1] = DEFAULT_SPRITE_GRID_SIZE; } return res; } @Override public void initializeWorkspace () { int id = myWorkspace2Tab.size(); int[] size = getNumBlocks(); initializeWorkspace(id, size[0], size[1]); } /** * Initialize an LE workspace * * @param numWidthBlocks - blocks per width (row) * @param numHeightBlocks - block per height (columns) */ public void initializeWorkspace (int numWidthBlocks, int numHeightBlocks) { int id = myWorkspace2Tab.size(); initializeWorkspace(id, numWidthBlocks, numHeightBlocks); } private void initializeWorkspace (int id, int numWidthBlocks, int numHeightBlocks) { LEGrid m = new LEGrid(numWidthBlocks, numHeightBlocks); createWorkspaceView(id, m); } @Override public void loadFile (File file2open) { LEGrid m = myLevelReader.makeGridFromFile(file2open); int id = myWorkspace2Tab.size(); createWorkspaceView(id, m); } @Override public void process (WorkspaceView<LevelEditing> t, Object cmd) { LEGrid m = (LEGrid) getModelForWorkspace(t); if (cmd instanceof String) { myModel.processCommand(m, (String) cmd); } t.setRenderable((Renderable<LevelEditing>) m); } @Override public void saveFile (File file2save, WorkspaceView<LevelEditing> t) { LEGrid grid = (LEGrid) getModelForWorkspace(t); if (checkSaveable(grid)) { myLevelWriter.createFile(file2save, grid, myToolsManager.getSpriteLibPath()); grid.saveThumbnail(file2save.getPath()); } else { showErrorMsg(SAVE_ERROR); } } private boolean checkSaveable (LEGrid grid) { return grid.isValidForSave(); } @Override public void start () { myView.start(); } @Override public void showErrorMsg (String copyError) { myView.showMessageDialog(copyError); } /** * TODO - simulation broke because of change in how games are created. * Among other things, implementation of abstract method: getVisits(), need for * sample player, and dependency of sample player on a view and a scroller manager. * @param grid */ public void simulate (LEGrid grid) { SimpleView simContainer = new SimpleView("Level Simulation"); ScrollingManager sm = new OmniScrollingManager(); GameView display = new GameView(PlatformerConstants.DEFAULT_WINDOW_SIZE, sm); sm.initView(display); mySamplePlayer = new Mario(new Dimension(20, 32), display, sm); Level sim = new Level(1, sm, grid); SplashPage sp = new TestSplashPage(display, sm); Model m = new Model(display, sm, mySamplePlayer, sp, sim); display.setModel(m); sim.addPlayer(mySamplePlayer); m.start(); display.start(); simContainer.add((GameView) display); simContainer.start(); } }