'Advanced 2-D Array map generation for 2D Platformer game with Java (processing)
I'm trying to figure out a way to make my simple map generation better. So the question to be specific is, how do I make my random 2-D array platform generator, less random so it looks more like a platformer game level as well as adding a bit more variables to it for adding variation to each Map Generated. Explanation below.
Currently, I have this:
void GenerateMap() {
int x = width/30;
int y = height/28;
int[][] map = new int[x][y];
//println(map.length);
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
float val = random(0, 100);
float nv = noise(val);
println(nv);
if (j <= (int) (.5 * map.length)) {
map[i][j] = nv < .3 ? 0 : 1;
} else if (j >= (int) (.7 * map.length)) {
map[i][j] = nv < .6 ? 1 : 0;
} else {
map[i][j] = nv <= .3 ? 0 : 1;
}
println(i +"-" + j + " - rowcol: " + map[i][j]);
}
}
levelMap = map;
JSONArray saveArr = arrayToJson(levelMap);
saveJSONArray(saveArr, dataPath("./maps/Generation_" + mapGenerations + ".json"), "compact");
}
It builds a 2d array with 1s and 0s, I tried to make it less random so it looks like a playable terrain. the top-most section will be 0's (air), the bottom-most will be 1's (platform). Then the middle will have a mix to make floating platforms and such. So far I've got nothing.
The next Idea that popped up was to have the number go from 0-N. This works by: 0 will always be air, 1 will always be a platform, 2 can be a platform of a different image, let's say a diagonal platform to form a slope off the edge 3 can be a collectible or anything ...etc
My issue is I can't figure out how to generate the numbers in a way that will make the map not look like a mess. I came up with a setup for my variables:
public int[] toplayer = null, // [0,0,0,0,...,0]
bottomlayer = null, // [1,1,1,1,...,1]
variation = {0,1,2}, // the 0-N
variationRatios = {60, 30, 10}; // this would specify the frequency/probability of each variation show up, respectively, in a random() function
After all, that's done, then I run a function to replace all values with their respective "Sprite" and then display them on the screen.
void drawPlatform(int amt, PVector pos, PVector size) {
for (int i = 0; i < amt; i++) {
//new Platform(new PVector(abs(width-((pos.x+(size.x/2)) + (i * size.x))), pos.y+(size.y/2)), size);
Platform p = new Platform(new PVector(abs(((pos.x+(size.x/2)) + (i * size.x))), pos.y+(size.y/2)), size);
if (platforms.indexOf(p) % 5 == 0 && !p.bouncy) {
p.bouncy = true;
}
}
}
JSONArray arrayToJson(int[][] arr) {
JSONArray ja = new JSONArray();
for (int[] ar : arr) {
JSONArray j = new JSONArray();
ja.append(j);
for (int a : ar) {
j.append(a);
}
}
return ja;
}
void LoadMap(int[][] map) {
drawPlatform(width/30, new PVector(0, 0), new PVector(30, 30)); // top
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
if (map[i][j] == 0) {
new Platform(new PVector((i*30)+15, (j*30)+45), new PVector(30, 30));
//drawPlatform(1, new PVector(i+j*30, (i+j)*30), new PVector(30, 30));
}
}
}
drawPlatform(width/30, new PVector(0, height-30), new PVector(30, 30)); // bottom
println(gameObjects.size() + " GameObjects loaded");
println(platforms.size() + " Platforms loaded");
}
Overall, this is how it's used:
GenerateMap();
LoadMap(levelMap);
mapGenerations++;
This is how it would end up looking (obviously different each generation):

But right now, I have something like this:

I've looked everywhere for a couple of days now, for a solution and can't find anything as specific as my request. If you have any ideas, please let me know.
Quick Note: Of course, we could have the user write the array by hand but that's not time-effective enough. I could also have a visual map builder but that's a lot more code and more time than I have available. I am not opposed to this idea, however.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
