I recently started working on a 2d platformer in java, and am asking a performance related question.
In my game, I have a world (relatively small for now).
But over half+ of the world isn't visible to the players camera, however I'm still painting the entire world (even the unseen parts).
Here's what I'm doing right now.
#Override
public void paintComponent(Graphics g){
g.translate(player.camX(), player.camY());
for (GameObject gameObject : solidObjects){
if (gameObject.isTouching(player.getCameraRect()))
gameObject.paint(g);
}
player.paint(g);
for (GameObject gameObject : unSolidObjects){
if (gameObject.isTouching(player.getCameraRect()))
gameObject.paint(g);
}
}
So the question is, would it be faster having an if-statement checking if its on the screen before painting?
Yes.
Doing a check to see if it's on a screen should take no more than 1 or 2 steps.
Painting everything requires you to draw every single pixel on to the screen regardless of whether it's used or not.
If gameObject.paint(g); involves a lot of drawing calls, most likely the branching (check) would save more work than it costs. If it's only like one drawing call to paint a sprite though, your library would already perform such a check to avoid buffer overruns and yours would be redundant.
That said, if you are starting to face performance issues here, then I recommend using some kind of data structure. A simple one is a grid like so:
When your elements move, remove them from the grid cells they occupy and insert them to the new one(s) they occupy. That should just involve manipulating a few integers if you implement this efficiently.
Then when you want to draw elements on the screen, only draw the elements in the grid cells that overlap. That'll prevent you from looping over every single element in the game world. This also comes in handy for accelerated collision detection if you need it.
A quad-tree is an alternative though a little bit more costly to update, but it can provide better search quality if the elements in your game are sparsely distributed.
Related
If I draw something with coordinations like -80 and -90 will it affect performance same way as if it was actually drawn inside?
Is it actually worth it checking if the final image will appear on screen?
(and not drawing it if won't)
If I draw something with coordinations like -80 and -90 will it affect performance same way as if it was actually drawn inside?
Somewhat, but not nearly as much as if it is inside the screen.
Is it actually worth it checking if the final image will appear on screen? (and not drawing it if won't)
It's practically never worth implementing your own culling/clipping in a library where drawing out of bounds isn't an error/access violation, since the library would already have to make that check to avoid writing to memory out of bounds, and it would generally be wise to bet that the library's way of checking this is smart and fast.
So if you were to add your own basic check on top, now you're just making the regular, on-screen drawing perform two of such checks (your own on top of whatever is going on under the hood), and for off-screen cases, it would be likely that your check would actually be slower (or at least no better) than the library's.
Now I have to place emphasis on basic culling/clipping here. By basic, I mean checking for each shape you draw on a per-shape basis. There you'll just more likely damage performance.
Acceleration Structures and Clipping/Culling in Bulk
Yet there are cases where you might have a data structure to do efficient culling of thousands of triangles at once with a single bounding box check to see if it's in the frustum, for example, in a 3D case with structures like bounding volume hierarchies. Games use these types of data structures to massively reduce the amount of drawing requests required per frame with very few checks, and there you do gain a potentially massive performance benefit. A more basic version of this is simply check if the object/mesh containing the triangles has a bounding box that is inside the screen, eliminating potentially thousands of triangles from being culled individually with a single bounding box check.
In 2D with clipping, you might be able to use something like a quad tree or fixed grid to only selectively draw what's on the screen (and also accelerate collision detection or click-detection, e.g.). There you might actually get a performance boost if you can eliminate many superfluous drawing calls with a single check. But again, that's using a data structure that eliminates a boatload of unnecessary drawing calls with a single check. These are spatial partitioning structures whose sole point is to avoid checking things on a per-shape basis.
For a more basic 2D example, if you have say, a 2D "widget" which, in order to draw it, involves drawing dozens of different shapes to the screen, you might be able to squeeze a performance gain if you can avoid requesting to draw dozens of shapes with a single check to see if the rectangle encompassing the entire widget is in the screen. Again, there you're doing one check to eliminate many drawing calls. You won't get a performance gain on a level playing field where you're doing that check on a per-shape basis, but if you can turn many checks into a single check, then you have a chance.
According to the Graphics implementation for most common draws/fills (i.e. drawRectangle see: source of Graphics on grepcode.com they start with checking if the width and height are bigger then zero and then are doing more operations, therefore doing check for x,y < 0 are in doing the same number of operations in worst case.
Keep in mind that a rectangle starting at -80 and -90 as you said but width and height i.e. 200 will be displayed on screen.
Yes it will still affect the performance as it still does exist within the program, it's just not visible on the screen
I have to create a connect 5 game with a GUI for my CS course final project. I worked with Graphics2D for the last project - a Maze - and working with Graphics2D was a nightmare. At most, the connect5 board will be 20x20, which would be an Area of 400. I was wondering what the performance implications of creating an Array of 400 JLabels to handle the GUI, since it will be easy to determine a mouse click within boundaries, get the array induces, and changing the color of space along with other similar operations whereas the same operations would be much more difficult with Graphics2D. So, my overall question is: would creating an array of that many JLabels be undesirable? If so, what other alternatives might I have? Thanks everyone!
I think the JLabel approach would be undesirable, I think one component with custom painting would be more desirable, because it seems a bit easier.
If you have your classes in that abstract format not tied to the UI or anything (so playable even on the command line where you could output in a text a representation of the board), then it should be simple to loop through the spaces representing the board and make the small set of drawing calls to draw each slot (empty or not).
Seems better to if you wanted to introduce animations like pieces falling down and then bumping up for a while when they hit the piece below it.
To start with,I am pretty new to 3D programming and libgdx.
I looked at a few tutorials and I already render the scene I want. I have some 1x1x1 blocks, created with ModelBuilder.createRect() for every visible face, so if another block covers a face of this block, there is no rect created for this block. Also the top and bottom rect is not needed, as I can never see them (except for the floor). So I thought, that this is pretty efficient. I also have Backface culling enabled and I do Viewfrustum culling. However, if I look in a direction, where many blocks are in my viewfrustum the FPS go down to 15-20. This is still okay for me, as my laptop is over 5 years old and its performance is not the best, but this answer made me think.
"ModelBuilder is used for debug only". Okay, but how should i then create my boxes? Why should i create a Model in a Modeling app (like Blender), for simple squares? By doing this i couldn't even cull the faces, which are occupied by other blocks.
So my question is:
How can i create and render those boxes the most efficient way?
ModelBuilder#createRect will create a new model for each rectangle. When rendering a (part of a) model instance, it implies a draw call. Therefor ModelBuilder#createRect is extremely inefficient. It is better to combine multiple rectangle into a single (part of a) Model. This can be done using:
modelBuilder.begin();
MeshPartBuilder mpb = modelBuilder.part(....);
mpb.rect(...); // first rect.
mpb.rect(...); // second rect.
// etc.
Model model = modelBuilder.end();
Note that this is still not efficient enough for e.g. a voxel engine. If you are aiming to optimize for voxels, you'll probably want to build the mesh (after frustum culling and depth sorting) in a custom RenderableProvider. Here's an example: https://github.com/libgdx/libgdx/tree/master/tests/gdx-tests/src/com/badlogic/gdx/tests/g3d/voxel
I've been trying various ways of creating a two-dimensional tile-based game for a few months now. I have always had each tile be a separate object of a 'Tile' class. The tile objects are stored in a two-dimensional array of objects. This has proven to be extremely impractical, mostly in terms of performance with many tiles being rendered at once. I have aided in this by only allowing tiles within a certain distance of the player being rendered, but this isn't that great either. I have also had problems with the objects returning a null-pointer exception when I try to edit the tile's values in-game. This has to do with the objects in the 2D array not being properly initialized.
Is there any other, simpler way of doing this? I can't imagine every tile-based game uses this exact way, I must be overlooking something.
EDIT: Perhaps LWJGL just isn't the correct library to use? I am having similar problems with implementing a font system with LWJGL... typing out more than a sentence will bring down the FPS by 100 or even more.
For static objects (not going anywhere, staying where they are) 1 tile = 1 object is OK. That's how it was done in Wolf3d. For moving objects you have multiple options.
You can, if you really really want to, store object sub-parts in adjacent cells/tiles when an object isn't contained fully within just one of them and crosses one or more cell/tile boundaries. But that may be not quite handy as you'd need to split your objects into parts on the fly.
A more reasonable approach is to not store moving objects in cells/tiles at all and process them more or less independently of the static objects. But then you will need to have some code to determine object visibility. Actually, in graphics the most basic performance problems come from unnecessary calculations and rendering. Generally, you don't want to even try to render what's invisible. Likewise, if some computations (especially complex ones) can be moved outside of the innermost loops, they should be.
Other than that it's pretty hard to give any specific advice given so little details about what you're doing, how you're doing it and seeing the actual code. You should really try to make your questions specific.
A two-dimensional array of Tile objects should be fine........ this is what most 2D games use and you should certainly be able to get good enough performance out of OpenGL / LWJGL to render this at a good speed (100FPS+).
Things to check:
Make sure you are clipping to only deisplay the visible set of tiles (According to the screen width and height and the player's position)
Make sure the code to draw each tile is fast... ideally you should be drawing just one textured square for each tile. In particular, you shouldn't be doing any complex operations on a per-tile basis in your rendering code.
If you're clever, you can draw multiple tiles in one OpenGL call with VBOs / clever use of texture coordinates etc. But this is probably unnecessary for a tile-based game.
I'm trying to develop side scrolling game for android involving many many textures so I was thinking if I could create a separate layer, all a single unique color (very similar to a green screen effect) make a collidable and make it invisible to the player.
(foreground layer) visual Image
(2nd layer)collidable copy of foreground layer with main character
(3rd layer)Background image
I not sure if this is possible or how to implement it efficiently, the idea just came to me randomly one day.
Future regards, Thanks
I assume your game is entirely 2D, using either bit-blits or quads (two 3D triangles always screen-aligned) as sprites. Over the years there have been lots of schemes for doing collision detection using the actual image data, whether from the background or the sprite definition itself. If you have direct access to video RAM, reading one pixel position can quickly tell if you've collided or not, giving pixel-wise accuracy not possible with something like bounding boxes. However, there are issues greatly complicating this: figuring out what you've collided with, or if your speed lands you many pixels into a graphical object, or if it is thin and you pass through it, or how to determine an angle of deflection, etc.
Using 3D graphics hardware and quads, you could potentially change render states, rendering in monochrome to an off-screen texture, yielding the 2nd collidable layer you described. Yet that texture is then resident in graphics memory, which isn't freely/easily accessible like your system memory is. And getting that data back/forth over the bus is slow. It's also costly, requiring an entire additional render pass (worst case, halving your frame rate) plus you have all that extra graphics RAM used up... all just to do something like collision-detect. Much better schemes exist, especially using data structures.
It's better to use bounding boxes, or even a hierarchy of sub-bounding boxes. After that, you can determine if you've landed on the other side of, say, a sloped line, requiring only division/addition operations. Your game already manages all the sprites you're moving, so integrate some data structures to help your collision detection. For instance, I just suggested in another thread the use of linked lists to limit the objects you must collision-detect against one another.
Ideas like yours might not always work, but your continual creative thinking will lead to ones that do. Sometimes you just have to try coding them to find out!