Average Density: 0.01
  1 package nl.tudelft.jpacman;
  2 
  3 import nl.tudelft.jpacman.board.BoardFactory;
  4 import nl.tudelft.jpacman.board.Direction;
  5 import nl.tudelft.jpacman.game.Game;
  6 import nl.tudelft.jpacman.game.GameFactory;
  7 import nl.tudelft.jpacman.level.*;
  8 import nl.tudelft.jpacman.npc.ghost.GhostFactory;
  9 import nl.tudelft.jpacman.points.PointCalculator;
 10 import nl.tudelft.jpacman.points.PointCalculatorLoader;
 11 import nl.tudelft.jpacman.sprite.PacManSprites;
 12 import nl.tudelft.jpacman.ui.Action;
 13 import nl.tudelft.jpacman.ui.PacManUI;
 14 import nl.tudelft.jpacman.ui.PacManUiBuilder;
 15 
 16 import java.awt.event.KeyEvent;
 17 import java.io.IOException;
 18 import java.util.List;
 19 
 20 /**
 21  * Creates and launches the JPacMan UI.
 22  * 
 23  * @author Jeroen Roosen
 24  */
 25 @SuppressWarnings("PMD.TooManyMethods")
 26 public class Launcher {
 27 
 28     private static final PacManSprites SPRITE_STORE = new PacManSprites();
 29 
 30     public static final String DEFAULT_MAP = "/board.txt";
 31     private String levelMap = DEFAULT_MAP;
 32 
 33     private PacManUI pacManUI;
 34     private Game game;
 35 
 36     /**
 37      * @return The game object this launcher will start when {@link #launch()}
 38      *         is called.
 39      */
 40     public Game getGame() {
 41         return game;
 42     }
 43 
 44     /**
 45      * The map file used to populate the level.
 46      *
 47      * @return The name of the map file.
 48      */
 49     protected String getLevelMap() {
 50         return levelMap;
 51     }
 52 
 53     /**
 54      * Set the name of the file containing this level's map.
 55      *
 56      * @param fileName
 57      *            Map to be used.
 58      * @return Level corresponding to the given map.
 59      */
 60     public Launcher withMapFile(String fileName) {
 61         levelMap = fileName;
 62         return this;
 63     }
 64 
 65     /**
 66      * Creates a new game using the level from {@link #makeLevel()}.
 67      *
 68      * @return a new Game.
 69      */
 70     public Game makeGame() {
 71         GameFactory gf = getGameFactory();
 72         Level level = makeLevel();
 73         game = gf.createSinglePlayerGame(level, loadPointCalculator());
 74         return game;
 75     }
 76 
 77     private PointCalculator loadPointCalculator() {
 78         return new PointCalculatorLoader().load();
 79     }
 80 
 81     /**
 82      * Creates a new level. By default this method will use the map parser to
 83      * parse the default board stored in the <code>board.txt</code> resource.
 84      *
 85      * @return A new level.
 86      */
 87     public Level makeLevel() {
 88         try {
 89             return getMapParser().parseMap(getLevelMap());
 90         } catch (IOException e) {
 91             throw new PacmanConfigurationException(
 92                     "Unable to create level, name = " + getLevelMap(), e);
 93         }
 94     }
 95 
 96     /**
 97      * @return A new map parser object using the factories from
 98      *         {@link #getLevelFactory()} and {@link #getBoardFactory()}.
 99      */
100     protected MapParser getMapParser() {
101         return new MapParser(getLevelFactory(), getBoardFactory());
102     }
103 
104     /**
105      * @return A new board factory using the sprite store from
106      *         {@link #getSpriteStore()}.
107      */
108     protected BoardFactory getBoardFactory() {
109         return new BoardFactory(getSpriteStore());
110     }
111 
112     /**
113      * @return The default {@link PacManSprites}.
114      */
115     protected PacManSprites getSpriteStore() {
116         return SPRITE_STORE;
117     }
118 
119     /**
120      * @return A new factory using the sprites from {@link #getSpriteStore()}
121      *         and the ghosts from {@link #getGhostFactory()}.
122      */
123     protected LevelFactory getLevelFactory() {
124         return new LevelFactory(getSpriteStore(), getGhostFactory(), loadPointCalculator());
125     }
126 
127     /**
128      * @return A new factory using the sprites from {@link #getSpriteStore()}.
129      */
130     protected GhostFactory getGhostFactory() {
131         return new GhostFactory(getSpriteStore());
132     }
133 
134     /**
135      * @return A new factory using the players from {@link #getPlayerFactory()}.
136      */
137     protected GameFactory getGameFactory() {
138         return new GameFactory(getPlayerFactory());
139     }
140 
141     /**
142      * @return A new factory using the sprites from {@link #getSpriteStore()}.
143      */
144     protected PlayerFactory getPlayerFactory() {
145         return new PlayerFactory(getSpriteStore());
146     }
147 
148     /**
149      * Adds key events UP, DOWN, LEFT and RIGHT to a game.
150      *
151      * @param builder
152      *            The {@link PacManUiBuilder} that will provide the UI.
153      */
154     protected void addSinglePlayerKeys(final PacManUiBuilder builder) {
155         builder.addKey(KeyEvent.VK_UP, moveTowardsDirection(Direction.NORTH))
156                 .addKey(KeyEvent.VK_DOWN, moveTowardsDirection(Direction.SOUTH))
157                 .addKey(KeyEvent.VK_LEFT, moveTowardsDirection(Direction.WEST))
158                 .addKey(KeyEvent.VK_RIGHT, moveTowardsDirection(Direction.EAST));
159     }
160 
161     private Action moveTowardsDirection(Direction direction) {
162         return () -> {
163             assert game != null;
164             getGame().move(getSinglePlayer(getGame()), direction);
165         };
166     }
167 
168     private Player getSinglePlayer(final Game game) {
169         List<Player> players = game.getPlayers();
170         if (players.isEmpty()) {
171             throw new IllegalArgumentException("Game has 0 players.");
172         }
173         return players.get(0);
174     }
175 
176     /**
177      * Creates and starts a JPac-Man game.
178      */
179     public void launch() {
180         makeGame();
181         PacManUiBuilder builder = new PacManUiBuilder().withDefaultButtons();
182         addSinglePlayerKeys(builder);
183         pacManUI = builder.build(getGame());
184         pacManUI.start();
185     }
186 
187     /**
188      * Disposes of the UI. For more information see
189      * {@link javax.swing.JFrame#dispose()}.
190      *
191      * Precondition: The game was launched first.
192      */
193     public void dispose() {
194         assert pacManUI != null;
195         pacManUI.dispose();
196     }
197 
198     /**
199      * Main execution method for the Launcher.
200      *
201      * @param args
202      *            The command line arguments - which are ignored.
203      */
204     public static void main(String[] args)  {
205         new Launcher().launch();
206     }
207 }