Whats wrong here, advice please!

Hello everyone! I wanted to post a method of mine I use in a game which isnt performing as well as id like. When this method is called, which is every frame rendered for x frames after a game item has left the screen, it just renders some squares from the departure point, which expand whilst also fading away. Whenever this happens it causes the screen to flicker, could anyone tell me if anything i am doing in this code could be causing this?


public void drawDeathAnims(Graphics g){
		
		
		//loop through arraylist
		//while looping if any are incountered which are too old delete them
		for(int i = 0; i < departurePoints.size(); i++){
			int[] dpt = departurePoints.get(i);
			//check that it's not too old, for now just go up to 400;
			if(dpt[3]>deathAnimFrames){
				//delete
				departurePoints.remove(i);
				i--;
			} else{
				//if its the first time get the chainsize form last frame
				if(dpt[3]==0){
					dpt[4]=gameState.getLastScore()/gameState.getLastChain();
					departurePoints.get(i)[4]=dpt[4];
					
				}

				//has to be centered
				
				Graphics2D g2 = (Graphics2D)g;
				g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
		                 (RenderingHints.VALUE_TEXT_ANTIALIAS_ON));
				g2.setFont(new Font("SansSerif",Font.BOLD,18));
				
				int opacity = 255-(255*dpt[3])/deathAnimFrames;
				String score = ""+(dpt[4]);
				int scoreX = GraphicUtils.getXPointForCenteringText(g2, score, Global.TILE_DIM);
				
				g2.setColor(new Color(0,0,0,opacity));				
				g2.drawString(""+score,
						GamePanel2.LEFT_BORDER+(dpt[0]*Global.TILE_DIM)+scoreX+2,
						//(-dpt[3]/3)+
						27+dpt[1]);
				
				g2.setColor(new Color(255,255,255,opacity));
				g2.drawString(""+score,
						GamePanel2.LEFT_BORDER+(dpt[0]*Global.TILE_DIM)+scoreX,
						//(-dpt[3]/3)+
						25+dpt[1]);
				
				int boxSize = Global.TILE_DIM+(dpt[3]*2);
				int boxXPos = GamePanel2.LEFT_BORDER+(dpt[0]*Global.TILE_DIM)-dpt[3];
				
				//g.setColor(Tile.getTileColor(dpt[2]));
				g.drawRect(boxXPos,
						(dpt[1])-dpt[3],
						boxSize,
						boxSize);
				
				g.drawRect(boxXPos+1,
						(dpt[1])-dpt[3]+1,
						boxSize-2,
						boxSize-2);
				
				int lessOpacity = opacity-50;
				if(lessOpacity < 0){
					lessOpacity = 0;
				}
				
				g.setColor(new Color(255,255,255,lessOpacity));
				g.drawRect(boxXPos+2,
						(dpt[1])-dpt[3]+2,
						boxSize-4,
						boxSize-4);
				
				
				g.drawRect(boxXPos+3,
						(dpt[1])-dpt[3]+3,
						boxSize-6,
						boxSize-6);
				
				int evenLessOpacity = opacity-50;
				if(evenLessOpacity < 0){
					evenLessOpacity = 0;
				}
				
				g.setColor(new Color(255,255,255,evenLessOpacity));
				g.drawRect(boxXPos+4,
						(dpt[1])-dpt[3]+4,
						boxSize-8,
						boxSize-8);
				
				
				g.drawRect(boxXPos+5,
						(dpt[1])-dpt[3]+5,
						boxSize-10,
						boxSize-10);
				
				
				
		
				//increse age by one
				dpt[3]++;
			}
		
		}		
	}

Thanks for any advice!

I’m at work so I didn’t have the time to read through it all to understand it but while quickly looking at it don’t EVER use “new” in your display function, especially not in a loop. Reuse as much as possible by for example creating colors in the construct function and storing them for later usage, don’t create new colors several times per frame.

Hello, thanks for your reply, much appreciated.

I thought that might be the case, creating objects is an expensive process i hear, the only problem is as each frame i want the box to get more transparent, is there a better way of doing this that the way i am currently, which is creating a new Color object each update with a reducing Alpha channel?

Thanks

You are free to create thousands or even tens of thousands objects per second.

If anything, it will slow you down a bit, but it will certainly not cause flickering.

is this conflicting advice?!

What Mickelukas says is simply not true. As said, creating lots of objects might reduce performance by a few percent, if that, but in your post you complain about flickering. That’s a totally different problem.

If you’d cache all your objects, your framerate might go up a tiny big, which will only make it flicker faster…

Creating lots of objects will slow down the application. If you read my post I’m not saying anything about the flickering. I didn’t have the time to read through everything to know what was the cause.

“What Mickelukas says is simply not true.” - Yea, right…

Profile it, then you’ll know.

Does everything on the screen flicker? What happens if you remove all the drawString code? Are you using double buffering for rendering?

this won’t heal your flickering, but it looks nicer… and who knows…
instead of

for(int i = 0; i < departurePoints.size(); i++){
		....	
		if(dpt[3]>deathAnimFrames){
			//delete
			departurePoints.remove(i);
			i--;
		} else{
               .....
    }

do

for(int i = departurePoints.size()-1; i > 0; i--){
		....	
		if(dpt[3]>deathAnimFrames){
			//delete
			departurePoints.remove(i);
			continue;
		} 
               .....

The creation of new Colors does not slow down your code more than 0.0000001%. I just tested creating millions of new Colors per second without a noticeable frame drop.

Just a guess, but it looks like you are drawing to the active graphics and no longer page flipping. You may want to move this loop
for(int i = 0; i < departurePoints.size(); i++){ outside of your method and pass in the size as an argument so you can continue to render off-screen.

I’m almost definitely sure it’s because of the drawing of rectangles with semi transparent color, because java2d can’t handle beyond drawing couple rectangles with semi transparent color. It can handle primitives with solid colors fine, so that’s my opinion.

A quick guess is that it has something to do with your use of Java2D, or more specifically alpha blending (which can be slow, depending on the JVM you’re using) and/or drawing strings (especially with anti-aliasing, this can be slow).

I’d definitely profile to check what’s wrong, but you can also deduce by removing drawing of your alpha blended squares and removing drawing of strings (just to see if one of them is your bottleneck).
Once you know where the bottleneck is, we can go from there.

I agree with Riven that it’s unlikely that creating new objects is creating your problem, after all it seems like you’re not creating that many objects anyway.

wow, lots of responces, thanks everyone! I will have a look in to the questions & suggestions raised and post back what i find.

Thanks again everyone!

Removing from a array list is death to performance especially if at the beginning (needs to move everything else you see). If you need removal and not random access use a linkedlist. If you need random access and not removal use a arraylist. If you need both either use a skiplist or check which is more used or use a arraylist and put your objects to remove at the end and remove right to left or if order is indifferent use a set.

Aha, i have found a solution!

I wasnt using active rendering (which i thought i had already implemeted) and was calling the repaint() method to paint my buffer to the screen.

Now no flickering / tearing, wahay!

Thanks for everyones help, a good few pointers there to make my game a bit more efficent, still have lots to learn!

Thanks! ;D

The issue is how many objects counts as “lots.” What Riven is saying is that you can allocate even 50k small objects per frame and still maintain 60 fps with no problems on any recent computer. And that’s in client mode! Yes, it takes time, but it’s not exactly slow.

I’d say that unless you’re allocating at least 10k small objects per frame, it’s not even worth worrying about, as it’s almost certainly not your bottleneck. Even if you are allocating that many, profile first and make sure that’s actually where your time is best spent; unless you’re working on a physics or graphics engine, there are probably other things that will give you more speed per hour spent optimizing.