There is a new book from Oreilly called 

Killer Game Programming in Java

http://www.oreilly.com/catalog/killergame/

You might find Chapter 2 very interesting. He shows how to control both
UPS (updates per sec) and FPS (frames per sec) independently.

Here is the table of contents for chap 2.


Chap 2. An Animation Framework
      Animation as a Threaded Canvas 
      Adding User Interaction 
      Converting to Active Rendering 
      FPS and Sleeping for Varying Times 
      Sleeping Better 
      FPS and UPS 
      Pausing and Resuming 
      Other Animation Approaches



-----Original Message-----
From: Discussion list for Java 2D API
[mailto:[EMAIL PROTECTED] On Behalf Of Olof Bjarnason
Sent: Thursday, August 25, 2005 12:05 PM
To: [EMAIL PROTECTED]
Subject: Re: [JAVA2D] Problem with non-stopping calls to update()


Whoa. Things like this scares me:

http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
(look at the section under "The event dispatching thread", the red
section)

I get the general feeling the AWT/Swing developers have been trying to
let the application developers not worry about threads (eg. hiding the
AWT-Event thread etc.) but then, when you get to the bottom of things
you REALLY have to worry about threads.

Quote: "To avoid the possibility of deadlock, you must take extreme care
that Swing components and models are created, modified, and queried only
from the event-dispatching thread." I guess this applies to generel,
old-skool AWT too...

Wow. Great. I think I'm gonne build my own GUI toolkit inside my Applet
instead of using AWT ... Question is how do I avoid AWT altogether...

/Olof


On 8/25/05, Olof Bjarnason <[EMAIL PROTECTED]> wrote:
> 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".

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