Hi. I am trying to create a SideScroller in Minecraft. Therefor I created a World Generator that generates the 2D World. But one problem do I have the "Mountains" that will be created by my Generator are...yeah not mountains. They are like spikes. No I try to make a Smooth Algorithm that the Spike will more mountain like. Here a Picture of a Map: http://i.imgur.com/XObHCxG.png And here my Generator Class: Code (Text): public class Map { private GenerateProcess process; private World world; private int sX; private int sY; private int z; private int bX; private int bY; private List<MapBlock> blocks; public Map(Location loc){ bX = loc.getBlockX() - 1; bY = loc.getBlockY() - 1; sX = loc.getBlockX(); sY = loc.getBlockY(); z = loc.getBlockZ(); world = loc.getWorld(); generateBorder(); } public Map generate(){ process = new GenerateProcess(); for(int y = sY; y <= (sY + MapVars.MAX_HEIGTH); y++){ for(int x = sX; x <= (sX + MapVars.MAX_WIDTH); x++){ process.currentX = x - sX; process.currentY = y - sY; MapBlock block = MapRandom.generateMapBlock(sX, sY, process); process.endingBlocks.add(block); } } blocks = process.endingBlocks; for(MapBlock block : blocks){ setBlockSync(new Location(world, block.getPosition().getX(), block.getPosition().getY(), z), block.isSolid() ? Material.LAPIS_BLOCK : Material.AIR); try { Thread.sleep(10); } catch (InterruptedException e) { } } return this; } public List<MapBlock> getAllBlocks(){ return blocks; } public MapBlock getBlockAt(Point p){ for(MapBlock block : blocks) if(block.getPosition().equals(p)) return block; return null; } private void generateBorder(){ new Thread(new Runnable() { @Override public void run() { for(int x = bX; x <= (bX + MapVars.MAX_WIDTH + 2); x++){ for(int y = bY; y <= (bY + MapVars.MAX_HEIGTH + 2); y++){ Location loc = new Location(world, x, y, z); setBlockSync(loc, Material.COAL_BLOCK); try { Thread.sleep(1); } catch (InterruptedException e) { } } } generate(); } }).start(); } private void setBlockSync(Location loc, Material mat){ new BukkitRunnable() { @Override public void run() { loc.getBlock().setType(mat); } }.runTask(ShellCraft.getInstance()); } } And the Class which the Generator uses: Code (Text): public class MapRandom { public static MapBlock generateMapBlock(int sX, int sY, GenerateProcess process){ int cY = process.currentY; int cX = process.currentX; if(cY == 0){ return new MapBlock(MapBlockType.SOLID, new Point(cX + sX, cY + sY)); }else{ Point underPoint = new Point(cX + sX, cY + sY-1); MapBlock underBlock = process.getBlock(underPoint); if(underBlock == null) return new MapBlock(MapBlockType.AIR, new Point(cX + sX, cY + sY)); if(!underBlock.isSolid()) return new MapBlock(MapBlockType.AIR, new Point(cX + sX, cY + sY)); if(cY < MapVars.LESS_AREA){ Random random = new Random(); float f = random.nextFloat(); if(f <= 0.95) return new MapBlock(MapBlockType.SOLID, new Point(cX + sX, cY + sY)); else return new MapBlock(MapBlockType.AIR, new Point(cX + sX, cY + sY)); }else{ if(cY < MapVars.SKY_Y){ Random random = new Random(); int i = random.nextInt(3); if(i == 0 || i == 2) return new MapBlock(MapBlockType.SOLID, new Point(cX + sX, cY + sY)); else return new MapBlock(MapBlockType.AIR, new Point(cX + sX, cY + sY)); }else{ return new MapBlock(MapBlockType.AIR, new Point(cX + sX, cY + sY)); } } } } } I hope u can help me
Consider using procedural noise instead of random values. Terrain is usually generated by perlin or simplex noise. Flow noise is a library that can generate 3D noise for you. https://mvnrepository.com/artifact/com.flowpowered/flow-noise/1.0.0 Example usage: Code (Text): double noiseValue = Noise.valueCoherentNoise3D(x, y, z, seed, NoiseQuality.FAST)
I assume at the moment it just picks a random height within the range of possible heights but what you need is for the height to vary depending on the height that came before it and only increase or decrease by a smaller random amount so that you get slopes instead of bar charts.
I'd like to do it on my own and not with an library...I did it nearly...but the only thing is the smoothing
Try looking into perlin noise. I used that to generate some pretty neat terrain! If it's too complicated for you you can do something like this: Set a start height. Place a block there and fill everything underneath. On the next block, either descrease height by 1, increase by 1, or don't do anything with it. Again place a block there and fill up underneath. This is the result: https://i.gyazo.com/8ad4aac0bf53a77bb9b54497f8a15f93.gif It generates okayish terrain. You don't have much variation and you'll have to add biomes to keep it a bit interesting.
I wouldn't say that I am the best in Java but I'd like a Challenge and honestly this is a litte bit boring and too easy. Ok. I try it with Perlin Noise.
But now is the question how do I do side scroller worlds with it? And how do I use it or what should I do with the floats?
Just quickly pointing out that Bukkit has built-in noise classes that don't require NMS. Includes simplex octave, simplex noise, perlin octave and perlin noise. I prefer the Simplex octave generator; no particular reason (I heard it was faster than Perlin, too? but I don't really know; haven't tested). Pretty easy to use, too. Now, I admit I have no idea about the performance of Bukkit's implementations; I'd love if someone pointed out whether a library could be a lot faster or not.
Ok now I understand this. But how do I use this to generate a 2D SideScrolling Map. I dont understand this the noise method returns only one double so one Location how do I generate a Map!? Maybe I am stupid, or I am stucking or something else
For each x coordinate, run the method, it returns a y value for the specified x value. Together they form a coordinate. It's the highest point, so fill everything under it.
You are thinking in the right direction. What you need is interpolation (finding values between points). Interpolating random values will create an octave. Stack many octaves with different frequencies and amplitudes on each other and you will get perlin noise.