سؤال

I have a problem that I'm not able to understand, none the less solve.

I am making a clone of Asteroids (I call it Meteors, to be clever). Currently I have a class entitled MeteorGame which is the chief class that does the GUI drawing. MeteorGame extends JFrame to make the window, and it has another class that it uses to interpret keyboard events. Everything works great but I need to scale this up. Basically, what I have created is one "level" of the game, and now I need a level manager. I call this class Meteors and I want IT to handle creating the JFrame, rather than MeteorGame.

So to this effect, what I am trying to create is a system where Meteors class is basically a shell that creates a window and instantiates "levels" of MeteorGame in sequence. I have converted my MeteorGame class from JFrame to JPanel, so that my JFrame Meteors class adds JPanel components to itself as the user levels up.

I want each MeteorGame to draw itself and interpret keyboard event entirely autonomously, with the JFrame Meteors class simply working to queue up levels.

Many problems.

  1. Is using the paintComponent() method the only way to draw to a JPanel? The way my old class works is it uses a constant while loop (managed for frame rate) to continuously call the update() and draw() methods that do all the work. So 40 times per second the method draws itself onto the JFrame.

    With my updates converting draw() to paintComponent() the frame is drawn only once, and then disappears. I need to find a way to keep redrawing the JPanel continuously. (to eliminate flicker I draw the panel by writing to an image and then drawing the image)

  2. Is there a better way to do all of this? I'm moving from a background in Objective-C iOS development where I am much more familiar with the view hierarchy. I'm sure that what I'm doing is not the most ideal situation by any means.

Also, when I create a JButton in the JFrame class and try to draw it using the following code, nothing happens. What am I doing wrong?

JButton button = new JButton("Close");
button.setLocation(300, 300);
add(button);
هل كانت مفيدة؟

المحلول

"Is using the paintComponent() method the only way to draw to a JPanel?"

Technically, no. But it's the correct way.

"The way my old class works is it uses a constant while loop (managed for frame rate) to continuously call the update() and draw() methods that do all the work"

Don't do this. Instead implement a javax.swing.Timer passing delay to timer, which will determine the frame rate. See more at How to Use Swing Timers

"With my updates converting draw() to paintComponent() the frame is drawn only once, and then disappears."

What you want to do is have a model class, say Asteroid which maintains the state of each Asteroid object. You can then maintain a List<Asteroid> that you can iterate through in the Timer calling each of its method to manipulate its state, then repaint() the panel with every tick of the timer. Then you can can iterate through the List in the paintComponent method, and call each Asteroid's draw method.

"I need to find a way to keep redrawing the JPanel continuously. (to eliminate flicker I draw the panel by writing to an image and then drawing the image)"

It most cases, using the Timer (if used correctly) will help in alleviating the flickering (of course given other factor that I may be unaware of).

"Is there a better way to do all of this?"

Take all the above notes into consideration and have a look at this answer, which takes all those points into consideration, and is also a wannabe asteroid like game/background of a game.

"Also, when I create a JButton in the JFrame class and try to draw it using the following code, nothing happens. What am I doing wrong?"

Can't tell with the bit of code you've provided.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top