summaryrefslogtreecommitdiff
path: root/src/ch/epfl/maze/graphics/GraphicComponent.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/ch/epfl/maze/graphics/GraphicComponent.java')
-rw-r--r--src/ch/epfl/maze/graphics/GraphicComponent.java432
1 files changed, 208 insertions, 224 deletions
diff --git a/src/ch/epfl/maze/graphics/GraphicComponent.java b/src/ch/epfl/maze/graphics/GraphicComponent.java
index 2321714..e49a542 100644
--- a/src/ch/epfl/maze/graphics/GraphicComponent.java
+++ b/src/ch/epfl/maze/graphics/GraphicComponent.java
@@ -1,237 +1,221 @@
1package ch.epfl.maze.graphics; 1package ch.epfl.maze.graphics;
2 2
3import java.awt.Graphics2D;
4import java.awt.geom.AffineTransform;
5import java.awt.image.BufferedImage;
6import java.awt.image.ImageObserver;
7
8import javax.swing.ImageIcon;
9
10import ch.epfl.maze.util.Action; 3import ch.epfl.maze.util.Action;
11import ch.epfl.maze.util.Direction; 4import ch.epfl.maze.util.Direction;
12import ch.epfl.maze.util.Vector2D; 5import ch.epfl.maze.util.Vector2D;
13 6
7import javax.swing.*;
8import java.awt.*;
9import java.awt.geom.AffineTransform;
10import java.awt.image.BufferedImage;
11import java.awt.image.ImageObserver;
12
14/** 13/**
15 * Graphic component of an animal that will be drawn by an {@link Animation}. 14 * Graphic component of an animal that will be drawn by an {@link Animation}.
16 *
17 */ 15 */
18 16
19public final class GraphicComponent { 17public final class GraphicComponent {
20 18
21 /* constants */ 19 /* constants */
22 public static final int MAXIMUM_FRAMES = 4; 20 public static final int MAXIMUM_FRAMES = 4;
23 public static final int SQUARE_SIZE = Display.SQUARE_SIZE; 21 public static final int SQUARE_SIZE = Display.SQUARE_SIZE;
24 22
25 /* drawing variables */ 23 /* drawing variables */
26 private final Vector2D mPosition; 24 private final Vector2D mPosition;
27 private final BufferedImage mImage; 25 private final BufferedImage mImage;
28 private Action mAction; 26 private Action mAction;
29 private boolean mRotate; 27 private boolean mRotate;
30 28
31 /** 29 /**
32 * Constructs a graphic component with the image of the animal, the position 30 * Constructs a graphic component with the image of the animal, the position
33 * at which the component needs to be drawn, and the corresponding action 31 * at which the component needs to be drawn, and the corresponding action
34 * that it needs to perform. 32 * that it needs to perform.
35 * 33 *
36 * @param image 34 * @param image Image of animal
37 * Image of animal 35 * @param position Position at which the image will be drawn
38 * @param position 36 * @param action Action that the component needs to perform
39 * Position at which the image will be drawn 37 */
40 * @param action 38
41 * Action that the component needs to perform 39 public GraphicComponent(BufferedImage image, Vector2D position, Action action) {
42 */ 40 // sanity checks
43 41 if (image == null) {
44 public GraphicComponent(BufferedImage image, Vector2D position, Action action) { 42 throw new IllegalArgumentException("BufferedImage cannot be null.");
45 // sanity checks 43 }
46 if (image == null) { 44 if (position == null) {
47 throw new IllegalArgumentException("BufferedImage cannot be null."); 45 throw new IllegalArgumentException("Position cannot be null.");
48 } 46 }
49 if (position == null) { 47 if (action == null) {
50 throw new IllegalArgumentException("Position cannot be null."); 48 action = new Action(Direction.NONE, false);
51 } 49 }
52 if (action == null) { 50
53 action = new Action(Direction.NONE, false); 51 // default values
54 } 52 mImage = image;
55 53 mPosition = position;
56 // default values 54 mRotate = true;
57 mImage = image; 55 mAction = action;
58 mPosition = position; 56 }
59 mRotate = true; 57
60 mAction = action; 58 /**
61 } 59 * Notifies the component that it will die between two squares.
62 60 */
63 /** 61
64 * Notifies the component that it will die between two squares. 62 public void willDieMoving() {
65 */ 63 mAction = new Action(mAction.getDirection(), mAction.isSuccessful(), true);
66 64 }
67 public void willDieMoving() { 65
68 mAction = new Action(mAction.getDirection(), mAction.isSuccessful(), true); 66 /**
69 } 67 * Asks the graphic component to paint itself on graphic environment, by
70 68 * performing a ratio of its action.
71 /** 69 *
72 * Asks the graphic component to paint itself on graphic environment, by 70 * @param ratio Ratio of the action to be performed
73 * performing a ratio of its action. 71 * @param g Graphic environment
74 * 72 * @param targetWindow Window on which the graphic is being drawn
75 * @param ratio 73 */
76 * Ratio of the action to be performed 74
77 * @param g 75 public void paint(float ratio, Graphics2D g, ImageObserver targetWindow) {
78 * Graphic environment 76 if (mAction.getDirection() == Direction.NONE) {
79 * @param targetWindow 77 renderStuck(g, targetWindow);
80 * Window on which the graphic is being drawn 78 } else {
81 */ 79 if (ratio > 0.5) {
82 80 if (!mAction.diesBetweenSquares() && !mAction.isSuccessful()) {
83 public void paint(float ratio, Graphics2D g, ImageObserver targetWindow) { 81 renderMove(1 - ratio, g, targetWindow, true);
84 if (mAction.getDirection() == Direction.NONE) { 82 } else if (!mAction.diesBetweenSquares()) {
85 renderStuck(g, targetWindow); 83 renderMove(ratio, g, targetWindow, false);
86 } else { 84 }
87 if (ratio > 0.5) { 85 } else {
88 if (!mAction.diesBetweenSquares() && !mAction.isSuccessful()) { 86 renderMove(ratio, g, targetWindow, false);
89 renderMove(1 - ratio, g, targetWindow, true); 87 }
90 } else if (!mAction.diesBetweenSquares()) { 88 }
91 renderMove(ratio, g, targetWindow, false); 89 }
92 } 90
93 } else { 91 /**
94 renderMove(ratio, g, targetWindow, false); 92 * Draws the moving component on graphics environment and target window.
95 } 93 * <p>
96 } 94 * The function draws the animal at {@code (position + ratio*heading)}.
97 } 95 *
98 96 * @param ratio Ratio of action performed by animation
99 /** 97 * @param g Graphic environment
100 * Draws the moving component on graphics environment and target window. 98 * @param targetWindow Frame display
101 * <p> 99 * @param buzz Buzzes the animal, used when he has just hit a wall
102 * The function draws the animal at {@code (position + ratio*heading)}. 100 */
103 * 101
104 * @param ratio 102 private void renderMove(float ratio, Graphics2D g, ImageObserver targetWindow, boolean buzz) {
105 * Ratio of action performed by animation 103 // transforms direction into vector
106 * @param g 104 Vector2D heading = mAction.getDirection().toVector().mul(SQUARE_SIZE);
107 * Graphic environment 105 Vector2D normalized = heading.normalize();
108 * @param targetWindow 106
109 * Frame display 107 // loads the correct frame
110 * @param buzz 108 BufferedImage img = cropImage(ratio, mAction.getDirection());
111 * Buzzes the animal, used when he has just hit a wall 109
112 */ 110 AffineTransform reset = new AffineTransform();
113 111
114 private void renderMove(float ratio, Graphics2D g, ImageObserver targetWindow, boolean buzz) { 112 // applies translation
115 // transforms direction into vector 113 double newX = (mPosition.getX() + ratio * heading.getX());
116 Vector2D heading = mAction.getDirection().toVector().mul(SQUARE_SIZE); 114 double newY = (mPosition.getY() + ratio * heading.getY());
117 Vector2D normalized = heading.normalize(); 115 reset.translate(newX, newY);
118 116
119 // loads the correct frame 117 // applies rotation
120 BufferedImage img = cropImage(ratio, mAction.getDirection()); 118 double rotation = 0;
121 119 if (buzz) {
122 AffineTransform reset = new AffineTransform(); 120 rotation = -(Math.PI / 6.0) * Math.sin((60 * ratio) / Math.PI);
123 121 }
124 // applies translation 122 if (mRotate) {
125 double newX = (mPosition.getX() + ratio * heading.getX()); 123 rotation += Math.atan2(normalized.getY(), normalized.getX()) - Math.PI / 2;
126 double newY = (mPosition.getY() + ratio * heading.getY()); 124 }
127 reset.translate(newX, newY); 125 reset.rotate(rotation, SQUARE_SIZE / 2, SQUARE_SIZE / 2);
128 126
129 // applies rotation 127 // transforms and draws image
130 double rotation = 0; 128 g.setTransform(reset);
131 if (buzz) { 129 g.drawImage(img, 0, 0, targetWindow);
132 rotation = -(Math.PI / 6.0) * Math.sin((60 * ratio) / Math.PI); 130
133 } 131 // inverts transformations
134 if (mRotate) {