Anonymous avatar Anonymous committed 587b4bb

Daily...

Comments (0)

Files changed (15)

src/Game/Ball.java

  */
 
 public class Ball extends RigidBody {
-    private float radius;
     private RigidBodyControl ball;
+    private float radius;
 
     public Ball(Handler handler) {
         super(handler);
     }
 
     public void zeroVelocity() {
+        ball.clearForces();
         ball.setLinearVelocity(Vector3f.ZERO);
     }
+
+    public void pause(){
+        ball.setKinematic(true);
+        ball.setKinematicSpatial(true);
+    }
+
+    public void resume(){
+        ball.setKinematic(false);
+        ball.setKinematicSpatial(false);
+    }
 }

src/Game/Cell.java

 package Game;
 
 /**
- * Represents a single cell on the board during randomly maze generating.
+ * Represents a cell on the board during randomly maze generating.
  */
 
 public class Cell {
     /**
-     * x and y represent the location of the cell on the board of which the
-     * centre is (0, 0)
+     * x and y are the relative coordinates of the cell on the board whose
+     * central cell has the coordinate of (0, 0).
      */
     private float x, y;
     private float sideLength;
     private boolean visited;
     private int direction;
 
+    /**
+     * There are two types of walls: normal walls and borders.
+     * Normal walls are those that can be pushed down.
+     * Borders are the border of the board, which cannot be pushed down.
+     *
+     * Initially, every cell has four normal walls, W, S, E, and N.
+     *
+     * Some of these may be changed to borders depending on the position of the
+     * cell on the board.
+     *
+     * If the cell is the leftmost cell in a row, it has a 'W' border.
+     * If the cell is the topmost cell in a column, it has a 'N' border.
+     * etc.
+     */
     private int wall;
     private int border;
 
+    final private int N = 1;
+    final private int E = 2;
+    final private int S = 4;
+    final private int W = 8;
 
     public Cell(int x, int y, int width, int height) {
         border = 0;
 
         /**
-         * |= is similar to +=. It is used to set up a flag.
+         * |= is used to set up a flag.
          * e.g. 0000 | 1010 = 1010
          */
         if (0 == x) {
-            border |= 8;
+            border |= W;
         } else if (width - 1 == x) {
-            border |= 2;
+            border |= E;
         }
 
         if (0 == y) {
-            border |= 1;
+            border |= N;
         } else if (height - 1 == y) {
-            border |= 4;
+            border |= S;
         }
 
+        /**
+         * e.g. If the border is 1001, the wall should be:
+         * 1111(15) - 1001 = 0110
+         */
         wall = 15 - border;
     }
 
     /**
-     * Visit a cell by setting its direction to the specified direction and
-     * 'knock down' the wall at that direction.
+     * Visits a cell by setting its direction to the specified direction and
+     * pushing down the wall in that direction.
      *
      * @param direction The direction to set up the cell.
      */
         this.visited = true;
 
         /**
-         * & is another bit operation. Here, it is used to test if a certain bit is 1.
-         * e.g. 1010 & 1000 = 1000 > 0
+         * & is used to test if a certain bit is 1.
+         * e.g. 1010 & 1000 (W) = 1000 > 0
+         *
+         * -= is used to push down the wall in a direction.
+         * e.g. 1010 - 1000 = 0010, the first bit is zeroed, so the 'W' wall is
+         * pushed down.
          */
         if ((direction & wall) > 0) {
             wall -= direction;
     }
 
     public boolean hasNorthWall() {
-        return (wall & 1) > 0 || (border & 1) > 0;
+        return (wall & N) > 0 || (border & N) > 0;
     }
 
     public boolean hasEastWall() {
-        return (wall & 2) > 0 || (border & 2) > 0;
+        return (wall & E) > 0 || (border & E) > 0;
     }
 
     public boolean hasSouthWall() {
-        return (wall & 4) > 0 || (border & 4) > 0;
+        return (wall & S) > 0 || (border & S) > 0;
     }
 
     public boolean hasWestWall() {
-        return (wall & 8) > 0 || (border & 8) > 0;
+        return (wall & W) > 0 || (border & W) > 0;
     }
 
     public void setSideLength(float sideLength) {
-        this.sideLength = sideLength * 2;
+        this.sideLength = sideLength;
     }
 
     /**
-     * Converts the index of the cell to the coordinate on the board.
+     * Converts the index of the cell in the array to the coordinate on
+     * the board.
      *
      * @param indexI  The first index of the cell
      * @param indexJ  The second index of the cell

src/Game/DFS.java

     private float unit;
 
     public DFS(int level) {
+        directions = new ArrayList<Integer>();
+        directions.add(E);
+        directions.add(S);
+        directions.add(W);
+        directions.add(N);
+
         height = 1 + level * 2;
         width = 3 + level * 2;
         unit = 1f / width;
         for (int i = 0; i < height; i++) {
             for (int j = 0; j < width; j++) {
                 grid[i][j] = new Cell(j, i, width, height);
-                grid[i][j].setSideLength(unit);
+                grid[i][j].setSideLength(unit*2);
 //                The index of the central cell is i = level, j = level + 1
                 grid[i][j].setScreenCoord(i, j, level, level + 1);
             }
         }
 
-        directions = new ArrayList<Integer>();
-        directions.add(E);
-        directions.add(S);
-        directions.add(W);
-        directions.add(N);
     }
 
     /**
         } else if (S == direction) {
             return N;
         } else {
-//          you must be kidding if the program goes to this line.
-            return Integer.MAX_VALUE;
+//          These code will never be executed.
+            return 0;
         }
     }
 
     /**
      * Generates a random maze.
-     * It randomly picks a direction and tries to move in
-     * that direction.
+     *
+     * Randomly picks an adjacent cell and moves to it.
+     *
      * It will move if:
-     * 1. it will not be out of range after one move.
+     * 1. The move will not be out-of-range.
      * 2. the cell to which it moves has not been visited.
-     * It will mark the current cell and the next cell as "visited".
      *
-     * @param cx x-coordinate of the current cell
-     * @param cy y-coordinate of the current cell
+     * @param cx x-coordinate of the cell from where the program starts to
+     * visit its adjacent cells.
+     * @param cy y-coordinate of the cell from where the program starts to
+     * visit its adjacent cells.
      */
-    void carvePassagesFrom(int cx, int cy) {
+    public void visitFrom(int cx, int cy) {
         Collections.shuffle(directions);
         for (Integer direction : directions) {
             int nx = cx + DX(direction);
                     && (grid[ny][nx].isNotVisited())) {
                 grid[cy][cx].visit(direction);
                 grid[ny][nx].visit(Opposite(direction));
-                carvePassagesFrom(nx, ny);
+                visitFrom(nx, ny);
             }
         }
     }
      * Adds the locations of horizontal walls and vertical walls in a random
      * maze to the ArrayList.
      *
-     * @param vWallLocations The ArrayList of locations of vertical walls
-     * @param hWallLocations The ArrayList of locations of horizontal walls
+     * @param vWallLocations The ArrayList of locations of vertical walls.
+     * @param hWallLocations The ArrayList of locations of horizontal walls.
      */
     public void fill(ArrayList<Vector3f> vWallLocations,
                      ArrayList<Vector3f> hWallLocations) {
                 Cell currentCell = grid[i][j];
                 if (currentCell.hasNorthWall()) {
                     hWallLocations.add(
-                            new Vector3f(currentCell.getX(),
+                            new Vector3f(
+                                    currentCell.getX(),
                                     0.2f,
                                     currentCell.getY() - unit));
                 }
 
                 if (currentCell.hasEastWall()) {
                     vWallLocations.add(
-                            new Vector3f(currentCell.getX() + unit,
+                            new Vector3f(
+                                    currentCell.getX() + unit,
                                     0.2f,
                                     currentCell.getY()));
                 }
 
                 if (currentCell.hasSouthWall()) {
                     hWallLocations.add(
-                            new Vector3f(currentCell.getX(),
+                            new Vector3f(
+                                    currentCell.getX(),
                                     0.2f,
                                     currentCell.getY() + unit));
                 }
                 if (currentCell.hasWestWall()) {
                     vWallLocations.add(
-                            new Vector3f(currentCell.getX() - unit,
+                            new Vector3f(
+                                    currentCell.getX() - unit,
                                     0.2f,
                                     currentCell.getY()));
                 }

src/Game/EndPoint.java

 
     /**
      * Note:
-     * The ball collides with the end if the distance between their centres
-     * is less than the threshold.
+     * The ball collides with the end point if the distance between their
+     * centres is less than the threshold value.
      *
      * @param ball The ball being tested for.
-     * @return If the end collides with the ball.
+     * @return True if the ball is too close to the end point.
      */
     @Override
     public boolean collideWith(Ball ball) {

src/Game/Handler.java

  * Is a workaround for the fact that Java does not support callback functions.
  */
 public interface Handler {
-    public void rotateBoard(float x, float y, float z);
+    /**
+     * Rotates the board in the game by the yaw, roll and pitch angles (in
+     * radians), in the local coordinate space.
+     *
+     * @param yaw
+     * @param roll
+     * @param pitch
+     */
+    public void rotateBoard(float yaw, float roll, float pitch);
 
+    /**
+     * Attaches a node to the game, so that the node is visible.
+     *
+     * @param node
+     */
     public void attachNodeToRoot(Node node);
 
-    public void attachPhysicsControl(RigidBodyControl rigidBodyControl);
+    /**
+     * Attaches the controller of the rigid body to the game, so that the
+     * movements of the rigid body obey physics the law of physics.
+     *
+     * @param rigidBody
+     */
+    public void attachPhysicsControl(RigidBodyControl rigidBody);
 
-    public void addShapeToBase(BoxCollisionShape boxCollisionShape,
+    /**
+     * Add a box to the base of the board.
+     *
+     * @param boxShape
+     * @param location The location where the box should be attached.
+     */
+    public void addShapeToBase(BoxCollisionShape boxShape,
                                Vector3f location);
 
-    public void addShapeToBase(CylinderCollisionShape cylinderCollisionShape,
-                               Vector3f location);
+    /**
+     * Add a cylinder to the base of the board.
+     *
+     * @param cylinderShape
+     * @param location The location where the cylinder should be attached.
+     */
+    public void addToBase(CylinderCollisionShape cylinderShape,
+                          Vector3f location);
 
     public float getBallRadius();
 
-    public void resetGame();
+    public void resetBall();
 
-    public void restartGame();
+    public void changeMap();
 
     public void stopGame();
 
-    public void loseGame();
-
     public float getBoardThickness();
 }

src/Game/Hole.java

  */
 
 public class Hole extends RigidBody {
+    CylinderCollisionShape cylinderCollisionShape;
     private float radius;
 
     protected float threshold;
         super(handler);
     }
 
+    @Override
+    public void attach() {
+        cylinderCollisionShape =
+                new CylinderCollisionShape(
+                        new Vector3f(
+                                radius,
+                                handler.getBoardThickness()/2,
+                                0.1f),
+                        1); // The mass of the ball is set to 1.
+        handler.addToBase(cylinderCollisionShape, location);
+    }
+
     public void setRadius(float radius) {
         this.radius = radius;
         threshold = (float) Math.sqrt(Math.pow(radius, 2)
                 + Math.pow(handler.getBallRadius(), 2));
     }
 
-    @Override
-    public void attach() {
-        CylinderCollisionShape cylinderCollisionShape = new CylinderCollisionShape(
-                new Vector3f(radius, handler.getBoardThickness(), 0.1f),
-                1);
-        handler.addShapeToBase(cylinderCollisionShape, location);
-    }
-
     /**
+     * Determines if the hole collides with the ball.
+     *
      * Note:
      * The ball collides with the hole if the distance between their centres
      * is less than a certain value AND the magnitude of the linear speed of
      * the ball is less than a certain value.
      *
      * @param ball The ball being tested for.
-     * @return If the end collides with the ball.
+     * @return True if the ball is too close to the hole and the speed of the
+     * ball is too small.
      */
     public boolean collideWith(Ball ball) {
         return location.distance(ball.getPhysicsLocation()) < threshold
-                && ball.getLinearVelocity() < 1.1f;
+                && ball.getLinearVelocity() < 1;
     }
 }

src/Game/Key.java

     private final ActionListener actionListener = new ActionListener() {
         public void onAction(String name, boolean pressed, float tpf) {
             if (name.equals("Reset") && !pressed) {
-                handler.resetGame();
+                handler.resetBall();
             } else if (name.equals("Quit") && !pressed) {
                 handler.stopGame();
             } else if (name.equals("Change") && !pressed) {
-                handler.restartGame();
+                handler.changeMap();
             }
         }
     };

src/Game/Labyrinth.java

+/**
+ * @author Meitian Huang
+ * @since 4/10/11
+ */
+
+package Game;
+
+import com.jme3.app.SimpleApplication;
+import com.jme3.bullet.BulletAppState;
+import com.jme3.bullet.collision.shapes.BoxCollisionShape;
+import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
+import com.jme3.bullet.collision.shapes.CylinderCollisionShape;
+import com.jme3.bullet.control.RigidBodyControl;
+import com.jme3.font.BitmapText;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Node;
+
+import java.util.ArrayList;
+
+/**
+ * Is the main component of the game.
+ */
+public class Labyrinth extends SimpleApplication {
+
+    private BulletAppState bulletAppState;
+    private float time;
+    private Score score;
+    private Handler handler;
+    private Pref pref;
+
+    private RigidBodyControl board;
+    private Ball ball;
+    private Node boardNode;
+    private CompoundCollisionShape base;
+    private ArrayList<Hole> holes;
+    private EndPoint end;
+    private BitmapText bitmapText;
+    private int timeLeft;
+    private boolean isLost;
+
+    /**
+     * Initiates the game.
+     */
+    @Override
+    public void simpleInitApp() {
+        time = 0;
+        bulletAppState = new BulletAppState();
+        stateManager.attach(bulletAppState);
+        bulletAppState.getPhysicsSpace().enableDebug(assetManager);
+        pref = new Pref();
+
+        initHandler();
+        score = new Score(handler);
+        initWorld();
+        setupKeys();
+    }
+
+    /**
+     * Creates the necessary callback functions.
+     */
+    private void initHandler() {
+        handler = new Handler() {
+            public void rotateBoard(float yaw, float roll, float pitch) {
+                if (!isLost) {
+                    boardNode.rotate(yaw * pref.sensitivity,
+                            roll * pref.sensitivity,
+                            pitch * pref.sensitivity);
+                }
+            }
+
+            public void attachNodeToRoot(Node node) {
+                rootNode.attachChild(node);
+            }
+
+            public void attachPhysicsControl(RigidBodyControl rigidBody) {
+                bulletAppState.getPhysicsSpace().add(rigidBody);
+            }
+
+            public void addShapeToBase(BoxCollisionShape boxShape,
+                                       Vector3f location) {
+                base.addChildShape(boxShape, location);
+            }
+
+            public void addToBase(CylinderCollisionShape cylinderShape,
+                                  Vector3f location) {
+                base.addChildShape(cylinderShape, location);
+            }
+
+            public float getBallRadius() {
+                return ball.getRadius();
+            }
+
+            public void resetBall() {
+                if (isLost) {
+                    time = 0;
+                    isLost = false;
+                }
+                reset();
+
+            }
+
+            public void changeMap() {
+                pref.init();
+                reset();
+            }
+
+            public void stopGame() {
+                isLost = true;
+                ball.pause();
+            }
+
+            public float getBoardThickness() {
+                return pref.boardHeight;
+            }
+        };
+    }
+
+    /**
+     * Initiates the environment of the game.
+     */
+    private void initWorld() {
+        initBoard();
+        initWall();
+        initBall();
+        initHoles();
+        initEnd();
+        initText();
+        finalise();
+    }
+
+    /**
+     * Initiates the base of the board.
+     */
+    private void initBoard() {
+        base = new CompoundCollisionShape();
+
+        final BoxCollisionShape box =
+                new BoxCollisionShape(
+                        new Vector3f(
+                                pref.boardLength,
+                                pref.boardHeight,
+                                pref.boardWidth));
+
+        base.addChildShape(box, Vector3f.ZERO);
+
+        boardNode = new Node("boardNode");
+        board = new RigidBodyControl(base, 90);
+
+        /**
+         * Sets the board to be kinematic so that the board is not effected
+         * by the gravity.
+         */
+        board.setKinematic(true);
+        board.setKinematicSpatial(true);
+
+        boardNode.addControl(board);
+
+        handler.attachNodeToRoot(boardNode);
+        handler.attachPhysicsControl(board);
+    }
+
+    /**
+     * Initiates the walls and attach them to the base.
+     */
+    private void initWall() {
+        for (Vector3f location : pref.vWallLocations) {
+            Wall wall = new Wall(handler);
+            wall.setLocation(location);
+            wall.setWall(pref.vWallShape);
+            wall.attach();
+        }
+
+        for (Vector3f location : pref.hWallLocations) {
+            Wall wall = new Wall(handler);
+            wall.setLocation(location);
+            wall.setWall(pref.hWallShape);
+            wall.attach();
+        }
+    }
+
+    /**
+     * Initiates the holes.
+     */
+    private void initHoles() {
+        holes = new ArrayList<Hole>();
+        for (Vector3f centre : pref.holeCentres) {
+            Hole hole = new Hole(handler);
+            hole.setLocation(centre);
+            hole.setRadius(pref.getUnit() * 0.5f);
+            hole.attach();
+            holes.add(hole);
+        }
+    }
+
+    /**
+     * Initiates the end of the game.
+     */
+    private void initEnd() {
+        end = new EndPoint(handler);
+        end.setLocation(pref.endPosition);
+        end.setRadius(pref.getUnit() * 0.9f);
+        end.attach();
+    }
+
+    /**
+     * Initiates the ball in the game.
+     */
+    private void initBall() {
+        ball = new Ball(handler);
+        ball.setLocation(pref.ballPosition);
+        ball.setRadius(pref.ballRadius);
+        ball.attach();
+
+        /**
+         * I don't find any point to have more than one ball. But I will show
+         * you that is possible.
+         * -- Meitian Huang
+         */
+        Ball ball2 = new Ball(handler);
+        ball2.setLocation(
+                pref.ballPosition.negate().add(new Vector3f(0, 0.4f, 0)));
+        ball2.setRadius(pref.ballRadius * 2);
+        ball2.attach();
+    }
+
+    /**
+     * Initiates the text displayed on the screen.
+     */
+    private void initText() {
+        guiNode.detachAllChildren();
+        guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
+        bitmapText = new BitmapText(guiFont, false);
+        bitmapText.setSize(guiFont.getCharSet().getRenderedSize());
+        bitmapText.setSize(24);
+        guiNode.attachChild(bitmapText);
+        updateText();
+    }
+
+    /**
+     * Sets some values only need to run once.
+     */
+    private void finalise() {
+        this.setDisplayStatView(false);
+        this.setDisplayFps(false);
+    }
+
+    /**
+     * Sets up the keybindings
+     */
+    private void setupKeys() {
+        Key key = new Key(handler);
+        key.associateKey(inputManager);
+    }
+
+    @Override
+    public void simpleUpdate(float tpf) {
+        cam.setLocation(new Vector3f(0, 2.5f, 0.3f));
+        cam.lookAt(board.getPhysicsLocation(), Vector3f.UNIT_Y);
+
+        if (!isLost) {
+            time += tpf;
+            if (end.collideWith(ball)) {
+                score.increaseScore(timeLeft);
+                score.reduceScore((int) time / 10);
+                pref.increaseLevel();
+                pref.init();
+                time = 0;
+                reset();
+            }
+
+            for (Hole hole : holes) {
+                if (hole.collideWith(ball)) {
+                    score.reduceScore();
+                    reset();
+                }
+            }
+
+            timeLeft = (pref.level * 15 - (int) time);
+            if (timeLeft < 0) {
+                isLost = true;
+            }
+        }
+
+        updateText();
+    }
+
+    /**
+     * Updates the text at the bottom of the screen.
+     */
+    private void updateText() {
+        if (isLost) {
+            bitmapText.setText("You lose!");
+        } else {
+            bitmapText.setText("Level:  " + pref.level + "\t"
+                    + "Time Left:    " + timeLeft + "\t"
+                    + score.toString());
+        }
+        bitmapText.setLocalTranslation(
+                (1280 - bitmapText.getLineWidth()) / 2,
+                bitmapText.getLineHeight(),
+                0);
+    }
+
+    /**
+     * Resets the game by removing all elements, re-initiating the environment,
+     * and resetting the position of the ball.
+     */
+    private void reset() {
+        bulletAppState.getPhysicsSpace().remove(board);
+        boardNode.removeFromParent();
+
+        initBoard();
+        initWall();
+        initHoles();
+        initEnd();
+
+        ball.setPhysicsLocation(pref.ballPosition);
+        ball.resume();
+        ball.zeroVelocity();
+    }
+}

src/Game/Maze.java

-/**
- * @author Meitian Huang
- * @since 4/10/11
- */
-
-package Game;
-
-import com.jme3.app.SimpleApplication;
-import com.jme3.bullet.BulletAppState;
-import com.jme3.bullet.collision.shapes.BoxCollisionShape;
-import com.jme3.bullet.collision.shapes.CompoundCollisionShape;
-import com.jme3.bullet.collision.shapes.CylinderCollisionShape;
-import com.jme3.bullet.control.RigidBodyControl;
-import com.jme3.font.BitmapText;
-import com.jme3.math.Vector3f;
-import com.jme3.scene.Node;
-
-import java.util.ArrayList;
-
-/**
- * Is the main component of the game.
- */
-public class Maze extends SimpleApplication {
-
-    private BulletAppState bulletAppState;
-    private float time;
-    private Score score;
-    private Handler handler;
-    private Pref pref;
-
-    private RigidBodyControl board;
-    private Ball ball;
-    private Node boardNode;
-    private CompoundCollisionShape base;
-    private ArrayList<Hole> holes;
-    private EndPoint end;
-    private BitmapText bitmapText;
-    private int timeLeft;
-    private boolean isLost;
-
-    @Override
-    public void simpleInitApp() {
-        time = 0;
-        bulletAppState = new BulletAppState();
-        stateManager.attach(bulletAppState);
-        bulletAppState.getPhysicsSpace().enableDebug(assetManager);
-        pref = new Pref();
-
-        initHandler();
-        score = new Score(handler);
-        initWorld();
-        setupKeys();
-    }
-
-    private void initHandler() {
-        handler = new Handler() {
-            public void rotateBoard(float x, float y, float z) {
-                if (!isLost) {
-                    boardNode.rotate(x * pref.sensitivity,
-                            y * pref.sensitivity,
-                            z * pref.sensitivity);
-                }
-            }
-
-            public void attachNodeToRoot(Node node) {
-                rootNode.attachChild(node);
-            }
-
-            public void attachPhysicsControl(RigidBodyControl rigidBodyControl) {
-                bulletAppState.getPhysicsSpace().add(rigidBodyControl);
-            }
-
-            public void addShapeToBase(BoxCollisionShape boxCollisionShape,
-                                       Vector3f location) {
-                base.addChildShape(boxCollisionShape, location);
-            }
-
-            public void addShapeToBase(CylinderCollisionShape cylinderCollisionShape,
-                                       Vector3f location) {
-                base.addChildShape(cylinderCollisionShape, location);
-            }
-
-            public float getBallRadius() {
-                return ball.getRadius();
-            }
-
-            public void resetGame() {
-                reset();
-            }
-
-            public void restartGame() {
-                pref.init();
-                reset();
-            }
-
-            public void stopGame() {
-                stop();
-            }
-
-            public void loseGame() {
-                System.out.println("You lose!");
-                stop();
-            }
-
-            public float getBoardThickness() {
-                return pref.boardHeight;
-            }
-        };
-    }
-
-    private void initWorld() {
-        initBoard();
-        initWall();
-        initBall();
-        initHoles();
-        initEnd();
-        initText();
-        finalise();
-    }
-
-    private void initBoard() {
-        base = new CompoundCollisionShape();
-
-        final BoxCollisionShape box =
-                new BoxCollisionShape(
-                        new Vector3f(pref.boardLength,
-                                pref.boardHeight,
-                                pref.boardWidth));
-
-        base.addChildShape(box, Vector3f.ZERO);
-
-        boardNode = new Node("boardNode");
-        board = new RigidBodyControl(base, 90);
-
-        board.setKinematic(true);
-        board.setKinematicSpatial(true);
-
-        boardNode.addControl(board);
-
-        handler.attachNodeToRoot(boardNode);
-        handler.attachPhysicsControl(board);
-    }
-
-
-    private void initWall() {
-        ArrayList<Wall> walls = new ArrayList<Wall>();
-
-        for (Vector3f location : pref.vWallLocations) {
-            Wall wall = new Wall(handler);
-            wall.setLocation(location);
-            wall.setWall(pref.vWallShape);
-            wall.attach();
-            walls.add(wall);
-        }
-
-        for (Vector3f location : pref.hWallLocations) {
-            Wall wall = new Wall(handler);
-            wall.setLocation(location);
-            wall.setWall(pref.hWallShape);
-            wall.attach();
-            walls.add(wall);
-        }
-    }
-
-    private void initHoles() {
-        holes = new ArrayList<Hole>();
-        for (Vector3f centre : pref.holeCentres) {
-            Hole hole = new Hole(handler);
-            hole.setLocation(centre);
-            hole.setRadius(pref.getUnit() * 0.5f);
-            hole.attach();
-            holes.add(hole);
-        }
-    }
-
-    private void initEnd() {
-        end = new EndPoint(handler);
-        end.setLocation(pref.endPosition);
-        end.setRadius(pref.getUnit() * 0.9f);
-        end.attach();
-    }
-
-    private void initBall() {
-        ball = new Ball(handler);
-        ball.setLocation(pref.ballPosition);
-        ball.setRadius(pref.ballRadius);
-        ball.attach();
-
-        if (pref.bugMe) {
-            Ball ball2 = new Ball(handler);
-            ball2.setLocation(pref.ballPosition.negate().add(new Vector3f(0, 0.4f, 0)));
-            ball2.setRadius(pref.ballRadius * 2);
-            ball2.attach();
-        }
-    }
-
-    private void finalise() {
-        this.setDisplayStatView(false);
-        this.setDisplayFps(false);
-    }
-
-    private void setupKeys() {
-        Key key = new Key(handler);
-        key.associateKey(inputManager);
-    }
-
-    @Override
-    public void simpleUpdate(float tpf) {
-        time += tpf;
-        cam.setLocation(new Vector3f(0, 2.5f, 0.3f));
-        cam.lookAt(board.getPhysicsLocation(), Vector3f.UNIT_Y);
-
-        if (end.collideWith(ball)) {
-            score.increaseScore(timeLeft);
-            score.reduceScore((int) time / 10);
-            pref.increaseLevel();
-            pref.init();
-            reset();
-            time = 0;
-        }
-
-        for (Hole hole : holes) {
-            if (hole.collideWith(ball)) {
-                score.reduceScore();
-                reset();
-            }
-        }
-        timeLeft = (pref.level * 30 - (int) time);
-        updateText();
-    }
-
-    private void updateText() {
-        timeLeft = (pref.level * 20 - (int) time);
-        if (timeLeft >= 0) {
-            bitmapText.setText("Level:  "
-                    + pref.level
-                    + "\t"
-                    + "Time Left:    "
-                    + timeLeft
-                    + "\t"
-                    + score.toString());
-        } else {
-            isLost = true;
-            bitmapText.setText("You lose! Press 'R' to restart. ");
-        }
-    }
-
-    public void initText() {
-        guiNode.detachAllChildren();
-        guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
-        bitmapText = new BitmapText(guiFont, false);
-        bitmapText.setSize(guiFont.getCharSet().getRenderedSize());
-        updateText();
-        bitmapText.setLocalTranslation(300, bitmapText.getLineHeight(), 0);
-        guiNode.attachChild(bitmapText);
-    }
-
-    public void reset() {
-        bulletAppState.getPhysicsSpace().remove(board);
-        boardNode.removeFromParent();
-
-        time = 0;
-        isLost = false;
-
-        initBoard();
-        initWall();
-        initHoles();
-        initEnd();
-
-        ball.setPhysicsLocation(pref.ballPosition);
-        ball.zeroVelocity();
-    }
-}

src/Game/Pref.java

 import java.util.ArrayList;
 
 /**
- * Generates (almost) every information the game needs to run.
+ * Generates (almost) every information the game needs.
  */
 public class Pref {
     protected int level;
     private void generateHoles() {
         holeCentres = new ArrayList<Vector3f>();
         for (int i = 0; i < (5 - level); i++) {
-            Vector3f vector3f;
+            Vector3f centre;
+
             do {
-                vector3f = new Vector3f(dfs.randomX(), 0, dfs.randomY());
-            } while (
-                    equalVector(ballPosition, vector3f)
-                            || equalVector(endPosition, vector3f)
-                            || holeCentres.contains(vector3f));
+                centre = new Vector3f(dfs.randomX(), 0, dfs.randomY());
+            } while (equalVector(ballPosition, centre) ||
+                    equalVector(endPosition, centre) ||
+                    holeCentres.contains(centre));
 
-            holeCentres.add(vector3f);
+            holeCentres.add(centre);
         }
     }
 
     public void generateWalls() {
         vWallLocations = new ArrayList<Vector3f>();
         hWallLocations = new ArrayList<Vector3f>();
+
         do {
             dfs = new DFS(level);
-            dfs.carvePassagesFrom(0, 0);
+            dfs.visitFrom(0, 0);
         } while (dfs.containErrors());
+
         dfs.fill(vWallLocations, hWallLocations);
 
-        Vector3f vWallDimension = new Vector3f(boardHeight, 0.2f, dfs.getUnit());
-        Vector3f hWallDimension = new Vector3f(dfs.getUnit(), 0.2f, boardHeight);
+        Vector3f vWallDimension =
+                new Vector3f(boardHeight, 0.2f, dfs.getUnit());
+        Vector3f hWallDimension =
+                new Vector3f(dfs.getUnit(), 0.2f, boardHeight);
+
         vWallShape = new BoxCollisionShape(vWallDimension);
         hWallShape = new BoxCollisionShape(hWallDimension);
     }
      * @return True if two vectors are overlapping
      */
     public boolean equalVector(Vector3f vectorA, Vector3f vectorB) {
-        return Math.abs(vectorA.getX() - vectorB.getX()) < epsilon
-                && Math.abs(vectorB.getZ() - vectorB.getZ()) < epsilon;
+        return Math.abs(vectorA.getX() - vectorB.getX()) < epsilon &&
+                Math.abs(vectorB.getZ() - vectorB.getZ()) < epsilon;
     }
 
     public float getUnit() {
-                Yet Another 3D Java Game
+#	Yet Another 3D Java Game
+![image](java.gif)
 
-    --Contributors--
+## Contributors
 Meitian Huang   u4700480
+
 Zunyi Liu       u4499582
+
 Yiwei Xu        u4834608
 
 
-    --License--
-This program uses a game engine called jMonkeyEngine, which is completely
-open-source under the BSD license.
-For more information, see LICENSE.
-
-    --What Does It Do--
-A ball, rolling within a maze needs to get to their destination at the other
-end, while avoiding holes. When the ball falls into a hole it is returned to
-the beginning of the maze. The player cannot directly control the ball.
-Instead, the player must alter the angle of the maze floor, tilting it using
-the up, down, left and right arrow keys. The ball obeys the laws of physics
-and will roll due to gravitational pull and accelerate until it hits the wall.
-The ball will stop rolling when it hits the wall.
-
-    --How to Run--
+## What Does It Do
+
+> A ball, rolling within a maze needs to get to their destination at the other end, while avoiding holes. When the ball falls into a hole it is returned to
+the beginning of the maze. The player cannot directly control the ball. Instead, the player must alter the angle of the maze floor, tilting it using the up, down, left and right arrow keys. The ball obeys the laws of physics
+and will roll due to gravitational pull and accelerate until it hits the wall. The ball will stop rolling when it hits the wall.
+
+### Notes
+1. You may see more than one cyliner. The largest one is the end. 
+2. You may see more than one ball. Remember: your goal is to make the smallest ball fall into the end. 
+
+## How to Run
 The main class is under src/Game/Starter.java.
-The rest is left as an exercise for the reader.:D
+*The rest is left as an exercise for the reader.*
 
 
-    --Limitation--
-This program won't run on a computer without OpenGL support.
+## Requirements
+In order to run this program, you need to have at least:
+
+1. OpenGL 1.0
+2. Java 6
+3. Imagination!
+
+
+## License
+This program is under the BSD license. 
+
+This program uses a game engine called jMonkeyEngine <http://jmonkeyengine.org/>, which is completely
+open-source under the BSD license.
+
+For more information, see LICENSE.

src/Game/README.html

+<!doctype html>
+<html>
+<head>
+    <meta charset="utf-8">
+    <style>
+        h1,
+        h2,
+        h3,
+        h4,
+        h5,
+        h6,
+        p,
+        blockquote {
+            margin: 0;
+            padding: 0;
+        }
+
+        body {
+            font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", Arial, sans-serif;
+            font-size: 13px;
+            line-height: 18px;
+            color: #737373;
+            margin: 10px 10px 10px 20px;
+        }
+
+        a {
+            color: #0069d6;
+        }
+
+        a:hover {
+            color: #0050a3;
+            text-decoration: none;
+        }
+
+        a img {
+            border: none;
+        }
+
+        p {
+            margin-bottom: 9px;
+        }
+
+        h1,
+        h2,
+        h3,
+        h4,
+        h5,
+        h6 {
+            color: #404040;
+            line-height: 36px;
+        }
+
+        h1 {
+            margin-bottom: 18px;
+            font-size: 30px;
+        }
+
+        h2 {
+            font-size: 24px;
+        }
+
+        h3 {
+            font-size: 18px;
+        }
+
+        h4 {
+            font-size: 16px;
+        }
+
+        h5 {
+            font-size: 14px;
+        }
+
+        h6 {
+            font-size: 13px;
+        }
+
+        hr {
+            margin: 0 0 19px;
+            border: 0;
+            border-bottom: 1px solid #aaa;
+        }
+
+        blockquote {
+            padding: 13px 13px 21px 15px;
+            margin-bottom: 18px;
+            font-family: georgia, serif;
+            font-style: italic;
+        }
+
+        blockquote:before {
+            content: "\201C";
+            font-size: 40px;
+            margin-left: -10px;
+            font-family: georgia, serif;
+            color: #eee;
+        }
+
+        blockquote p {
+            font-size: 14px;
+            font-weight: 300;
+            line-height: 18px;
+            margin-bottom: 0;
+            font-style: italic;
+        }
+
+        code, pre {
+            padding: 0 3px 2px;
+            font-family: Monaco, Andale Mono, Courier New, monospace;
+            -webkit-border-radius: 3px;
+            -moz-border-radius: 3px;
+            border-radius: 3px;
+        }
+
+        code {
+            background-color: #fee9cc;
+            color: rgba(0, 0, 0, 0.75);
+            padding: 1px 3px;
+            font-size: 12px;
+        }
+
+        pre {
+            display: block;
+            padding: 14px;
+            margin: 0 0 18px;
+            line-height: 16px;
+            font-size: 11px;
+            border: 1px dashed #ccc;
+            border: 1px dashed rgba(0, 0, 0, 0.15);
+            -webkit-border-radius: 3px;
+            -moz-border-radius: 3px;
+            border-radius: 3px;
+            white-space: pre;
+            white-space: pre-wrap;
+            word-wrap: break-word;
+        }
+
+        pre code {
+            background-color: #fdfdfd;
+            color: #737373;
+            font-size: 11px;
+        }
+
+        @media screen and (min-width: 768px) {
+            body {
+                width: 748px;
+                margin: 10px auto;
+            }
+        }
+    </style>
+    <title>README.html</title>
+</head>
+<body>
+<h1>Yet Another 3D Java Game</h1>
+
+<p><img src="java.gif" alt="image"/></p>
+
+<h2>Contributors</h2>
+
+<p>Meitian Huang u4700480</p>
+
+<p>Zunyi Liu u4499582</p>
+
+<p>Yiwei Xu u4834608</p>
+
+<h2>What Does It Do</h2>
+
+<blockquote><p>A ball, rolling within a maze needs to get to their destination
+    at the other end, while avoiding holes. When the ball falls into a hole it
+    is returned to
+    the beginning of the maze. The player cannot directly control the ball.
+    Instead, the player must alter the angle of the maze floor, tilting it using
+    the up, down, left and right arrow keys. The ball obeys the laws of physics
+    and will roll due to gravitational pull and accelerate until it hits the
+    wall. The ball will stop rolling when it hits the wall.</p></blockquote>
+
+<h3>Notes</h3>
+
+<ol>
+    <li>You may see more than one cyliner. The largest one is the end.</li>
+    <li>You may see more than one ball. Remember: your goal is to make the
+        smallest ball fall into the end.
+    </li>
+</ol>
+
+
+<h2>How to Run</h2>
+
+<p>The main class is under src/Game/Starter.java.
+    <em>The rest is left as an exercise for the reader.</em></p>
+
+<h2>Requirements</h2>
+
+<p>In order to run this program, you need to have at least:</p>
+
+<ol>
+    <li>OpenGL 1.0</li>
+    <li>Java 6</li>
+    <li>Imagination!</li>
+</ol>
+
+
+<h2>License</h2>
+
+<p>This program is under the BSD license.</p>
+
+<p>This program uses a game engine called jMonkeyEngine <a
+        href="http://jmonkeyengine.org/">http://jmonkeyengine.org/</a>, which is
+    completely
+    open-source under the BSD license.</p>
+
+<p>For more information, see LICENSE.</p>
+</body>
+</html>

src/Game/RigidBody.java

     }
 
     /**
-     * Attaches this rigid body to the base.
-     */
-    public abstract void attach();
-
-    /**
      * Sets the location of the object.
      *
      * @param location The location to which the object is set.
     public void setLocation(Vector3f location) {
         this.location = location;
     }
+
+    /**
+     * Attaches this rigid body to the base.
+     */
+    public abstract void attach();
 }

src/Game/Score.java

     }
 
     /**
-     * Reduces the score by 1 and terminates the game if the score is less than 0.
+     * Reduces the score by 1 and terminates the game if the score is less
+     * than 0.
      */
     public void reduceScore() {
-        if ((--score) < 0) {
-            handler.loseGame();
+        if ((score -= 10) < 0) {
+            System.out.println("Less than zero");
+            handler.stopGame();
         }
     }
 
+    /**
+     * Reduces the score by n and terminates the game if the score is less
+     * than 0.
+     * @param n
+     */
     public void reduceScore(int n) {
         if ((score -= n) < 0) {
-            handler.loseGame();
+            handler.stopGame();
         }
     }
 

src/Game/Starter.java

 
 
         AppSettings settings = new AppSettings(true);
-        settings.setTitle("Maze");
+        settings.setTitle("Labyrinth");
 //        Uses whatever version of OpenGL to render.
         settings.setRenderer(AppSettings.LWJGL_OPENGL_ANY);
 //        Disables audio renderer...
         settings.setFullscreen(true);
         settings.setResolution(1280, 800);
 
-        Maze app = new Maze();
+        Labyrinth app = new Labyrinth();
         app.setSettings(settings);
         app.start();
     }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.