What tile storage structure to use on a side scroller? - java

I am developing a 2d side scroller in slick2d which i would like to be tile based, but I don't really know how to store the tiles. My game has infinite dynamicly generated terrain and is interactable (a bit like a mix of minecraft and terraria). I am currently using a
Map < Integer, Map < Integer, Tile > >
object but it doesn't seem right because I need dynamic world loading and generation. I am using JBox2d for physics.
Is there any better way to store the data in a more efficient way because only a portion of the world is supposed the be loaded because the world size can become infinitly big

You should take a look at the cunk-approach (There's a good reason games like Minecraft have chunks). Select a chunk size (for example 8x8) and create a Chunk data structure (class). Inside the chunk, you can store the static tiles inside a normal Array[][] if possible (faster), or, if needed, in an ArrayList.
public class Chunk
{
private int xPosition;
private int yPosition;
private Tile[][] staticTiles;
private ArrayList<Tile> dynamicTiles;
...
public boolean isInRenderRange()
{
...
}
public boolean isInUpdateRange()
{
...
}
...
}
Then you can go ahead and create the Level data structure. I would recommend something like a basic ArrayList where you can just add and remove elements as you which. You can just iterate over all elements (chunks) in your update and render methods and check for isInRenderRange() and isInUpdateRange().
This will give you the benefit of not having to deal with very complex data-structures like multi-linked lists. You can just change each chunks x- and yPosition when moving backwards, forwards, upwards or downwards. Each tile inside the chunk should have a reference to the chunk they are in in order to get their absolute position.
If you have huge loads of chunks you can sort the ArrayList once in a while to make use of branch-prediction in the extensive render and update calls.

If you are only scrolling one way (like Mario 1) then you need something like a linked list representing the left to right transition. At each node in the linked list you want an array (or possibly a structure) of tiles representing the tiles top to bottom for one horizontal point.
You then hold a link to the current node (i.e. the vertical structure that is at the left of the screen) and each redraw you go from the current point in the linked list forward, drawing vertical strips as you go.
If you want to go backwards (like Mario 3) you'll need a doubly linked list type structure so that your start pointer can move backward.
Going up and down would require either a more complex structure or a smaller vertical representation of the linked list structure.

Related

Which method of managing an array of tiles is better?

So in this game I'm programming the "board" is an Array of tiles. I have to get which type of tile is at certain positions and move them around. Not every position that could have a tile has a tile.
I see two ways of doing this.
1) Have a 2D Array of tiles. The dimensions of the board in tiles would be equal to the dimensions of the Array. Places where there is no tile would be represented by null. These would be organized so that myArray[1][1] would refer to the tile at (1, 1).
Pros: Easy to find a tile at a specific coordinate
Cons: Seems bulky, many of the Tiles in the array will be null.
2) Have a regular unordered ArrayList of tiles. Since tiles have an x and a y component, I do not need to sort this.
Pros: Lightweight, takes less memory
Cons: When I need to find a tile at a specific coordinate I will need to use a for loop and search through every tile
Thanks :)
The question in my mind is: is it better to use a concrete array or a sparse array, and the solution (again in my mind) is "it depends". If your universe is potentially very large, then definitely use the sparse array, else you'll be wasting resources on cells that have no current relevance. If on the other hand the universe will be well limited in size, then the convenience of a concrete array (or some type of collection) will come to the fore.
You can try hashmap. Where keep the coordinate as key. And tile value at value position.
Ex pos(2,3)->2.3 so on ..
This way search and memory both can be optimized.

OpenGL 2.0 ES how does a matrix stack work?

I am having some performance problems with OpenGL. I essentially want to create a grid of squares. I first tried to implement it where each square I would translate to where I want a square, then multiply the model and view matrix, pass it into the shader program and draw the square. I would do this for each square. After creating about 50 squares the frame rate would start to drop to less than what I desire.
I then tried a VBO method where I basically would generate a vertex buffer each time the squares change location. Frame rate increased dramatically with this approach, but I have too much latency when something changes because it has to regenerate all the vertex locations.
What I think I need is a matrix stack... I used opengl 1.1 before and would use push/pop. I don't really understand the concepts of what that was doing though and how to reproduce it. Does anyone know where a good example of a matrix stack is that I can use as an example? Or possibly just a good explanation for one?
You can check this tutorial, is basically doing the same you want to achieve, but with cubes instead of squares. It uses a VBO as well:
http://www.learnopengles.com/android-lesson-seven-an-introduction-to-vertex-buffer-objects-vbos/
About the matrices, in OpenGL ES 2.0 you don't have any matrix related functions anymore, but you can use the glmath library, which does the same (and much more):
http://glm.g-truc.net/
It's a header library, so you just need to copy it somewhere and include it where you need it.
I'm not sure if I completely understand your objective, but I guess you could copy the data of one square in the grapic card (using a VBO) and then repeatedly update the model matrix for every square.
The concept of a matrix stack makes sense if your squares have some kind of hierarchy between them (for instance, if one of them moves, the one to its left has to move accordingly).
You can imagine it as a skeleton made out of squares. If the shoulder moves, all the pieces in the arm will move as well (hands, fingers, and so on).
You can emulate that by using a matrix stack. You can create some kind of tree with all your squares, so that every square has a list of "descendants", which will apply the same transformation as the parent. then you can render recursively all the squares like that:
Apply transform to the root square(s)
Push the transform in a queue
Call the same render function for every child
Every child reads the matrix on the top of the queue, multiplies
it by its own transformation, push the new matrix on the queue and
calls the children
After that every child pops out the matrix they pushed before
Using the glmath is quite easy, you just need to create a queue (std:vector in this case) of matrices:
std::vector<glm::mat4> matrixStack;
And then for every child:
glm::mat4 modelMatrix = matrixStack.back();
glm::mat4 nodeTransform = /*apply your transform here*/
glm::mat4 new = modelMatrix * nodeTransform;
matrixStack.push_back(new);
/*Pass in the new matrix to the shader and call to glDrawArrays or whatever to render your square*/
for (every child) {
render();
}
matrixStack.pop_back();
For the drawing part, I guess you could bind the vertex array with the square vertices, and then update the model matrix in the shader for every child, before calling glDrawArrays.

What is the correct way to place objects in their places on a grid using OpenGL?

For the sake of argument, let's say I want to place a wall object (for simplicity, let's pretend it's just a 1x1 square) on a 2d grid which is 20x20. Let's say I have the object modeled out in coordinates between 0 and 1.
So, my question is, using openGL in the correct manner (I realize there are plenty of ways I could change the coordinates manually, but that doesn't edify me for the future), how do I place this object on the grid in the location (5,5)? Would it be related to the model matrix?
Yes, I think you have the right idea.
If your wall exists in model space from (0,0) to (1,1), and you want to position a particular instance of this wall at (5,5) through (6,6), than an appropriate thing to do would be to draw this wall with a Model Matrix that is translated by 5 units in the x and y direction.
You should not use the transformation matrices to place single primitives. Everytime you change a uniform (aka matrix) it's very likely the rasterizer pipline must be flushed, which is a sure performance killer.
As a general rule, to be efficient, a given transformation matrix should be applied to at least 100 primitives within a scene. So if you have some grid of tiles, it's better to either duplicate-translate them into a larger Vertex Array, or use instancing (if available).

creating a grid of rectangles dynamically

I wanted to create Conway's Game of Life. I read the Java 2d API, but the Graphics class only provides methods to drawRect() and fillRect() on the paintComponent of a JPanel. I mean that the rectangles cannot be handled individually as objects i.e. so that i can check which one is on in relation to the ones in the vicinity.
So I wanted to ask how are squares to be made so that they can be handled individually and the grid be created dynamically?
Create a Sqaure class with all properties required.
Create a list of Square objects representing the board.
In the draw method for the JPanel, iterate over your list of Square objects, drawing each one out, based on its properties.
Keep your display code separate from your logic as much as possible - it's nearly always a good idea.
I'd like to propose a completely different solution. Normally have to treat the generated graphics as output-only, meaning, you don't want to read state from the graphics because that'd be too slow.
You'll have to keep the state of the cells elsewhere, like in a two-dimensional array.
boolean[][] or int[][] for example.
Then you'll need a "render" method of sorts, that takes the values of your cells, and draws it out.
But I'd like to propose an even cooler way of doing this. Instead of keeping a two dimensional array, use the (one dimensional) array that a BufferedImage is made up of.
Normally, each "pixel" is an element in that array. Then you use drawImage to draw that image, and scale that image up. This could perform really well. You might be able to have an entire screen draw in real time pretty much.
There are various methods on BufferedImage, it gets a little confusing at first. In the end you'll find a DataBuffer somewhere. You'll want access to the int[].
Then, to set a cell: data[y * width + x] = -1; (white cell)
to clear a cell: data[y * width + x] = 0; (black cell)
(for example - or vice versa - or any other color).
You can get really fancy with this. You could use various offset variables instead of having to calculate the y*width+x all the time, and optimize it really well.
In fact, I go as far as being able to make it so efficient, that you could actually outperform another guy making the exact same program in C++.

Efficient algorithm for collisions in 2D game?

I'm programming a Bomberman in Java following a tutorial (this is my first game).
The tutorial suggests the following code for detecting collisions.
for (int p=0; p<entities.size(); p++) {
for (int s=p+1; s<entities.size(); s++) {
Entity me = (Entity) entities.get(p);
Entity him = (Entity) entities.get(s);
if (me.collidesWith(him)) {
me.collidedWith(him);
him.collidedWith(me);
}
}
By now, entities is an array list containing the enemies and the player.
As I want to also detect the player collides with walls, should I put every single wall or bricks tile in the level into the entities arraylist? If so, isn't this algorithm very inefficient? These tiles aren't going to collide with other tiles, so I was thinking to manage game entities in different lists. What do you suggest? Is there a more efficient algorithm to do it?
Note: I already read other questions related to collisions in 2D games.
Thanks a lot.
I suggest reading this excellent article about how ghost movement and collision detection works in PacMan.
Then I would suggest logically modeling your Bomberman levels as a collection of tiles. Each tile represents a discrete position in your level, and it is not logically possible to ever be "between" tiles or occupying two tiles at the same time. Each tile can track what sort of terrain feature is currently on it, and whether or not it is a valid destination tile for the player (and the enemies, potentially with different rules for each if the enemies are allowed to traverse terrain that is normally impassable for the player).
Then you don't need a collision detection algorithm for every object in the world. When it comes time for an enemy to move, or when the user tries to move their character, all you have to do is check all the tiles that are adjacent to their current tile (4, or 8 max if you allow diagonal movement), see if each tile represents a valid movement direction, and block the movement if it is not in a valid direction.
And to answer your question, yes, iterating every object in the world on every position update will be very inefficient.
There is another way to use grids for collision system. I'm using more complex version of the Aroth's suggestion and using this to fix collision bugs.
Theoretically this system is the fastest(assuming you are doing this check if(Grid[x][y] ==true)) because it only uses a single Boolean check for each entity(the things that can move).
Note: In the above grid check example, I've used a 2 dimensional array of booleans that sets the coordinates of impassable grids to false.`
If you are not worried about physics like bouncing from a wall you can use this:
1- Divide the map into grids.
2- Making every entity only fill a tile would be better but not necessary.
3- Store the previous position or the grid of the entities.
4- Whenever an entity moves, before visually updating their location (also before
doing other calculations) check the grids they are in. If they are in grid
that is not empty or simply in a grid that they are not supposed to
be, return their position back to the previous position (which you have stored).
If you want to allow entities to move freely inside the grids(the grids are bigger than the minimum distance they can move) then you need to put them adjacent to the grids they've entered and they weren't supposed to. Otherwise just return them back to the previous grid.
If you want them to bounce from the wall you can still use this but I'm not sure how many features can be added to a collision system like this.
May I recommend my own project. But it's still wip.
https://github.com/YagaoDirac/Dirac-2d-collision-detection-for-games
It's based on quad-tree which handles sparse pretty well.
It supplies collision group. This conception is also used in both UE and Unity.
It support only circle vs circle and overlapping only for now(2022 feb 22).
I plan to make at least AABB, and collision which at least stop your pawn from leaving the map.
I may also provide another system based on fixed grid.

Categories

Resources