I am trying to create an Asteroids-game, but I am already struggling at the very beginning: I want to create a countdown before the game starts. To do that, I'm using a timer which starts when pressing the button "start" and which (should) load a BufferedImage
every second, then display it on a JFrame
.
The entire thing worked perfectly before I added the timer. However, the image is still being drawn, and the method run()
of the TimerTask
is still being used completely. However, the image does not appear on my JFrame
.
public class Main implements ActionListener {
private static File load = null;
private static BufferedImage image = null;
private JFrame frame;
private JButton start;
private JLabel game_name;
private JLabel screen;
private ImageIcon icon;
private Asteroids aster = new Asteroids();
private static Main m = new Main();
protected static int height = 550;
protected static int width = 800;
protected static int cd = 0;
/*
* Here the JFrame frame gets created and set up, and the main method
* does its job. I believe only the actionPerformed method to be
* important, so I removed this part from the post.
*
*/
private void addScreen() {
frame.add(screen);
}
@Override
public void actionPerformed(ActionEvent ae) {
// Cleaning the screen
start.setVisible(false);
game_name.setVisible(false);
// Creating the image
aster.spawn(5);
// creating the countdown timer
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
// creating countdown
aster.initialScreen();
// Reading the image
load = new File(aster.filePath + aster.fileName + ".png");
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
try {
image = ImageIO.read(load);
} catch (IOException i) {
System.out.println("Reading has encountered an error: \n" + i); }
// Implementing the Image
screen = new JLabel();
screen.setSize(width, height);
icon = new ImageIcon(image);
screen.setIcon(icon);
m.addScreen();
System.out.println("roger");
}
}, 0, 1000);
} // end actionPerfomed()
} // end class
Can someone spot the mistake? I really don't understand what the problem is, I am new to timers though, so if something I do is really stupid please tell me.
Alright, so I somehow solved the problem:
First of, I did change the util.Timer to a swing.Timer, however, that in itself did not help.
Before, I was saving each image after it was drawn on my desktop, and then I was loading it onto the screen when it should be displayed. I played around with the code a little, and discovered that I don't need to save it but can actually reference it directly by making it static
. When I did that, the problem disappeared. Here a code example of what I mean:
Before:
// In the drawing class
save = new File(aster.filePath + aster.fileName + ".png");
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
try {
ImageIO.write(image, "png", save);
} catch (IOException i) {
System.out.println("Writing has encountered an error: \n" + i); }
// In the displaying class
load = new File(aster.filePath + aster.fileName + ".png");
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
try {
image = ImageIO.read(load);
} catch (IOException i) {
System.out.println("Reading has encountered an error: \n" + i); }
ImageIcon icon = new ImageIcon(image);
displayingJLabel.setIcon(icon);
frame.add(displayingJLabel);
After:
// One static declaration and initialization of an BufferedImage in the drawing class
public static BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// Drawing Code
// Accessing the image
ImageIcon icon = new ImageIcon(DrawingClass.image);
displayingJLabel.setIcon(icon);
frame.add(displayingJLabel);
Essentially, everything is the same except that the entire saving and reading process has been skipped, and instead of several local BufferedImage
am I using only one static BufferedImage
.
I don't know for sure why this worked, but my guess is that the entire reading and writing process simply took too long for the Timer to go off every second, and this new method is a lot faster. I haven't tried to do the whole thing with a util.Timer again, but I think the swing.Timer probably has its fair share in solving this problem.