package cicaprojekt; import javax.swing.*; import java.awt.*; import java.io.File; import java.io.IOException; import java.util.Map; /** * Egy játékmenetet reprezentáló oszály. */ public class Game { /** * Az egyik játékos, O'Neill ezredes tárolása. */ private Player oneill = null; /** * A másik játékos, Jaffa tárolása. */ private Player jaffa = null; /** * A Replikátor tárolása. */ private PlayerBase replicator = null; /** * Az aktuális útvesztő tárolása. */ private Dungeon dungeon; /** * A játékidő tárolása. */ private FlowOfTime flowoftime; /** * A megjelenítési felület tárolása. */ private Display display; /** * Egy játékpéldány. */ public static Game instance = new Game(); /** * Az osztály konstruktora. */ private Game() {} /** * A Replikátor megsemmisítését implementáló függvény. * Ha a Replikátor úgy semmisült meg, hogy szakadékba esett, akkor * a szakadék helyét egy mező veszi át. * * @param caller a megsemmisülő Replikátor * @see Tile#setX(int) * @see Tile#setY(int) * @see Tile#setAdajacentTile(Tile, Direction) * @see Tile#getAdjacentTile(Direction) * @see Display#gapMagic(Gap, Field, int) */ public void playerBaseDestroyed(PlayerBase caller) { if (caller.getCurrentTile().isGap()) { Field field = new Field(); Tile callertile = caller.getCurrentTile(); field.setX(callertile.getX()); field.setY(callertile.getY()); field.setAdajacentTile(caller.getCurrentTile().getAdjacentTile(Direction.NORTH), Direction.NORTH); callertile.getAdjacentTile(Direction.NORTH).setAdajacentTile(field, Direction.SOUTH); field.setAdajacentTile(caller.getCurrentTile().getAdjacentTile(Direction.SOUTH), Direction.SOUTH); callertile.getAdjacentTile(Direction.SOUTH).setAdajacentTile(field, Direction.NORTH); field.setAdajacentTile(caller.getCurrentTile().getAdjacentTile(Direction.WEST), Direction.WEST); callertile.getAdjacentTile(Direction.WEST).setAdajacentTile(field, Direction.EAST); field.setAdajacentTile(caller.getCurrentTile().getAdjacentTile(Direction.EAST), Direction.EAST); callertile.getAdjacentTile(Direction.EAST).setAdajacentTile(field, Direction.WEST); display.gapMagic((Gap) callertile, field, dungeon.getMapWidth()); Game.instance.updateDisplay(); } } /** * Egy játékos megsemmisítését implementáló függvény. Csökkenti a játék * teljesítéséhez szükséges ZPM-ek számát a megsemmisülő általá * összegyűjtött ZPM-ekkel, majd frissíti a megjelenítést. * Ha mindkét játékos halott, akkor a játék véget ér Anubis győzelmével. * * @param caller a megsemmisülő játékos * @see #updateDisplay() * @see FlowOfTime#stopTime() * @see #stopGame(GameoverCause) */ public void playerDestroyed(Player caller) { dungeon.setZPMsToWin(dungeon.getZPMsToWin() - caller.getZPMCount()); Game.instance.updateDisplay(); if (jaffa.isDestroyed() && oneill.isDestroyed()) { flowoftime.stopTime(); stopGame(GameoverCause.ANUBIS); } } /** * Beállítja az aktuális útvesztőt a kapott útvesztőre. * * @param dungeon kapott útvesztő */ public void setDungeon(Dungeon dungeon) { this.dungeon = dungeon; } /** * Beállítja az akutális megjelenítést a kapott megjelenítésre. * * @param display kapott megjelenítés */ public void setDisplay(Display display) { this.display = display; } /** * Elindítja a játékot a kapott útvesztőt tartalmazó fájl alapján. * Inicializálja a csillagkapukat, felépíti az útvesztőt, létrehozza * a játékosokat és a Replikátort, valamint beállítja a megjelenítést. * Elindítja a zenét, majd a játékidőt is. * * @param dungeonFile kapott útvesztő * @throws IOException Ha nem található a fájl. * @see Stargate#init() * @see Dungeon#buildDungeon(File, Display) * @see Display#addVisual(Drawer) * @see Display#startMusic() * @see FlowOfTime#start(long) */ public void startGame(File dungeonFile) throws IOException { Stargate.init(); Map players = dungeon.buildDungeon(dungeonFile, display); oneill = new Player("O'Neill", players.get("oneill"), Direction.getRandom()); jaffa = new Player("Jaffa", players.get("jaffa"), Direction.getRandom()); replicator = new PlayerBase("Replicator", players.get("replicator"), Direction.getRandom()); display.setMapSize(dungeon.getMapWidth(), dungeon.getMapHeight()); display.addVisual(new PlayerDrawer(oneill)); display.addVisual(new PlayerDrawer(jaffa)); display.addVisual(new PlayerBaseDrawer(replicator)); display.startMusic(); flowoftime = new FlowOfTime(); flowoftime.start(dungeon.getTimeLimit()); } /** * A játék megállítása valamilyen kapott okból. Az oknak megfelelően * más és más befejezése van a játéknak. Végül a zene leállítása. * * @param cause a leállítás oka * @see Display#stopMusic() */ public void stopGame(GameoverCause cause) { switch (cause){ case TIMEOUT: JOptionPane.showMessageDialog(null, "Time is up! Anubis has enslaved the world by now.", "Game over", JOptionPane.INFORMATION_MESSAGE, new ImageIcon("Anubis.png")); Application.frameInstance.backToMapSelection(); break; case ONEILLWON: JOptionPane.showMessageDialog(null, "Colonel O'Neill won!", "Game over", JOptionPane.INFORMATION_MESSAGE, new ImageIcon("Deal_with_iit.png")); Application.frameInstance.backToMapSelection(); break; case JAFFAWON: JOptionPane.showMessageDialog(null, "Jaffa won!", "Game over", JOptionPane.INFORMATION_MESSAGE, new ImageIcon("Deal_with_iit.png")); Application.frameInstance.backToMapSelection(); break; case DRAW: JOptionPane.showMessageDialog(null, "Draw! While O'Neill and the Jaffa struggled against eachother, Anubis has enslaved the world.", "Game over", JOptionPane.INFORMATION_MESSAGE, new ImageIcon("Anubis.png")); Application.frameInstance.backToMapSelection(); break; case ANUBIS: JOptionPane.showMessageDialog(null, "There is no one left to stop Anubis from enslaving the world", "Game over", JOptionPane.INFORMATION_MESSAGE, new ImageIcon("Anubis.png")); Application.frameInstance.backToMapSelection(); break; } display.stopMusic(); } /** * O'Neill ezredes léptetése a kapott irányba. * * @param direction kapott irány * @see Player#move(Direction) * @see #checkZPMStatus() */ public void moveONeill(Direction direction) { oneill.move(direction); checkZPMStatus(); } /** * Jaffa léptetése a kapott irányba. * * @param direction kapott irány * @see Player#move(Direction) * @see #checkZPMStatus() */ public void moveJaffa(Direction direction) { jaffa.move(direction); checkZPMStatus(); } /** * A Replikátor léptetése a kapott irányba. * * @param direction kapott irány * @see PlayerBase#move(Direction) */ public void moveReplicator(Direction direction) { replicator.move(direction); } /** * O'Neill ezredes forgatása balra. * * @see Player#rotateLeft() */ public void rotateOneillLeft() { oneill.rotateLeft(); } /** * O'Neill ezredes forgatása jobbra. * * @see Player#rotateRight() */ public void rotateOneillRight() { oneill.rotateRight(); } /** * Jaffa forgatása balra. * * @see Player#rotateLeft() */ public void rotateJaffaLeft() { jaffa.rotateLeft(); } /** * Jaffa forgatása jobbra. * * @see Player#rotateRight() */ public void rotateJaffaRight() { jaffa.rotateRight(); } /** * O'Neill ezredes dobozainak kezelése. * * @see Player#hasBox() * @see Player#boxDrop() * @see Player#boxLift() */ public void boxONeill() { if(oneill.hasBox()) oneill.boxDrop(); else oneill.boxLift(); } /** * Jaffa dobozainak kezelése. * * @see Player#hasBox() * @see Player#boxDrop() * @see Player#boxLift() */ public void boxJaffa() { if(jaffa.hasBox()) jaffa.boxDrop(); else jaffa.boxLift(); } /** * Csillagkapu lövését implementáló függvény. * Ha a kilőtt csillagkapu sárga vagy kék, akkor O'Neill * ezredeshez tartozik, egyébként Jaffához. * * @param color a csillagkapu színe */ public void shootStargate(Color color) { if(color == Color.YELLOW || color == Color.BLUE) oneill.shootStargate(Stargate.get(color)); else jaffa.shootStargate(Stargate.get(color)); } /** * A megjelenítő panel frissítése, újrarajzolása. * * @see Control#ioErrorMessage() */ public void updateDisplay() { try { display.drawVisuals(); display.repaint(); } catch (IOException e) { Control.ioErrorMessage(); } } /** * A ZPM-ek állapotának ellenőrzése. Ha O'Neill ezredes és Jaffa összesen * összegyűjtöttek annyi ZPM-et, amennyi szükséges a játék megnyeréséhez, * akkor az fog nyerni, aki több ZPM-et gyűjtött, egyébként veszítettek. * A játékidő leállítódik és a játék véget ér. * * @see Player#getZPMCount() * @see FlowOfTime#stopTime() * @see #stopGame(GameoverCause) */ private void checkZPMStatus() { if (oneill.getZPMCount() + jaffa.getZPMCount() >= dungeon.getZPMsToWin()) { if (oneill.getZPMCount() > jaffa.getZPMCount()) { flowoftime.stopTime(); stopGame(GameoverCause.ONEILLWON); } else if (oneill.getZPMCount() < jaffa.getZPMCount()) { flowoftime.stopTime(); stopGame(GameoverCause.JAFFAWON); } else { flowoftime.stopTime(); stopGame(GameoverCause.DRAW); } return; } if (oneill.getZPMCount() >= dungeon.getZPMsToWin()) { flowoftime.stopTime(); stopGame(GameoverCause.ONEILLWON); } else if (jaffa.getZPMCount() >= dungeon.getZPMsToWin()) { flowoftime.stopTime(); stopGame(GameoverCause.JAFFAWON); } } /** * A ZPM-ek véletlenszerű generálását implementáló függvény. A függvény addig * iterál, amíg nem talál alkalmas helyet egy új ZPM-nek. Ha ezt megtalálta, * akkor létrehoz oda egy új ZPM-et, majd megnöveli a játékban való győzelemhez * szükséges ZPM-ek számát. * * @see Tile#setZPMOnTile(ZPM) * @see Dungeon#setZPMsToWin(int) */ public void generateZPM() { if(((jaffa.getZPMCount() + oneill.getZPMCount()) % 2) == 0) { Tile source = oneill.getCurrentTile(); Tile compare; for (int i = 0; i < dungeon.getMapHeight(); i++) { compare = source.getAdjacentTile(Direction.getRandom()); if (compare != null) source = compare; } while (!source.canHazZPM() || source.hasZPM()) { int newSourceCounter = 0; for (int i = 0; i < dungeon.getMapHeight(); i++) { compare = source.getAdjacentTile(Direction.getRandom()); if (compare != null) source = compare; } while(newSourceCounter != 20) { compare = source.getAdjacentTile(Direction.getRandom()); if (compare != null) { source = compare; if (!compare.hasZPM() && (compare.playerBaseOnTile == null)) { if (source.canHazZPM() && !source.hasZPM()) { break; } } } newSourceCounter++; } } source.setZPMOnTile(new ZPM()); dungeon.setZPMsToWin(dungeon.getZPMsToWin()+1); } } }