-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGame.java
More file actions
232 lines (180 loc) · 7.47 KB
/
Game.java
File metadata and controls
232 lines (180 loc) · 7.47 KB
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
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
/**
* Game is where setup occurs. The idea of creating a game class is that for different screens or setups, we will have
* different games which use different things. This class ensures that not just one monitor can run this program.
*/
public class Game
{
private final Robot ROBOT = new Robot();
private int topOfDino;
private int rightOfDino;
private int bottomOfDino;
private int topOfRetry;
/**
* Our constructor takes in one boolean to see if we need to set up or not. If it does need to set up, it will run the
* setup method. If it doesn't, it will look to the PresetValues class and get values from there.
* @param calibrate If we need to set up or not
* @throws AWTException Because we use setup()
* @throws InterruptedException Because we use setup()
* // @throws IOException Because we use setup()
*/
public Game(boolean calibrate) throws AWTException, InterruptedException //, IOException
{
if (calibrate)
{
setup();
}
else
{
topOfDino = PresetValues.TOP_OF_DINO;
rightOfDino = PresetValues.RIGHT_OF_DINO;
bottomOfDino = PresetValues.BOTTOM_OF_DINO;
topOfRetry = PresetValues.TOP_OF_RETRY;
}
}
public int getBottomOfDino()
{
return bottomOfDino;
}
public int getRightOfDino()
{
return rightOfDino;
}
public int getTopOfDino()
{
return topOfDino;
}
public int getTopOfRetry()
{
return topOfRetry;
}
public int getGameHeight()
{
return bottomOfDino - topOfDino;
}
/**
* This takes a screenshot using the ROBOT.createScreenCapture method. We only need the width since x, y, and height
* are already defined in this class.
* @param width How wide do we want the capture to be
* @return A buffered image of the screen
* // @throws IOException Because of using saveImage sometimes
*/
public BufferedImage screenshot(int width) throws IOException
{
Rectangle screen = new Rectangle(rightOfDino, topOfDino, width, getGameHeight());
BufferedImage image = ROBOT.createScreenCapture(screen);
saveImage(image, "src/image.png");
return image;
}
/**
* Saves an image to a file.
* @param image A buffered image
* @param fileName A file somewhere accessible from the current location
* @throws IOException Since we use write
*/
private void saveImage(BufferedImage image, String fileName) throws IOException
{
File file = new File(fileName);
ImageIO.write(image, "png", file);
}
/**
* This checks to see if there is an obstacle in the picture. It sets the background color to be some color in at the
* top of the image and checks if there is any other colors in the image.
*
* @param image The image we want to process
* @return if there is an obstacle or not
*/
public boolean isObstacle(BufferedImage image)
{
// An obstacle will almost never be in this position
int background = image.getRGB(0, 0);
// We do 2 at a time to speed this process up. This is one of the most costly things we have to do, so anything
// that will cut corners is good.
// Go through the height (2 at a time)
for (int i = 0; i < image.getHeight(); i += 2)
{
// Go through the width (2 at a time)
for (int j = 0; j < image.getWidth(); j += 2)
{
if (image.getRGB(j, i) != background)
{
return true;
}
}
}
return false;
}
/**
* Setup writes to PresetValues.java and finds those values with help from the user.
* @throws InterruptedException from Thread.sleep()
*/
public void setup() throws InterruptedException
{
// Stores the string which we'll write
String presetValuesString = "public class PresetValues\n{\n";
Scanner scnr = new Scanner(System.in); // Need this to wait until the user is ready
// Give instructions
System.out.println("Setup will require the chrome dino game to be open. Once you have it open (chrome://dino),");
System.out.println("run til you die. Once you are ready hit enter.");
scnr.nextLine();
System.out.println("For every location it asks for, move your cursor there, alt + tab back to this page, and");
System.out.println("then hit enter. It will then record the mouse location. Do this for all locations. Hit enter");
System.out.println("to continue.");
scnr.nextLine();
// First we need the y position of the mouse at the top of the dino's head
System.out.println("Location: Top of the dino's head. Waiting for input to capture...");
scnr.nextLine();
topOfDino = getMousePosition().y;
presetValuesString += "\tpublic static final int TOP_OF_DINO = " + topOfDino + ";\n";
// Now we need to know the x position of the mouse at the rightmost part of the dino
System.out.println("Location: Rightmost part of the dino's head. Waiting for input to capture...");
scnr.nextLine();
rightOfDino = getMousePosition().x + 10; // The dino has an outline that can mess up our search for an obstacle so move it a little bit more to the right to be sure
presetValuesString +="\tpublic static final int RIGHT_OF_DINO = " + rightOfDino + ";\n";
// Now we need to know the y position of the moues at the bottom of the dino's head
System.out.println("Location: Bottom of the dino's head. Waiting for input to capture...");
scnr.nextLine();
bottomOfDino = getMousePosition().y;
presetValuesString += "\tpublic static final int BOTTOM_OF_DINO = " + bottomOfDino + ";\n";
// Now we need the y coordinate of the top of the retry button
System.out.println("Location: Top of the retry button. Waiting for input...");
scnr.nextLine();
topOfRetry = getMousePosition().y + 10;
presetValuesString += "\tpublic static final int TOP_OF_RETRY = " + topOfRetry + ";\n";
System.out.println("Hit enter to continue to the game...");
scnr.nextLine();
presetValuesString += "}";
createFile(presetValuesString, "src/PresetValues.java");
}
/**
* Writes a string s to a file with fileName in the project
* @param s The string we'll write
* @param fileName The file in the project we want to write to
*/
private void createFile(String s, String fileName)
{
try
{
FileWriter fileWriter = new FileWriter(fileName);
fileWriter.write(s);
fileWriter.close();
} catch (IOException e)
{
throw new RuntimeException(e);
}
}
/**
* Waits for input, then returns the mouse position
* @return Current mouse position
*/
private Point getMousePosition()
{
return MouseInfo.getPointerInfo().getLocation();
}
}