diff options
-rw-r--r-- | src/ch/epfl/xblast/client/XBlastComponent.java | 206 |
1 files 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 @@ | |||
1 | package ch.epfl.xblast.client; | 1 | package ch.epfl.xblast.client; |
2 | 2 | ||
3 | import ch.epfl.xblast.Cell; | ||
3 | import ch.epfl.xblast.PlayerID; | 4 | import ch.epfl.xblast.PlayerID; |
4 | 5 | ||
5 | import javax.swing.*; | 6 | import javax.swing.*; |
6 | import java.awt.*; | 7 | import java.awt.*; |
8 | import java.awt.image.ImageObserver; | ||
9 | import java.util.Arrays; | ||
10 | import java.util.Collections; | ||
7 | import java.util.List; | 11 | import java.util.List; |
12 | import java.util.Objects; | ||
13 | import java.util.stream.Collectors; | ||
14 | import java.util.stream.IntStream; | ||
8 | 15 | ||
9 | /** | 16 | /** |
17 | * The game graphical component. | ||
18 | * | ||
19 | * @author Pacien TRAN-GIRARD (261948) | ||
10 | * @author Timothée FLOURE (257420) | 20 | * @author Timothée FLOURE (257420) |
11 | */ | 21 | */ |
12 | public final class XBlastComponent extends JComponent { | 22 | public final class XBlastComponent extends JComponent { |
13 | private static final int PREFERRED_WIDTH = 960; | ||
14 | private static final int PREFERRED_HEIGHT = 688; | ||
15 | private static final int BLOCK_WIDTH = 64; | ||
16 | private static final int BLOCK_HEIGHT = 48; | ||
17 | private static final int SCORE_IMAGE_WIDTH = 48; | ||
18 | private static final int SCORE_IMAGE_HEIGHT = 48; | ||
19 | private static final int TIME_LED_WIDTH = 16; | ||
20 | private static final int TIME_LED_HEIGHT = 16; | ||
21 | |||
22 | private static final Font font = new Font("Arial", Font.BOLD, 25); | ||
23 | private static final int SCORES_TEXT_VERTICAL_POSITION = 659; | ||
24 | private static final int SCORES_P1_TEXT_HORIZONTAL_POSITION = 96; | ||
25 | private static final int SCORES_P2_TEXT_HORIZONTAL_POSITION = 240; | ||
26 | private static final int SCORES_P3_TEXT_HORIZONTAL_POSITION = 768; | ||
27 | private static final int SCORES_P4_TEXT_HORIZONTAL_POSITION = 912; | ||
28 | 23 | ||
29 | /** | 24 | private static final ImageObserver IMG_OBSERVER = null; |
30 | * Displayed gameState. | ||
31 | */ | ||
32 | private GameState gamestate; | ||
33 | 25 | ||
34 | /** | 26 | private static final Dimension CELL_DIMENSION = new Dimension(64, 48); |
35 | * Display a list of images on the given graphic context. | 27 | private static final Dimension SCORE_IMG_DIMENSION = new Dimension(48, 48); |
36 | * | 28 | private static final Dimension TIME_LED_DIMENSION = new Dimension(16, 16); |
37 | * @param g the graphic context | 29 | private static final Dimension PREFERRED_WINDOW_DIMENSION = frameDimension(); |
38 | * @param images the given list of images, ordered in row-major order | ||
39 | */ | ||
40 | private void drawMap(Graphics2D g, List<Image> images) { | ||
41 | int x = 0; | ||
42 | int y = 0; | ||
43 | 30 | ||
44 | for (Image img : images) { | 31 | private static final List<Point> CELL_POSITIONS = buildCellGrid(CELL_DIMENSION); |
45 | if (x + BLOCK_WIDTH > PREFERRED_WIDTH) { | 32 | private static final List<Point> SCORE_TXT_POSITIONS = buildScorePositionList(659); |
46 | y += BLOCK_HEIGHT; // Or img.getHeight(null) ? | 33 | private static final List<Point> SCORE_BG_POSITIONS = |
47 | x = 0; | 34 | buildLine(SCORE_IMG_DIMENSION, 20, new Point(0, CELL_DIMENSION.height * Cell.ROWS)); |
48 | } | 35 | private static final List<Point> TIME_LINE_POSITIONS = |
36 | buildLine(TIME_LED_DIMENSION, 60, new Point(0, CELL_DIMENSION.height * Cell.ROWS + SCORE_IMG_DIMENSION.height)); | ||
49 | 37 | ||
50 | if (img != null) | 38 | private static final Font TXT_FONT = new Font("Arial", Font.BOLD, 25); |
51 | g.drawImage(img, x, y, null); | 39 | private static final Color TXT_COLOR = Color.WHITE; |
52 | 40 | ||
53 | x += BLOCK_WIDTH; // Or img.getWidth(null) ? | 41 | private static Dimension frameDimension() { |
54 | } | 42 | return new Dimension( |
43 | CELL_DIMENSION.width * Cell.COLUMNS, | ||
44 | CELL_DIMENSION.height * Cell.ROWS + SCORE_IMG_DIMENSION.height + TIME_LED_DIMENSION.height); | ||
55 | } | 45 | } |
56 | 46 | ||
57 | /** | 47 | private static List<Point> buildCellGrid(Dimension elementDim) { |
58 | * Compute the horizontal position of the player in px. | 48 | return Collections.unmodifiableList(Cell.ROW_MAJOR_ORDER.stream() |
59 | * | 49 | .map(c -> new Point(c.x() * elementDim.width, c.y() * elementDim.height)) |
60 | * @param player the given player | 50 | .collect(Collectors.toList())); |
61 | * @return the horizontal position in pixel | 51 | } |
62 | */ | ||
63 | private int playerXPosition(GameState.Player player) { return 4 * player.position().x() - 24; } | ||
64 | 52 | ||
65 | /** | 53 | private static List<Point> buildLine(Dimension elementDim, int len, Point shift) { |
66 | * Compute the vertical position of the player in px. | 54 | return Collections.unmodifiableList(IntStream.range(0, len) |
67 | * | 55 | .mapToObj(x -> new Point(x * elementDim.width + shift.x, shift.y)) |
68 | * @param player the given player | 56 | .collect(Collectors.toList())); |
69 | * @return the vertical position in pixel | 57 | } |
70 | */ | 58 | |
71 | private int playerYPosition(GameState.Player player) { return 3 * player.position().y() - 52; } | 59 | private static List<Point> buildScorePositionList(int vShift) { |
60 | return Arrays.asList( | ||
61 | new Point(96, vShift), | ||
62 | new Point(240, vShift), | ||
63 | new Point(768, vShift), | ||
64 | new Point(912, vShift)); | ||
65 | } | ||
66 | |||
67 | private static void drawImage(Graphics2D g, Image img, Point pos) { | ||
68 | g.drawImage(img, pos.x, pos.y, IMG_OBSERVER); | ||
69 | } | ||
70 | |||
71 | private static void drawGrid(Graphics2D g, List<Point> grid, List<Image> imgs) { | ||
72 | for (int i = 0; i < grid.size() && i < imgs.size(); ++i) | ||
73 | drawImage(g, imgs.get(i), grid.get(i)); | ||
74 | } | ||
75 | |||
76 | private static Point playerPosition(GameState.Player p) { | ||
77 | return new Point( | ||
78 | 4 * p.position().x() - 24, | ||
79 | 3 * p.position().y() - 52); | ||
80 | } | ||
81 | |||
82 | private GameState gameState; | ||
83 | private PlayerID playerID; | ||
72 | 84 | ||
73 | /** | 85 | /** |
74 | * Draw the players on the graphic context. | 86 | * Draw the players on the graphic context. |
75 | * | 87 | * |
76 | * @param g the graphic context | 88 | * @param g the graphic context |
77 | * @param players the list of players to be displayed | 89 | * @param players the list of players to be displayed |
78 | */ | 90 | */ |
79 | private void drawPlayers(Graphics2D g, List<GameState.Player> players) { | 91 | private void drawPlayers(Graphics2D g, List<GameState.Player> players) { |
80 | for (GameState.Player player : players) { | 92 | // TODO: draw in preferred order |
81 | g.drawImage(player.image(), playerXPosition(player), playerYPosition(player), null); | ||
82 | } | ||
83 | } | ||
84 | 93 | ||
85 | /** | 94 | for (GameState.Player p : players) |
86 | * Draw the scores on the graphic context. | 95 | drawImage(g, p.image(), playerPosition(p)); |
87 | * | ||
88 | * @param g the graphic context | ||
89 | * @param scores the list of images composing the scores to be displayed | ||
90 | */ | ||
91 | private void drawScores(Graphics2D g, List<Image> scores) { | ||
92 | int x = 0; | ||
93 | int y = PREFERRED_HEIGHT - SCORE_IMAGE_HEIGHT - TIME_LED_HEIGHT; | ||
94 | for (Image img : scores) { | ||
95 | g.drawImage(img, x, y, null); | ||
96 | x += SCORE_IMAGE_WIDTH; | ||
97 | } | ||
98 | } | 96 | } |
99 | 97 | ||
100 | /** | 98 | /** |
101 | * Write the remaining lives of each player on the graphic context. | 99 | * Writes the remaining lives of each playerID on the graphic context. |
102 | * | 100 | * |
103 | * @param g the graphic context | 101 | * @param g the graphic context |
104 | * @param players list of players | 102 | * @param players list of players |
105 | */ | 103 | */ |
106 | private void writeScores(Graphics2D g,List<GameState.Player> players) { | 104 | private void writeScores(Graphics2D g, List<GameState.Player> players) { |
107 | g.setColor(Color.WHITE); | 105 | g.setColor(TXT_COLOR); |
108 | g.setFont(font); | 106 | g.setFont(TXT_FONT); |
109 | |||
110 | // Ugly !!!!! | ||
111 | g.drawString(Integer.toString(players.get(0).lives()), SCORES_P1_TEXT_HORIZONTAL_POSITION,SCORES_TEXT_VERTICAL_POSITION); | ||
112 | g.drawString(Integer.toString(players.get(1).lives()), SCORES_P2_TEXT_HORIZONTAL_POSITION,SCORES_TEXT_VERTICAL_POSITION); | ||
113 | g.drawString(Integer.toString(players.get(2).lives()), SCORES_P3_TEXT_HORIZONTAL_POSITION,SCORES_TEXT_VERTICAL_POSITION); | ||
114 | g.drawString(Integer.toString(players.get(3).lives()), SCORES_P4_TEXT_HORIZONTAL_POSITION,SCORES_TEXT_VERTICAL_POSITION); | ||
115 | 107 | ||
108 | players.stream().forEach(p -> writeScore(g, p)); | ||
116 | } | 109 | } |
117 | 110 | ||
118 | /** | 111 | private void writeScore(Graphics2D g, GameState.Player p) { |
119 | * Draw the time "line" on the graphic context | 112 | String score = Integer.toString(p.lives()); |
120 | * | 113 | Point pos = SCORE_TXT_POSITIONS.get(p.id().ordinal()); |
121 | * @param g the graphic context | 114 | g.drawString(score, pos.x, pos.y); |
122 | * @param time the list of images composing the line | ||
123 | */ | ||
124 | private void drawTime(Graphics2D g, List<Image> time) { | ||
125 | int x = 0; | ||
126 | int y = PREFERRED_HEIGHT - TIME_LED_HEIGHT; | ||
127 | for (Image img : time) { | ||
128 | g.drawImage(img, x, y, null); | ||
129 | x += TIME_LED_WIDTH; | ||
130 | } | ||
131 | } | 115 | } |
132 | 116 | ||
133 | /** | 117 | /** |
134 | * Display the given GameState from the point of view of the given player. | 118 | * Display the given GameState from the point of view of the given playerID. |
135 | * | 119 | * |
136 | * @param gameState GameState to be displayer | 120 | * @param gs GameState to be displaye |