Improve rendering

Started by
4 comments, last by Martin Radev 10 years ago

Hello, I hope this is the right category.

I wanted to implement something like a fog of war for my 2d shooter game. I am using Java 2D graphics.

Currently, what I do is go over each pixel of the screen and compute whether the distance from that pixel to the player is more than some number (200 for example). Then, I just do a & bit operation with a mask which has all of its even bits on. This makes the pixel look gray.

However, there is lag. This is mainly because I go over each pixel. Since there are 800x600 pixels, the computation is quite slow. What do you think? How can I implement something like "fog of war" or "line of sight"?

I was thinking of trying to improve the other computations in the game so that it is left more time for this part of the game. For example, currently I check all objects for a collision. I can reduce it by using a binary space tree.

What do you think?

P.S. I cannot switch to Opengl at this point.

Advertisement

Do the distance check using the squares of the distances instead of actual distances to avoid square root calculations

eg. X^2 + Y^2 < 200^2

Where X,Y are difference between pixels and players position.

If you hadnt already done that it might work for a simple game but you probably should find a better algorithm if you are working on something more serious.

Try:

-Lower resolution FoW layer (eg calculate FoW for 2x2 or 4x4 pixel groups instead of for every pixel)

-Try hierarchial approach (so you can easily identify the areas which are guaranteed to be visible or guaranteed to be hidden, then do more precise calculations for the remaining areas. Quadtree?)

-Try saving results of calculations where possible.

-Dont do calculation every frame, so if the player moves the visible areas remain the same until they update again. You can adjust update rate too or update further areas at different rate than closer areas.

-Prevent the player from seeing what is behind him. This affects game play but will let you easily eliminate checking half of the map.

Oh, and if your game is tile based you should do the FoW on the tile grid not per pixel probably.

o3o

I would think that if you just start out with everything in your map as fogged out, and just keep track of the state, then this isn't a problem. You're going to need to keep track of that anyway if you save/load progress. When something happens in a sector that removes the fog, then you update that sector's fog flag. A small 2D boolean array could be all you need. Even if you need to keep track of every pixel, this would still be better than checking every pixel every time.

If this is way off, post some code or pics for future readers.

I think, therefore I am. I think? - "George Carlin"
My Website: Indie Game Programming

My Twitter: https://twitter.com/indieprogram

My Book: http://amzn.com/1305076532

Here is an image of the game screen: http://imgur.com/1rCq1Qv

Here is the code where I do the fog of war and check whether a players sees another player/bullet: https://github.com/martinradev/2dShooter/blob/master/VirtualCommando/src/main/java/me/martin/radev/game/virtualcommando/view/gui/screens/gamescreen/GameScreenMap.java

I will do that with not computing actually the square root of a number though this would not improve it a lot. I am not quite sure though how to do the other things you mentioned since I always produce on the image every frame and then I have to add the mask again.

Just a quick thought, but you could have a precomputed bitmap with alpha that is the fog with the player at the center of the bitmap, and then just center that bitmap around the player and blit that on top of the gameworld.

Another, separate but basic optimization is to just check the pixels that have changed. You already know where the player is, where the player was, and the radius of their fog clearing, so you could just check that space. You could just check the min-max of that and do a for loop around that rectangle. Or you could make the whole screen grey (blitting a big texture that is grey with your 'out in the fog' alpha, and then just check the area around where the player currently is.

Thank you. It worked flawlessly.

This topic is closed to new replies.

Advertisement