Hi there!

I am new to the list, I hope I found the right list to ask this
question, otherwise i appologize and ask for directions of which list
is more appropriate.

I am developing an Applet based 2d game ( a minimalistic SimCity clone
). In an attempt to decrease flickering I skip the
erase-to-background-color default behaviour of paint() by overriding
it and putting my drawing code there instead. paint(Graphics g) simply
calls update(g), as per recommendation in Java API docs:

        public void update(Graphics g) {
                // Background: map field
                g.drawImage(backbuffer, 0, 0, this);
                
                // Foreground: headsup display
                headsup.draw(g);
        }

        public void paint(Graphics g) {
                update(g);
        }

The headsup-display draws some lines ontop of the background map
image, for example the cursor.

Now the problem is that even though the window (Firefox or
AppletViewer) is left unresized and nothing obscures it, the
update-method gets called repeatedly without-end, giving
less-than-optimal performance, and a lot of flickering.

Even more strangely, when starting the Applet, it works fine (update()
gets called once a second..) for a some 5-10 seconds, then the mad
update()-calling begins. I'm under WinXP, JRE1.4.2. The continuous
update:ing really hogs the CPU (gets up to 90%) which is not good for
a game supposed to be run on a web page while the user listens to
music for example.

Technical details:

In order to drive the simulation, I have a background thread which
approximately once a second fires an ActionEvent on a phony Button
which is a member field of the Applet:

        private Button triggerStepButton;

        public void run() {
                Thread.currentThread().setPriority(1);
                while (running) {
                        ActionEvent ae = new ActionEvent(this.triggerStepButton,
                                        ActionEvent.ACTION_PERFORMED, "");
                        
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ae);
                        try {
                                Thread.sleep(1000);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                }
        }

run() is a method of my Applet, aswell as triggerStepButton.
triggerStepButton has one listener: the Applet. In the init() method
of the Applet:

                triggerStepButton = new Button();
                triggerStepButton.addActionListener(this);

So, the Applet has the following signature:

   public class TerraformerApplet extends Applet implements Runnable,
ActionListener { ...

The actionPerformed method of the Applet looks like this:

        public void actionPerformed(ActionEvent e) {
                model.step();
                updateBackbuffer();
                repaint();
        }

... where model contains the SimCity model and it's specific rules.
updateBackbuffer updates the parts of the background image (called
backbuffer) which have changed since last call. The actionPerformed
method is called once a second, even after the mad update:ing has
begun.

Why not call model.step() and updateBackbuffer() in run()? Well I want
to avoid the synchronization hassle needed to make only one thread
access the model/background image at-a-time. This solution is simpler,
even though it might seem slightly complicated at a first glance. I
tried the synchronization solution first, but then I remembered that
the whole event-queue system is built around the idea of running ONE
EVENT AT A TIME, so it seemed natural to squeeze in the
step()-triggering into it. I assume the postEvent-method is
synchronized?

So, does anyone have any idea what is going on? Somehow I get the
feeling the repaint() queries are not "eaten up" in the event queue,
as if there is supposed to be some way to do a consume(e), analogous
to KeyEvent's, but the API docs gives no hint of this. Or, I got an
infinite loop calling repaint() somewhere, which is triggered after a
few seconds of the Applet running. Both seem far-fetched at the
moment...

Thanks for any answers,

/Olof

===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to