Thanks for you answer Chet.

On 8/25/05, Chet Haase <[EMAIL PROTECTED]> wrote:
> Olof,
> 
> I'm not sure of where the "mad update" is coming from, but you
> don't want to call update() from paint; that's actually backwards
> from what the system expects.
> 
>  From the Component javadocs:
>         The update method of Component calls this component's paint
>         method to redraw this component.
> and:
>         Subclasses of Component that override this method should
>         either call super.update(g), or call paint(g) directly
>         from their update method.

OK, guess I misread the docs. Actually, I followed this tutorial to begin with:
http://www.dgp.toronto.edu/~mjmcguff/learn/java/

> 
> Update calls paint() internally, which means that it calls
> your paint, which calls update, which ...

Yes, if I don't override update().

> Of course, you've overridden update(), so this changes the
> behavior, but it's a bit confusing at the least.  But there could
> be more wrong here: it could be that by changing the nature of
> update/paint interaction, you're getting in the way of the
> regular system of issuing and consuming repaint() events, which
> could cause the paint calls to keep being issued.
> 
> The solution here is to simply override paint() and do your
> painting there.  Or if you're using Swing, override paintComponent()
> instead.  Don't override update, or at least not in the manner you
> are doing currently.
I'm using AWT I guess, no Swing. I'm trying to go for old-API in order
to make the game runnable on more computers. I compile for 1.4.2, but
I guess 1.4.2 has Swing so I could go for paintComponent, but my
feeling is I should use paint(), eg.the tutorial uses paint().
Comments?

> 
> To improve performance in general:
>         - use a timer to schedule regular repaints so you don't get
>         swamped with constant repaint events (similar to what you're
>         doing, but I don't follow the complexity of using key actions
>         for this.  Why not simply issue a repaint call?)
>         - only draw the area that's changed.  So if only one rectangle
>         of the playing area has changed, draw that updated region
>         into the back buffer, and copy that region of the back buffer
>         into the window.
Thanks for these tips, I will try and implement the
update-only-changed-area thingy.

Some things I've tried now:

- I don't override update() (removed it completely from my Applet),
and I put the painting code in paint(). No change.
- I removed ALL repaint() calls from my Applet. Of course the graphics
isn't updating at all to begin with, but then the mad-updating begins
... No change.
- I changed to JRE 1.5.02. No change.

Confused... 

/Olof

> 
> Chet.
> 
> 
> Olof Bjarnason wrote:
> > 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".
>

===========================================================================
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