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. Update calls paint() internally, which means that it calls your paint, which calls update, which ... 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. 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. 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".