Thanks Ted that seems nice! My progress so far: since Swing's Timer class is Swing (duh) I have to convert my Applet to a JApplet, which means paintComponent instead of paint for instance. Hope it is as simple as that...
/Olof On 8/25/05, Ted Hill <[EMAIL PROTECTED]> wrote: > 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".