Solved LibGDX Random Coin Placement

Ahoy!

I am having a bit of a hard time figuring out how to randomly place a coin based on !null tiles on a tilemap layer. Here is what I have at the moment:
For loop through the tile maps width and height, check if cell is null, if it isn’t place a coin there.

This, of course, only runs once and places the coin at the last position it can. What I want is for it to place one in any !null tile on the layer. How can I achieve this?

My method is “populateCoin”.

Thanks!

  • A

Loop through your tiles. If each cell is not null, add it to an ArrayList.

Choose a random cell from that ArrayList, and add the coin to it.

Should I use an array of rectangles? Can you give me an example of the array list I should use?

It depends on your setup. You said you have some kind of data structure of tiles or cells. Some of those tiles or cells are null, some aren’t. You want to do something to a random not-null tile or cell.

One way to do that is to create another data structure (like an ArrayList) that contains only the eligible tiles or cells, then just choose a random index from that data structure.

How exactly you do that depends entirely on how your code is stuctured. Can you post an MCVE?

I meant more of like, what type of ArrayList can I use to store two x and y integer values? I have each tile equivalent to 1.

Something where I can do :
coins.add[x][y];

I mean, a simple Point class would do the trick.

But you presumably already have an Object that represents a Tile or Cell. What class are you currently adding the coin to? Can you show us any example code?

Sure, here is my populateCoin (or populateRupees) method.
http://pastebin.com/KQ8NangT

Essentially, I want to be able to add the X and Y positions on the layer than are !null. Then I want to be able to set one coin (coin.position.set(x, y)) to a random X, Y from that array.

Pseudocode:


List<A> nonNulls = tiles.filter(x -> x != null); // expand to loop
A selected = nonNulls.get((int) (Math.random() * nonNulls.size()));
coin.position.set(selected.position);

A is whatever gives enough information to set the coin’s position. So probably a Point-like type.

Ohhhh, right! Couldn’t I use a rectangle object for A? Rectangle positions can be accessed through position.x, and position.y.

What happened when you tried to use a Rectangle?

Like I said, a simple Point class would do the trick. Either use the Point class provided by whatever library you’re using, or create your own basic class:


class Point{
   int x;
   int y;
}

However, it seems strange to me that you don’t already have some kind of data structure in place to represent cells.

Yet another approach would be to just choose a random point until you find one that’s not null, and then place the coin there. Which approach you should take depends on which you have more of: nulls or not nulls.

I do have one, I use rectangles. I tried it and did it wrong, now corrected by BurntPizza. Thanks to the both of you! I’m going to try and get it working, I’ll update in a bit!

Good news! I was able to get it to work. :slight_smile:

Here is what I did:

	private void populateRupees(){
		TiledMapTileLayer layer = (TiledMapTileLayer)map.getLayers().get(0);
		tiles.clear();
		for(int y = 0; y <= layer.getHeight(); y++){
			for(int x = 0; x <= layer.getWidth(); x++){
				Cell cell = layer.getCell(x, y);
				if(cell != null){
					Rectangle rect = rectPool.obtain();
					rect.set(x, y, 1, 1);
					tiles.add(rect);
				}
			}
		}
		
		Rectangle randomRect = tiles.random();
		rupee.position.set(randomRect.x, randomRect.y);
		
	}

Basically, I have an array tiles that is storing rectangles for tiles. I then go through the layer and find !null cells and add them to ‘tiles’. Once done running the loop, I create a rectangle and set it to a random entry of tiles. Once done I set the position of my coin, or rupee, to the rectangles position.

Thank you both for helping me understand this. I’m trying to learn procedural generation, which has been a very scary task, and this is helping motivate me.

=)
-A

Solved! For now…