-
Notifications
You must be signed in to change notification settings - Fork 0
/
NumberDisplayer.java
195 lines (168 loc) · 5.02 KB
/
NumberDisplayer.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
import greenfoot.Actor;
import greenfoot.GreenfootImage;
import java.util.LinkedList;
/**
* This class contains the utility methods to render scores. The image in
* this class aligns from the right (Drawing items from the right to the
* left.
*
* @author Team APCSA 2019
* @author Yijie Gui
* @author Andy Ge
* @since 2019-05-29 17:06
*/
@SuppressWarnings("WeakerAccess")
public class NumberDisplayer extends Actor
{
/** Image of the Numbers (0-9) */
private final GreenfootImage[] numberImages;
/** Image of the Dot (Eg. the "." in "12.4") */
private final GreenfootImage dotImage;
/** Max height in the numbers */
private final int maxHeight;
/** Current rendered width from the right to the left. */
private int currentRenderedWidth;
/**
* Construct a score displayer.
*/
public NumberDisplayer()
{
this(Images.SCORE_NUMBERS, Images.SCORE_DOT);
}
/**
* Construct a score displayer.
*
* @param numberImages Numbers
* @param dotImage Image of the dot.
*/
public NumberDisplayer(GreenfootImage[] numberImages, GreenfootImage dotImage)
{
this(numberImages, dotImage, 1);
}
/**
* Construct a score displayer.
*
* @param numberImages Numbers
* @param dotImage Image of the dot.
* @param scale Scale of those images.
*/
public NumberDisplayer(GreenfootImage[] numberImages, GreenfootImage dotImage, double scale)
{
this.numberImages = new GreenfootImage[10];
this.dotImage = new GreenfootImage(dotImage);
currentRenderedWidth = 0;
// Scale it
this.dotImage.scale((int) (dotImage.getWidth() * scale), (int) (dotImage.getHeight() * scale));
for (int i = 0; i < this.numberImages.length; i++)
{
GreenfootImage image = this.numberImages[i] = new GreenfootImage(numberImages[i]);
image.scale((int) (image.getWidth() * scale), (int) (image.getHeight() * scale));
}
// Calculate max height
int maxHeight = 0;
for (GreenfootImage image : numberImages)
{
maxHeight = Math.max(image.getHeight(), maxHeight);
}
this.maxHeight = maxHeight;
}
/**
* Initialize location and image.
*
* @param x X location
* @param y Y location
*/
protected void init(int x, int y)
{
// Create a base image
GreenfootImage image = new GreenfootImage(Constants.WIDTH, maxHeight);
setImage(image);
// Set location
setLocation(x, y);
}
/**
* Draw a number to the right.
*
* @param number Number
* @param digits How many digits to keep?
*/
public void drawNumber(double number, int digits)
{
// Get the decimal half to digits
double decimal = (number % 1) * Math.pow(10, digits);
// Draw the decimal half
drawNumber((int) decimal);
// Draw dot
drawLetter(dotImage);
// Draw the integer half
drawNumber((int) number);
}
/**
* Draw a integer to the right.
*
* @param number Integer
*/
public void drawNumber(int number)
{
// Get the digits in a stack
LinkedList<Integer> stack = toDigits(number);
// Draw them in reverse order
while (!stack.isEmpty())
{
drawLetter(numberImages[stack.pollLast()]);
}
}
/**
* Draw a letter to the right-most space.
* Precondition: letter.getHeight() <= maxHeight
*
* @param letter Letter image
*/
public void drawLetter(GreenfootImage letter)
{
// Calculate X and Y so that it is right aliened and centered vertically
int x = Constants.WIDTH - currentRenderedWidth - letter.getWidth();
int y = (int) ((maxHeight - letter.getHeight()) / 2.0);
// Draw it!
getImage().drawImage(letter, x, y);
// Add its width to the current rendered width
currentRenderedWidth += letter.getWidth();
}
/**
* Clear the image.
*/
public void clear()
{
getImage().clear();
currentRenderedWidth = 0;
}
/**
* Convert an integer to a list of digits.
*
* @param number Number
* @return Stack of digits.
*/
public static LinkedList<Integer> toDigits(int number)
{
// Get the digits in a stack
LinkedList<Integer> stack = new LinkedList<>();
if (number == 0) stack.push(0);
else while (number > 0)
{
stack.push(number % 10);
number /= 10;
}
return stack;
}
// ###################
// Getters and Setters
// ###################
public GreenfootImage[] getNumberImages()
{
return numberImages;
}
public int getMaxHeight()
{
return maxHeight;
}
}