OOP-Projects-Java

Log | Files | Refs | README

Board.java (8705B)


      1 package game;
      2 
      3 import java.awt.Color;
      4 
      5 import java.awt.Dimension;
      6 import java.awt.Font;
      7 import java.awt.Graphics;
      8 import java.util.ArrayList;
      9 
     10 import javax.swing.BorderFactory;
     11 import javax.swing.JPanel;
     12 
     13 import blocks.Tile;
     14 import blocks.Tileable;
     15 import blocks.Poly;
     16 
     17 public class Board extends JPanel {
     18 	// size of window
     19 	private final Dimension size = new Dimension(490, 788);
     20 
     21 	private final Color backgroundColor = Color.DARK_GRAY;
     22 
     23 	// size of each individual tile
     24 	private final int tileSize = 25;
     25 
     26 	private int score;
     27 
     28 	private Tileable[][] grid;
     29 
     30 	private ArrayList<Poly> polys = new ArrayList<Poly>();
     31 
     32 	private boolean polyFalling;
     33 	
     34 	
     35 	/**
     36 	 * Constructs board.
     37 	 * Calculates the size of the grid based of the size of the window.
     38 	 */
     39 	public Board() {
     40 		grid = new Tileable[Math.abs(size.width / tileSize)][Math.abs(size.height / tileSize)];
     41 		setBorder(BorderFactory.createLineBorder(Color.black));
     42 		polyFalling = false;
     43 		score = 0;
     44 		fillGrid();
     45 	}
     46 
     47 	/**
     48 	 * Fills the grid with unoccupied Tiles.
     49 	 */
     50 	public void fillGrid() {
     51 		for (int x = 0; x < grid[0].length; x++) {
     52 			for (int y = 0; y < grid.length; y++) {
     53 				grid[y][x] = new Tile(false);
     54 			}
     55 		}
     56 	}
     57 
     58 	/**
     59 	 * Detects full rows. Then calls on ClearRow and fall which together 
     60 	 * makes sure full rows are handled correctly.
     61 	 */
     62 	public void detectFullRow() {
     63 		for (int row = 0; row < grid[0].length; row++) {
     64 			for (int col = 0; col < grid.length; col++) {
     65 				if (!(grid[col][row].isOccupied())) {
     66 					break;
     67 				}
     68 				if (col == grid.length - 1) {
     69 					score += 10;
     70 					clearRow(row);
     71 					fall(row);
     72 				}
     73 			}
     74 		}
     75 	}
     76 	
     77 	/**
     78 	 * Getter for score.
     79 	 * @return current score.
     80 	 */
     81 	public int getScore() {
     82 		return score;
     83 	}
     84 	
     85 	/**
     86 	 * Sets all Tiles on a given row to be unoccupied.
     87 	 * @param rowNumber
     88 	 */
     89 	private void clearRow(int rowNumber) {
     90 		for (int col = 0; col < grid.length; col++) {
     91 			grid[col][rowNumber].setOccupied(false);
     92 			grid[col][rowNumber].setColor(backgroundColor);
     93 		}
     94 	}
     95 
     96 	/**
     97 	 * increase score by given amount.
     98 	 * @param amount
     99 	 */
    100 	public void givePoints(int amount) {
    101 		score += amount;
    102 	}
    103 
    104 	/**
    105 	 * Returns the size of the window.
    106 	 * @return size.
    107 	 */
    108 	public Dimension getSize() {
    109 		return this.size;
    110 	}
    111 
    112 	/**
    113 	 * Used for the graphical components of the game.
    114 	 * Draws all components of the board.
    115 	 */
    116 	public void paintComponent(Graphics g) {
    117 		super.paintComponent(g);
    118 		g.setColor(Color.gray);
    119 		draw(g);
    120 	}
    121 	
    122 	/**
    123 	 * Move a Poly in given direction
    124 	 * @param poly the poly to move
    125 	 * @param x movement in X direction.
    126 	 * @param y movement in Y direction.
    127 	 * @return return whether movement was carried through or not.
    128 	 */
    129 	public boolean move(Poly poly, int x, int y) {
    130 		if (isLegal(poly, x, y)) {
    131 			poly.move(x, y);
    132 			return true;
    133 		}
    134 		return false;
    135 	}
    136 
    137 	/**
    138 	 * Checks if a movement, or current position of poly is allowed.
    139 	 * @param poly the poly to check.
    140 	 * @param x offset in X direction.
    141 	 * @param y offset in Y direction.
    142 	 * @return boolean movement legal or not.
    143 	 */
    144 	public boolean isLegal(Poly poly, int x, int y) {
    145 		int[][] shape = poly.getShape();
    146 		int[] position = poly.getPos();
    147 
    148 		// iterate over every "tile" in poly shape
    149 		for (int i = 0; i < shape.length; i++) {
    150 			for (int j = 0; j < shape[0].length; j++) {
    151 				int realX = position[0] + j;
    152 				int realY = position[1] + i;
    153 				if (shape[i][j] == 1) {
    154 
    155 					// check X direction
    156 					if (realX + x >= grid.length || realX + x < 0) {
    157 						return false;
    158 					}
    159 					if (grid[realX + x][realY].isOccupied()) {
    160 						return false;
    161 					}
    162 
    163 					// check y direction
    164 					if (realY + y >= grid[0].length - 1) {
    165 						return false;
    166 					}
    167 					if (grid[realX][realY + y].isOccupied()) {
    168 						return false;
    169 					}
    170 				}
    171 			}
    172 		}
    173 
    174 		return true;
    175 	}
    176 
    177 	/**
    178 	 * Returns the currently falling poly, if any.
    179 	 * @return falling poly.
    180 	 */
    181 	public Poly getFallingPoly() {
    182 		if (!(polys.isEmpty())) {
    183 			return polys.get(polys.size() - 1);
    184 		}
    185 		return null;
    186 	}
    187 
    188 	/**
    189 	 * Converts a poly in to Tiles at its current position.
    190 	 * After conversion the Poly is no longer controllable.
    191 	 * @param poly the poly to convert.
    192 	 */
    193 	private void freeze(Poly poly) {
    194 		int[][] shape = poly.getShape();
    195 		int[] position = poly.getPos();
    196 		for (int i = 0; i < shape.length; i++) {
    197 			for (int j = 0; j < shape[0].length; j++) {
    198 				if (shape[i][j] == 1) {
    199 					grid[position[0] + j][position[1] + i] = new Tile(poly.getColor());
    200 				}
    201 			}
    202 		}
    203 		polyFalling = false;
    204 		polys.remove(poly);
    205 	}
    206 
    207 	/**
    208 	 * Is there a Poly falling currently.
    209 	 * @return is there a falling poly.
    210 	 */
    211 	public boolean isFalling() {
    212 		return polyFalling;
    213 	}
    214 
    215 	/**
    216 	 * Moves a given Poly one step down, for as long as possible.
    217 	 * When movement is no longer possible, freeze it into position.
    218 	 * @param poly to move.
    219 	 */
    220 	public void fall(Poly poly) {
    221 		polyFalling = true;
    222 		if (move(poly, 0, 1)) {
    223 			return;
    224 		} else {
    225 			freeze(poly);
    226 		}
    227 	}
    228 	
    229 	/**
    230 	 * Move given row down one number in grid.
    231 	 * @param row the row number to move downwards.
    232 	 */
    233 	public void fall(int row) {
    234 		for (int j = row; j > 0; j--) {
    235 			for (int i = grid.length - 1; i >= 0; i--) {
    236 				grid[i][j] = grid[i][j - 1];
    237 			}
    238 		}
    239 	}
    240 
    241 	/**
    242 	 * Moves a Poly to its lowest possible position and freezes it.
    243 	 * @param poly
    244 	 */
    245 	public void instaFall(Poly poly) {
    246 		polyFalling = true;
    247 		boolean result = true;
    248 		do {
    249 			result = move(poly, 0, 1);
    250 		} while (result);
    251 		freeze(poly);
    252 	}
    253 	
    254 	/**
    255 	 * Has the user lost.
    256 	 * @return whether the user has lost or not.
    257 	 */
    258 	public boolean hasLost() {
    259 		for (int i = 0; i < grid.length; i++) {
    260 			if (grid[i][0].isOccupied()) {
    261 				return true;
    262 			}
    263 		}
    264 		return false;
    265 	}
    266 
    267 	/**
    268 	 * Add a new poly to the board.
    269 	 * @param poly
    270 	 */
    271 	public void addPoly(Poly poly) {
    272 		polys.add(poly);
    273 		polyFalling = true;
    274 	}
    275 
    276 	/**
    277 	 * Get the spawnpoint for new Polys.
    278 	 * @return coordinates of spawnpoint.
    279 	 */
    280 	public int[] getPrefferedSpawn() {
    281 		int[] spawn = { grid.length / 2, 0 };
    282 		return spawn;
    283 	}
    284 
    285 	/**
    286 	 * Turns the entire board into the desired background color.
    287 	 * @param g Java graphics.
    288 	 */
    289 	private void clearBoard(Graphics g) {
    290 		g.setColor(backgroundColor);
    291 		g.fillRect(0, 0, size.width, size.height);
    292 	}
    293 
    294 	/**
    295 	 * Draw all elements of the board that are to be displayed.
    296 	 * @param g Java graphics.
    297 	 */
    298 	public void draw(Graphics g) {
    299 		clearBoard(g);
    300 		
    301 		// generate grid lines
    302 		drawGrid(g);
    303 		
    304 		// draw guidelines
    305 		drawPolyGuide(g);
    306 		
    307 		// draw polys
    308 		drawPoly(g);
    309 		
    310 		// draw tiles
    311 		drawTiles(g);
    312 		
    313 		// show score
    314 		drawScore(g);
    315 	}
    316 
    317 	/**
    318 	 * Draws the falling poly(s).
    319 	 * @param g
    320 	 */
    321 	private void drawPoly(Graphics g) {
    322 		// draw polys
    323 		if (polys.size() > 0) {
    324 			for (Poly poly : polys) {
    325 				g.setColor(poly.getColor());
    326 				int[][] shape = poly.getShape();
    327 
    328 				for (int i = 0; i < shape.length; i++) {
    329 					for (int j = 0; j < shape[0].length; j++) {
    330 						if (shape[i][j] == 1) {
    331 							g.fillRect(poly.getPos()[0] * tileSize + (j * tileSize),
    332 									poly.getPos()[1] * tileSize + (i * tileSize), tileSize, tileSize);
    333 
    334 						}
    335 					}
    336 				}
    337 			}
    338 		}
    339 	}
    340 
    341 	/**
    342 	 * Draws all the Tiles.
    343 	 * @param g
    344 	 */
    345 	private void drawTiles(Graphics g) {
    346 		for (int x = 0; x < grid[0].length; x++) {
    347 			for (int y = 0; y < grid.length; y++) {
    348 				if (grid[y][x].isOccupied()) {
    349 					g.setColor(grid[y][x].getColor());
    350 					g.fillRect(y * tileSize, x * tileSize, tileSize, tileSize);
    351 				}
    352 			}
    353 		}
    354 	}
    355 
    356 	/**
    357 	 * Draws the guidelines that show where the falling Poly is going to land.
    358 	 * @param g
    359 	 */
    360 	private void drawPolyGuide(Graphics g) {
    361 		g.setColor(Color.white);
    362 		if (getFallingPoly() != null) {
    363 			Poly poly = getFallingPoly();
    364 			int[][] shape = poly.getShape();
    365 			g.drawLine(poly.getPos()[0] * tileSize + (shape[0].length * tileSize), 0,
    366 					poly.getPos()[0] * tileSize + (shape[0].length * tileSize), size.height);
    367 			g.drawLine(poly.getPos()[0] * tileSize, 0, poly.getPos()[0] * tileSize, size.height);
    368 		}
    369 	}
    370 
    371 	/**
    372 	 * Displays the score at the top left of the window.
    373 	 * @param g
    374 	 */
    375 	private void drawScore(Graphics g) {
    376 		// show score
    377 		g.setColor(Color.white);
    378 		String scoreText = "Score: " + String.valueOf(score);
    379 		g.setFont(new Font("Helvetica", Font.PLAIN, tileSize));
    380 		g.drawString(scoreText, tileSize, g.getFontMetrics().getHeight());
    381 	}
    382 
    383 	/**
    384 	 * Draws the gridlines representing the board.
    385 	 * @param g
    386 	 */
    387 	private void drawGrid(Graphics g) {
    388 		g.setColor(Color.gray);
    389 
    390 		for (int x = 0; x < grid.length; x++) {
    391 			for (int y = 0; y < grid[0].length; y++) {
    392 				//draw x lines
    393 				g.drawLine(x * tileSize, 0, x * tileSize, grid[0].length * tileSize);
    394 				//draw y lines
    395 				g.drawLine(0, y * tileSize, grid[1].length * tileSize, y * tileSize);
    396 			}
    397 		}
    398 	}
    399 }