From ec60c9e4190ac19f68287a8008c430779468fd6a Mon Sep 17 00:00:00 2001 From: Sensor12 <36866066+Sensor12@users.noreply.github.com> Date: Mon, 5 Mar 2018 17:48:15 +0100 Subject: [PATCH] Add files via upload --- src/display/Main.java | 163 +++++++++++++++++++++++++----------------- 1 file changed, 97 insertions(+), 66 deletions(-) diff --git a/src/display/Main.java b/src/display/Main.java index 26fe5a5..1dda48d 100755 --- a/src/display/Main.java +++ b/src/display/Main.java @@ -10,10 +10,56 @@ import logic.Levels; import util.Vector2d; +/* + * Unser Programm implementiert eine Version des Breakout-Spiels, mithilfe des + * "model, view, controller" Prinzips. Durch Nutzen des MVCs ist es möglich das + * Spiel über verschiedene Views zu visualisieren, in diesem Projekt auf dem + * CAU-Hochhaus. Zur Darstellung auf dem Hochhaus haben wir die View auf die Größe des + * Hochhauses(28 x 14) skaliert. + * Als Model haben wir verschiedene Klassen geschrieben, + * dazu zählt das Paket logic und das Paket util. + * Die View und der Controller werden in dem Paket display realisiert. + * Unser Standartcontroller benutzt die Maus, um das Paddle zu steuern. + * Um zu erreichen, dass das Spiel auf jeder Maschine gleich schnell läuft, nutzen wir + * in der Main-Klasse die Mainloop, die die Ausführungszeit für ein frame misst, dabei + * dient die GameLogic unter anderem der konstanten Bewegung des Balls. + * Als Basis der Grafik wird die ACM Bibliothek genutzt, die bereits in der + * Vorlesung genutzt wurde. + * Ebenfalls wurde in diesem Projekt viel mit objekt-orientierter Programmierung gearbeitet, + * es wurden eigene Objekte für den Ball, das Spielbrett, die Blöcke, + * das Paddle, usw. erstellt und genutzt. + * Auch die, für die objekt-orientierte Programmierung, typische Vererbung spielt eine wichtige + * Rolle in unserem Programm. So ist zum Beipiel die NoBlock-Klasse eine Unterklasse der + * Block-Klasse, sowie auch LighthouseScreenThread von LighthouseDisplayThread erbt. + * Auch die Gleichzeitigkeit spielt ein Rolle bei der Darstellung verschiedener Views, in unserem + * Beispiel in der Klasse LightHouseDisplayThread. + * Zu Beginn des Spiels wird in der Main-Klasse die init-Methode ausgeführt, die die Verbindung + * zum Lighthouse herstellt, sowie die Möglichkeit Mouseevents zu nutzen und das Spielbrett, bestehend aus + * Ball, Paddle und Platzhaltern für Blöcke, zu erstellen. + * Danach wird die run-Methode ausgeführt, die das Intro startet und ein neues Objekt der GameLogic + * erstellt. Dieses Objekt beinhaltet zunächst das 1. Level. Innerhalb der run-Methode wird die Mainloop + * gestartet und in Dauerschleife ausgeführt. + * Die Mainloop ist , wie bereits beschrieben für die zeitliche Abhängigkeit zuständig, darüber hinaus prüft + * sie auch, ob der Spieler ein Level abgeschlossen oder bereits verloren hat. + * Die GameLogic beinhaltet drei Konstruktoren, die dazu dienen zwischen Leveln und Mitteilung an den + * Nutzer auszuwählen. + * Sie beinhaltet verschiedene getter-Methoden, registriert die Kollision des Balls mit + * den Blöcken, dem Paddle und den Rändern, außerdem ist sie zuständig für die Bewegung des Paddles + * und des Balls. + * In der Board-Klasse haben wir ebenfalls mehrere Konstruktoren, die dazu dienen ein Spielfeld + * mit unterschiedlichen Farben zu erstellen. Sie nutzt dafür die Block-Klasse und NoBlock-Klasse. + * Die NoBlock-Klasse, ist wie bereits beschrieben, eine Unterklasse der Block-Klasse und dient vor allem + * der einfacheren Registierung einer Kollision mit Blöcken. + * Die Block-Klasse dient der Farbgebung verschiedener Blöcke, diese werden zum Teil zufällig + * generiert. + * + * + * + */ + public class Main extends GraphicsProgram { - /* Constants */ - + //constants private static final int WIDTH = 560; private static final int HEIGHT = 280; private static final int BLOCK_HEIGHT = 20; @@ -22,9 +68,8 @@ public class Main extends GraphicsProgram { private static final long FRAMETIME = 1_000_000_000 / FPS; // nanoseconds private static final int FPS_LH = 30; private static final long FRAMETIME_LH = 1_000_000_000 / FPS_LH; - - /* Private instance variables */ - + + //instance variables private GameLogic gameLogic = new GameLogic(); private GRect ball; private GRect paddle; @@ -32,10 +77,7 @@ public class Main extends GraphicsProgram { private boolean useLighthouse = false; private LighthouseDisplay disp; - - /** - * Reads settings via user input and initialises ACM and Lighthouse displays and the controller. - */ + public void init() { if (readBoolean("Use Lighthouse API? [true/false] ")) { useLighthouse = true; @@ -63,83 +105,60 @@ public void init() { initGFX(); } - /** - * Displays text, or rather a sequence of letters, as block configurations. - * @param text the sequence of blocks to display. - */ - private void showText(int[][][] text) { + public void showText(int[][][] text) { for (int[][] screen : text) { - /* Load the current letter */ gameLogic = new GameLogic(screen); - /* Display via ACM */ display(); if (useLighthouse) { - Thread t = new LighthouseScreenThread(gameLogic, disp); - t.start(); + displayScreenLighthouse(); } - pause(750); + pause(1000); } } - - /** - * Loads the first level and shows the intro screen. - * Calls main loop. - */ + public void run() { - /* Show intro screen */ - showText(Levels.INTRO); - /* Load level 0 */ + +// showText(Levels.INTRO); gameLogic = new GameLogic(0); - /* Start the main loop */ mainLoop(); } - - /** - * Controls logic and display timings and sequences levels; - */ + private void mainLoop() { long timer = System.nanoTime(); long lastFrame = System.nanoTime(); long lastLHFrame = System.nanoTime(); - long tmpTimer; // necessary for precise timing + long tmpTimer; while (true) { - - /* Run a single logic cycle */ tmpTimer = System.nanoTime(); gameLogic.cycle(System.nanoTime() - timer); timer = tmpTimer; - /* Game over check */ + // Game over if (gameLogic.getDeathState() == true) { showText(Levels.GAMEOVER); - gameLogic = new GameLogic(0); // start over at level 0 - continue; + gameLogic = new GameLogic(0); } - /* Level completed check */ + // Level completed if (gameLogic.getLevelCompleteState() == true) { if (gameLogic.getNextLevel() < Levels.LVL.length) { - // There are levels left: start the next one gameLogic = new GameLogic(gameLogic.getNextLevel()); } else { showText(Levels.YOU_WIN); gameLogic = new GameLogic(0); } - continue; } - - /* Update ACM display as needed */ + if (System.nanoTime() - lastFrame > FRAMETIME) { display(); lastFrame = System.nanoTime(); } - - /* Update Lighthouse display as needed */ + if (useLighthouse && System.nanoTime() - lastLHFrame > FRAMETIME_LH) { LighthouseDisplayThread t = new LighthouseDisplayThread(gameLogic, disp); t.start(); @@ -148,25 +167,16 @@ private void mainLoop() { } } - - /** - * Handles mouse movement. - */ + public void mouseMoved(MouseEvent e) { double x = e.getX(); gameLogic.movePaddle(x - gameLogic.getPaddleData()[1] / 2); } - - /** - * Handles mouse input. - */ + public void mouseClicked(MouseEvent e) { gameLogic.go(); } - - /** - * Updates the ACM display. - */ + private void display() { Vector2d ballPos = gameLogic.getBallPos(); ball.setLocation(ballPos.getX(), ballPos.getY()); @@ -182,12 +192,9 @@ private void display() { } repaint(); } - /** - * Initialises all graphics objects of the ACM display. - */ + private void initGFX() { - - /* init the block representations */ + Block[][] blocks = gameLogic.getBlocks(); blockReps = new GRect[blocks.length][blocks[0].length]; @@ -199,20 +206,44 @@ private void initGFX() { add(blockReps[col][row]); } } - - /* init the ball representation */ + ball = new GRect(-500, -500, gameLogic.getBallSize(), gameLogic.getBallSize()); ball.setColor(Color.WHITE); ball.setFillColor(Color.WHITE); ball.setFilled(true); add(ball); - - /* init the paddle representation */ + paddle = new GRect(-500, HEIGHT - gameLogic.getPaddleData()[2], gameLogic.getPaddleData()[1], gameLogic.getPaddleData()[2]); paddle.setFillColor(Color.WHITE); paddle.setFilled(true); add(paddle); } + + private void displayScreenLighthouse() { + byte[] px = new byte[3 * 28 * 14]; + for (int i = 0; i < 14; i++) { + for (int j = 0; j < 14; j++) { + Color c = gameLogic.getBlocks()[i][j].getColor(); + byte r = (byte) c.getRed(); + byte g = (byte) c.getGreen(); + byte b = (byte) c.getBlue(); + int first = 6 * i + 3 * 28 * j; + px[first] = r; + px[first + 3] = r; + px[first + 1] = g; + px[first + 4] = g; + px[first + 2] = b; + px[first + 5] = b; + } + } + + try { + disp.send(px); + } catch (Exception e) { + println("Couldn't send data: " + e.getMessage()); + e.printStackTrace(); + } + } } \ No newline at end of file