Advertisement

map generation

Started by September 01, 2023 10:36 PM
12 comments, last by LorenzoGatti 1 year, 2 months ago

alvaro said:
I suggest you start thinking in data structures, not just code that prints stuff on the screen.

Yes! Thanks : )

pbivens67 said:
how do get better at developing data structures?

You just need to start using them, and you'll get better with time.

Many programmers do it by planning ahead. For example, the problem and idea might be:

alvaro said:
The Level class should have data members that describe the level. It shouldn't be the case that the same function creates the level and prints it out.

Then they write a class or struct, currently just defining what data and functions may be needed:

struct GameLevel
{
	int width;
	int height;
	std::vector<int> tiles;
	
	void Init (int w, int h)
	{
		// set width and height, resize tiles to w*h, set each tile to zero
	}
	
	int GetTile (int x, int y)
	{
		return tiles[x + y*width]; 
	}
	
	int SetTile (int x, int y, int tile)
	{
		tiles[x + y*width] = tile; 
	}
	
	void Render (/* params for offst and scale */)
	{
		// loop over all tiles, set material texture and render the quad
	}
	
	bool SaveToFile (char* filename);
	
	bool LoatFromFile (char* filename);
	
};

Not much code written yet, but you already see what functionality and data the level data structure is meant to get.

You do the same for Sprites, as proposed earlier.

The most widely used data structures in games are probably to help with linear algebra, e.g.:

vec2, vec3, matrix3x3, matrix4x4, (floating point numbers)
vec2i, vec3i, (integer numbers, which we could use in our GameLevel class to handle coordinates.)

See the often proposed frameworks such as SFML or RayLib, which come with implementations of all those data structures ready to use.
You need to learn how using such data structures makes things much easier, then you will automatically come up with new data structures as needed.
But to do so, you need to get started with a first data structure for some thing you use often, like Sprites or Levels.
It's a chicken and egg problem, and a matter of experience and habits. You're very, very late with learning this, but it's mandatory. You need to get started, and after you notice the advantage and usage patterns, everything should become better.

For a longer termed learning plan, i would propose you focus on a limited topic. E.g. just 2D games with a tile map. No 3D, no isometric stuff, no complex physics. Make PacMan and Breakout using the same data structures for both.
After that, you can reuse your stuff for future projects, but you no longer need to start from scratch for everything. You have a bag of tools which you can use and extend. That's the whole point.

Let's say you have made 3 games, and then somebody tells ‘you should sort tiles by material and then draw all grass tiles, then all rock tiles, etc. It's faster because ther is less need to switch testures!’
Then you only need to modify the GameLevel::Render method once, and all 3 games will be updated and run faster.

Or, maybe all 3 games require collision detection of Sprite vs. Sprite and Sprite vs. Tiles. Again you want to code this only once, not 3 times.

But the advantage should show within a single project already. Anytime you implement similar stuff again and again (like rendering a textured quad), you should think about a function or data structure to implement this just once.

(I'm mixing topics here - 'data structures' means just bundling data in a struct. Algorithms to implement functionality of using and modifying such data is it's own topic, but nowadays with OOP we usually merge both topics.)

thx joe

Advertisement

Alberth said:
The code should be split in an initialization step that creates the array and fills it with values for the fields (ie what tile to paint at each spot in the level). Once initialization is done, your paint code must use the data stored in the array to paint the fields of the level.

You already have nested loops over each tile, you can add an outer loop over tile types (with the corresponding OpenGL textures) and draw each tile if its type matches the current texture. This would be simple and presumably efficient (repeated inner loops but minimal texture changes), but you might be able to draw fixed vertex and index buffers instead of separate primitives.

Omae Wa Mou Shindeiru

This topic is closed to new replies.

Advertisement