From 0a04160109c59dc4c257a8363a4098a45ba257aa Mon Sep 17 00:00:00 2001 From: Pacien TRAN-GIRARD Date: Mon, 9 May 2016 21:39:41 +0200 Subject: Refactor component --- src/ch/epfl/xblast/client/XBlastComponent.java | 206 ++++++++++++------------- 1 file changed, 98 insertions(+), 108 deletions(-) diff --git a/src/ch/epfl/xblast/client/XBlastComponent.java b/src/ch/epfl/xblast/client/XBlastComponent.java index ac9f223..cab6fde 100644 --- a/src/ch/epfl/xblast/client/XBlastComponent.java +++ b/src/ch/epfl/xblast/client/XBlastComponent.java @@ -1,143 +1,129 @@ package ch.epfl.xblast.client; +import ch.epfl.xblast.Cell; import ch.epfl.xblast.PlayerID; import javax.swing.*; import java.awt.*; +import java.awt.image.ImageObserver; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import java.util.stream.IntStream; /** + * The game graphical component. + * + * @author Pacien TRAN-GIRARD (261948) * @author Timothée FLOURE (257420) */ public final class XBlastComponent extends JComponent { - private static final int PREFERRED_WIDTH = 960; - private static final int PREFERRED_HEIGHT = 688; - private static final int BLOCK_WIDTH = 64; - private static final int BLOCK_HEIGHT = 48; - private static final int SCORE_IMAGE_WIDTH = 48; - private static final int SCORE_IMAGE_HEIGHT = 48; - private static final int TIME_LED_WIDTH = 16; - private static final int TIME_LED_HEIGHT = 16; - - private static final Font font = new Font("Arial", Font.BOLD, 25); - private static final int SCORES_TEXT_VERTICAL_POSITION = 659; - private static final int SCORES_P1_TEXT_HORIZONTAL_POSITION = 96; - private static final int SCORES_P2_TEXT_HORIZONTAL_POSITION = 240; - private static final int SCORES_P3_TEXT_HORIZONTAL_POSITION = 768; - private static final int SCORES_P4_TEXT_HORIZONTAL_POSITION = 912; - /** - * Displayed gameState. - */ - private GameState gamestate; + private static final ImageObserver IMG_OBSERVER = null; - /** - * Display a list of images on the given graphic context. - * - * @param g the graphic context - * @param images the given list of images, ordered in row-major order - */ - private void drawMap(Graphics2D g, List images) { - int x = 0; - int y = 0; + private static final Dimension CELL_DIMENSION = new Dimension(64, 48); + private static final Dimension SCORE_IMG_DIMENSION = new Dimension(48, 48); + private static final Dimension TIME_LED_DIMENSION = new Dimension(16, 16); + private static final Dimension PREFERRED_WINDOW_DIMENSION = frameDimension(); - for (Image img : images) { - if (x + BLOCK_WIDTH > PREFERRED_WIDTH) { - y += BLOCK_HEIGHT; // Or img.getHeight(null) ? - x = 0; - } + private static final List CELL_POSITIONS = buildCellGrid(CELL_DIMENSION); + private static final List SCORE_TXT_POSITIONS = buildScorePositionList(659); + private static final List SCORE_BG_POSITIONS = + buildLine(SCORE_IMG_DIMENSION, 20, new Point(0, CELL_DIMENSION.height * Cell.ROWS)); + private static final List TIME_LINE_POSITIONS = + buildLine(TIME_LED_DIMENSION, 60, new Point(0, CELL_DIMENSION.height * Cell.ROWS + SCORE_IMG_DIMENSION.height)); - if (img != null) - g.drawImage(img, x, y, null); + private static final Font TXT_FONT = new Font("Arial", Font.BOLD, 25); + private static final Color TXT_COLOR = Color.WHITE; - x += BLOCK_WIDTH; // Or img.getWidth(null) ? - } + private static Dimension frameDimension() { + return new Dimension( + CELL_DIMENSION.width * Cell.COLUMNS, + CELL_DIMENSION.height * Cell.ROWS + SCORE_IMG_DIMENSION.height + TIME_LED_DIMENSION.height); } - /** - * Compute the horizontal position of the player in px. - * - * @param player the given player - * @return the horizontal position in pixel - */ - private int playerXPosition(GameState.Player player) { return 4 * player.position().x() - 24; } + private static List buildCellGrid(Dimension elementDim) { + return Collections.unmodifiableList(Cell.ROW_MAJOR_ORDER.stream() + .map(c -> new Point(c.x() * elementDim.width, c.y() * elementDim.height)) + .collect(Collectors.toList())); + } - /** - * Compute the vertical position of the player in px. - * - * @param player the given player - * @return the vertical position in pixel - */ - private int playerYPosition(GameState.Player player) { return 3 * player.position().y() - 52; } + private static List buildLine(Dimension elementDim, int len, Point shift) { + return Collections.unmodifiableList(IntStream.range(0, len) + .mapToObj(x -> new Point(x * elementDim.width + shift.x, shift.y)) + .collect(Collectors.toList())); + } + + private static List buildScorePositionList(int vShift) { + return Arrays.asList( + new Point(96, vShift), + new Point(240, vShift), + new Point(768, vShift), + new Point(912, vShift)); + } + + private static void drawImage(Graphics2D g, Image img, Point pos) { + g.drawImage(img, pos.x, pos.y, IMG_OBSERVER); + } + + private static void drawGrid(Graphics2D g, List grid, List imgs) { + for (int i = 0; i < grid.size() && i < imgs.size(); ++i) + drawImage(g, imgs.get(i), grid.get(i)); + } + + private static Point playerPosition(GameState.Player p) { + return new Point( + 4 * p.position().x() - 24, + 3 * p.position().y() - 52); + } + + private GameState gameState; + private PlayerID playerID; /** * Draw the players on the graphic context. * - * @param g the graphic context + * @param g the graphic context * @param players the list of players to be displayed */ private void drawPlayers(Graphics2D g, List players) { - for (GameState.Player player : players) { - g.drawImage(player.image(), playerXPosition(player), playerYPosition(player), null); - } - } + // TODO: draw in preferred order - /** - * Draw the scores on the graphic context. - * - * @param g the graphic context - * @param scores the list of images composing the scores to be displayed - */ - private void drawScores(Graphics2D g, List scores) { - int x = 0; - int y = PREFERRED_HEIGHT - SCORE_IMAGE_HEIGHT - TIME_LED_HEIGHT; - for (Image img : scores) { - g.drawImage(img, x, y, null); - x += SCORE_IMAGE_WIDTH; - } + for (GameState.Player p : players) + drawImage(g, p.image(), playerPosition(p)); } /** - * Write the remaining lives of each player on the graphic context. + * Writes the remaining lives of each playerID on the graphic context. * - * @param g the graphic context + * @param g the graphic context * @param players list of players */ - private void writeScores(Graphics2D g,List players) { - g.setColor(Color.WHITE); - g.setFont(font); - - // Ugly !!!!! - g.drawString(Integer.toString(players.get(0).lives()), SCORES_P1_TEXT_HORIZONTAL_POSITION,SCORES_TEXT_VERTICAL_POSITION); - g.drawString(Integer.toString(players.get(1).lives()), SCORES_P2_TEXT_HORIZONTAL_POSITION,SCORES_TEXT_VERTICAL_POSITION); - g.drawString(Integer.toString(players.get(2).lives()), SCORES_P3_TEXT_HORIZONTAL_POSITION,SCORES_TEXT_VERTICAL_POSITION); - g.drawString(Integer.toString(players.get(3).lives()), SCORES_P4_TEXT_HORIZONTAL_POSITION,SCORES_TEXT_VERTICAL_POSITION); + private void writeScores(Graphics2D g, List players) { + g.setColor(TXT_COLOR); + g.setFont(TXT_FONT); + players.stream().forEach(p -> writeScore(g, p)); } - /** - * Draw the time "line" on the graphic context - * - * @param g the graphic context - * @param time the list of images composing the line - */ - private void drawTime(Graphics2D g, List time) { - int x = 0; - int y = PREFERRED_HEIGHT - TIME_LED_HEIGHT; - for (Image img : time) { - g.drawImage(img, x, y, null); - x += TIME_LED_WIDTH; - } + private void writeScore(Graphics2D g, GameState.Player p) { + String score = Integer.toString(p.lives()); + Point pos = SCORE_TXT_POSITIONS.get(p.id().ordinal()); + g.drawString(score, pos.x, pos.y); } /** - * Display the given GameState from the point of view of the given player. + * Display the given GameState from the point of view of the given playerID. * - * @param gameState GameState to be displayer - * @param player player related to the view + * @param gs GameState to be displayed + * @param pid playerID related to the view */ - public void setGameState(GameState gameState, PlayerID player) { - this.gamestate = gameState; + public void setGameState(GameState gs, PlayerID pid) { + this.gameState = gs; + this.playerID = pid; + repaint(); } @@ -148,7 +134,7 @@ public final class XBlastComponent extends JComponent { */ @Override public Dimension getPreferredSize() { - return new Dimension(PREFERRED_WIDTH,PREFERRED_HEIGHT); + return PREFERRED_WINDOW_DIMENSION; } /** @@ -158,14 +144,18 @@ public final class XBlastComponent extends JComponent { */ @Override protected void paintComponent(Graphics g0) { - if (this.gamestate != null) { - Graphics2D g = (Graphics2D) g0; - drawMap(g, this.gamestate.board()); - drawMap(g, this.gamestate.explosions()); - drawPlayers(g, this.gamestate.players()); - drawScores(g, this.gamestate.scores()); - writeScores(g, this.gamestate.players()); - drawTime(g, this.gamestate.ticks()); - }; + Graphics2D g = (Graphics2D) g0; + + if (Objects.isNull(this.gameState)) + return; + + drawGrid(g, CELL_POSITIONS, this.gameState.board()); + drawGrid(g, CELL_POSITIONS, this.gameState.explosions()); + drawGrid(g, SCORE_BG_POSITIONS, this.gameState.scores()); + drawGrid(g, TIME_LINE_POSITIONS, this.gameState.ticks()); + + drawPlayers(g, this.gameState.players()); + writeScores(g, this.gameState.players()); } + } -- cgit v1.2.3