Jump to content

  • Log In with Google      Sign In   
  • Create Account

PaintComponent runs slow and flickers in Java


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
9 replies to this topic

#1 Patriarch K   Members   -  Reputation: 212

Like
0Likes
Like

Posted 12 December 2012 - 04:09 AM

I have a game which is painting a lot of gifs and images everywhere and it runs a little bit slow meanwhile. Sometimes it can run very good for a minute or something, but then it starts to lag and stuff. Most of the images flicker from time to time. Not extremely much, but they still flicker a little bit.
I will shoe the relevant parts of my code and maybe you can find what I need to do. I have googled and seen things with dubble buffering and stuff, but I don't really get it.

The code here is just a lot of stuff, I have removed a lot of "game logic" and image files so the names are not the same, but you will at least get my method with this code:


public class Game3 extends JPanel implements ActionListener{

ImageIcon flowerIcon = new ImageIcon("img\\Dragon.gif");
Image flower = flowerIcon.getImage();
ImageIcon flowerhitIcon = new ImageIcon("img\\DragonHit.gif");
Image flowerhit = flowerhitIcon.getImage();
ImageIcon flowerfireIcon = new ImageIcon("img\\DragonFire.gif");
Image flowerfire = flowerfireIcon.getImage();

URL music = null;
AudioClip musicSound;
URL pop = null;
AudioClip popSound;
Font font;
Random r;
boolean skott = false;
Nalle nalle = new Nalle();
ArrayList<Bubble> bubblor = new ArrayList<Bubble>();
Timer tim;

Game3(){
   try {
	wee = new URL("file:img\\wee.wav");
   }
   catch (MalformedURLException exp) {
   }
   weeSound = Applet.newAudioClip(wee);
   try {
	namnam = new URL("file:img\\namnamn.wav");
   }
   catch (MalformedURLException exp) {
   }
   namnamSound = Applet.newAudioClip(namnam);
   bubbles = Integer.parseInt(textBubbles);
   tim = new Timer(20, this);
   setFocusable(true);
   addKeyListener(k);
   musicSound.loop();
   tim.start();
  }
}

public void checkCollisions(){
blablabla
}

@Override
public void paintComponent(Graphics g){
  super.paintComponent(g);
  Graphics2D g2d = (Graphics2D) g;
  if(Map.redLevel == true){
   g2d.drawImage(background, himmelX, himmelY, null);
   g2d.drawImage(background2, himmelX2, himmelY2, null);
   g2d.drawImage(lava, grassX+80, grassY+355, null);
   g2d.drawImage(lava, grassX+680, grassY+130, null);
   repaint();
  }
}

@Override
public void actionPerformed(ActionEvent arg0) {
blablabla....
}


Sponsor:

#2 PsychotikRabbit   Members   -  Reputation: 168

Like
0Likes
Like

Posted 12 December 2012 - 07:41 AM

Are you regulating the FPS (Frame per seconds) of your game loop ? You do not need to draw constantly the images because it will just provoke a huge lag. You can simply draw your images let's say 25 times per seconds. I don't think you should override the PaintComponent method to draw all your images as you can't control when this method is called.

I think you should try going with Slick2D API, it provides everything you need for your game and it's pretty simple to use. It's not a good idea to use Swing as you do for a game as Swing is slow and is not made for games, it's made for interface such as menus.

Slick2D will provide you a game engine which will regulate the FPS and a Graphic object where you can draw your images.

#3 Patriarch K   Members   -  Reputation: 212

Like
0Likes
Like

Posted 12 December 2012 - 08:09 AM

Hmm, but all my Images are kind of moving and If I don't repaint them, then they will not move?

#4 PsychotikRabbit   Members   -  Reputation: 168

Like
0Likes
Like

Posted 12 December 2012 - 08:15 AM

Normally, you will repaint them but only a fixed number of times in a second. This way you can control the speed of the game. But first, I think you really shouldn't use Swing to make a game, you will get other performances issues like the one you have.

#5 PsychotikRabbit   Members   -  Reputation: 168

Like
0Likes
Like

Posted 12 December 2012 - 08:20 AM

You can easily switch to Slick 2D it shouldn't be hard to do so. This is an example of a simple game application using Slick.

package slick.path2glory.SimpleGame;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;

public class SimpleGame extends BasicGame{

    public SimpleGame()
    {
	    super("Slick2DPath2Glory - SimpleGame");
    }

    @Override
    public void init(GameContainer gc)
   throws SlickException {
	    //this is where you will load your images
    }

    @Override
    public void update(GameContainer gc, int delta)
   throws SlickException	
    {
	   //this is where you will control the game AI
    }

    public void render(GameContainer gc, Graphics g)
   throws SlickException
    {
    	 //This is where you can draw your images in the provided Graphics
    }

    public static void main(String[] args)
   throws SlickException
    {
		 AppGameContainer app =
   new AppGameContainer(new SimpleGame());

		 app.setDisplayMode(800, 600, false);
		 app.start();
    }
}

As you can see it's pretty much the same concept that you are using for drawing, but the API provides a game container which is a game loop in a independant window.

#6 Patriarch K   Members   -  Reputation: 212

Like
0Likes
Like

Posted 12 December 2012 - 08:34 AM

Well, in my case then I rely on the timer which is 20 frames per millisecond. If I make a separate update mechanism, wouldn't like 100 or something be a little bit too slow?
My game is very soon finished and it works fine as it is at the moment, but not perfect - that's why I made this thread. I will try the SLIK on my next game!

#7 PsychotikRabbit   Members   -  Reputation: 168

Like
0Likes
Like

Posted 12 December 2012 - 08:59 AM

For the timer you can try differents values to test the stability of your games but as I said 25 frames per second should be enough.

And is the repaint() method call is really necessary in your paintComponent method ?
@Override
public void paintComponent(Graphics g){
  super.paintComponent(g);
  Graphics2D g2d = (Graphics2D) g;
  if(Map.redLevel == true){
   g2d.drawImage(background, himmelX, himmelY, null);
   g2d.drawImage(background2, himmelX2, himmelY2, null);
   g2d.drawImage(lava, grassX+80, grassY+355, null);
   g2d.drawImage(lava, grassX+680, grassY+130, null);
   repaint();
  }
}

Edited by PsychotikRabbit, 12 December 2012 - 09:00 AM.


#8 de_mattT   Members   -  Reputation: 308

Like
0Likes
Like

Posted 12 December 2012 - 03:49 PM

I just had a look at an old game I made and I did the following for double buffering. I can't remember why but I just played it and it runs fine.

panel.setDoubleBuffered(true);
RepaintManager.currentManager(frame).setDoubleBufferingEnabled(true);

Where panel is my extended JPanel with the overriden paintComponent() method (I saw that I'm not calling repaint() at the end of my paintComponent() method, which supports PsychotikRabbit's suggestion).
Where frame is a JFrame.

Hope this works for you too.

Matt

Edited by de_mattT, 12 December 2012 - 03:51 PM.


#9 VildNinja   Members   -  Reputation: 447

Like
0Likes
Like

Posted 12 December 2012 - 05:00 PM

It's been a while since I last did graphics in native Java, but from the looks of it, you're not using active rendering. This article helped me a lot, when I got tired of the slow repaint() calls: http://www.gamedev.net/page/resources/_/technical/general-programming/java-games-active-rendering-r2418

#10 P0jahn   Members   -  Reputation: 270

Like
0Likes
Like

Posted 13 December 2012 - 12:05 PM

I have 66 frames per second without any problems in Swing.

Edited by P0jahn, 13 December 2012 - 12:05 PM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS