Fullscreen performance question

Hi *,

I don’t know very well this new full screen concept and I have a question.
I’m trying to implement a soccer game, for which I have to draw first the pitch and then the player (only one for now). I use double buffering (at least I think I’m doing so ;)) to do this, and there’s no problem if I put the display mode at 640x480. But when I put it to 800x600, it’s then much slower, even if I shorten the sleep time of the redrawing thread.
Thanks in advance!

A tip: to get good answer be sure to write good description on the problem.

Are you using Bufferstrategy? How much slower between the different modes? fps? etc…

I’m using BufferStrategy like from examples I could find and the fps dropped from 25 to 10. Just ask if you need some more input, I don’t know what I should exactly tell!

Your fps is 25 in 640x400? It sounds like you are using operations that is not hardware accelated like scaling etc.

And then it sounds to me that the cpu has to work even harder when there are more pixels like 800x600 and therefor you get a big drop.

With my little 2d game library I got fps over 100 with 100 sprites moving on the screen and the in both 640x400 and 800x600… I dont remember what 1600x1200 got but it was abow your fps anyway.

So can you post your render code, i.e the code where you are painting on your Graphic object, so that I can have a look on it.

I’m using BufferStrategy like from examples I could find and the fps dropped from 25 to 10. Just ask if you need some more input, I don’t know what I should exactly tell!

here’s the code:

public void render() {
Graphics g = getFrame().getBufferStrategy().getDrawGraphics();

if (getFrame().getBufferStrategy().contentsLost()) {
return;
}

if (null == getOffscreenImage()) {
initBackBuffer();
}

Graphics2D offscreenGraphics = (Graphics2D)getOffscreenImage().getGraphics();

// pitch position
int tmpX = getPosition().getX();
int tmpZ = getPosition().getZ();

// pitch image is 1266x1694, we just need the frame’s size
Image img = ((BufferedImage)getPitchImage()).getSubimage(tmpX, tmpZ, FRAME_WIDTH, FRAME_HEIGHT);
offscreenGraphics.drawImage(img, 0, 0, null);

// draw the player
// current player image returns an image stored in an array, corresponding to the running direction
offscreenGraphics.drawImage(getCurrentPlayerImage(), getPlayerRelativeX(), getPlayerRelativeZ(), null);

offscreenGraphics.dispose();

g.drawImage(offscreenImage, 0, 0, null);

getFrame().getBufferStrategy().show();
}

the trouble that I see is the


   // pitch image is 1266x1694, we just need the frame's size
  Image img = ((BufferedImage)getPitchImage()).getSubimage(tmpX, tmpZ, FRAME_WIDTH, FRAME_HEIGHT);
  offscreenGraphics.drawImage(img, 0, 0, null); 

part of the code. Using the getSubImage routine EVERY time the render method is being called will slow the down the game alot.

And using such a large image as a background is not optimal either. My suggestion is that you make the pitch as tiles, as most of the part is green I quess only on image with dimension of 64x64 or 32x32 should to to paint large part of the pit. The sidelines etc can have specific tiles in the same size. Then save the background tiles as


Image[][] pit

Where pit[0][0] is the top right corner of the soccer pit. And remember only create each tile image ones and then use that tile Image objects refrence in your pit array to avoid massive memory usage.

Then you need some sort of conversion between the pit array images and the coordinates of the frame that needs to be displayed.


// pitch position
//  int tmpX = getPosition().getX();
//  int tmpZ = getPosition().getZ(); 

// use instead
Point p = translate(getPosition().getX(), getPosition().getY());
int tmpX = p.x;
int tmpY = p.y;

public Point translate(int x, int y){
  return new Point((int) x/TILEWIDTH, (int) y/TILEHEIGHT,
}

Then you need to paint some tiles on your graphic object


int x, y;
for (int i=tmpX; i<(SCREENWIDTH/TILEWIDTH+tmpX); i++)
for (int j=tmpY; j<(SCREENHEIGHT/TILEHEIGHT+tmpY); j++){
g.drawTile(pti[i][j], x, y);
x+=TILEWIDTH;
x+=TILEHEIGHT;
}

I hope you get the idea… you still need to compensate for the offset the translate function makes otherwise the pitch will move one whole tile every 64px or so. This code is not a working one and written in 5 min… just to let you see the concept.

I see, thanks a lot Backmask. The only problem is that I would need this image as a background as it contains also some details like crowd, …
That with the tiles is a good idea and is easy to implement but it wouldn’t like as nice as the pitch image.
I guess I’ll have to find some workaroud for this.
Thanks a lot for your help!

Just make the crowed as tiles to and try to work them in to the array as well. Thinks tiles ;D

I havn’t had the time to fool around with scrolling tile backgrounds yet but there is a library by zparticle at his website.

http://www.scottshaver2000.com/

it contains the code for the scrolling things. Havn’t look at it but I have seen a demo on the scrolling and it worked with a good fps. (see under library -> planetation -> Downloads - > library source.

Always glad to help a fellow java gaming programmer ::slight_smile:

hehe, just a question still:
would there be a way to get a subimage with more efficience than BufferedImage.getSubImage(…)?

I don’t know any other way. But maybe someone in these forums can tell you if there is.

np m8! BTW, do you know how to mask some color from an image to get some kind of transparency by masking a specific color and how to change a color to an other one?

Hmm havnt tried anything like that…

I use ordinary .png or .gif files when I need transparasy on my sprites. I create them with the followning code…


GraphicsConfiguration gfxConfig = //get your gfx here

Image tempImage = new ImageIcon(filename).getImage();
BufferedImage sprite = gfxConfig.createCompatibleImage(tempImage.getWidth(), tempImage.getHeight(), Transparency.BITMASK);

Graphics2D g = (Graphics2D)sprite.getGraphics();
g.drawImage(tempImage, null, null);
g.dispose();