forked from jzitnik/twodcraft
122 lines
4.1 KiB
Java
122 lines
4.1 KiB
Java
package cz.jzitnik.game.generation;
|
|
|
|
import cz.jzitnik.game.entities.Block;
|
|
import cz.jzitnik.game.Game;
|
|
import cz.jzitnik.game.SpriteLoader;
|
|
import cz.jzitnik.game.entities.items.ItemBlockSupplier;
|
|
import cz.jzitnik.game.entities.items.ItemType;
|
|
import cz.jzitnik.game.sprites.Steve;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.Random;
|
|
import java.util.concurrent.CopyOnWriteArrayList;
|
|
|
|
public class Generation {
|
|
public static void generateWorld(Game game) {
|
|
var world = game.getWorld();
|
|
initializeWorld(world);
|
|
|
|
Block steveBlock = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
|
steveBlock.setSpriteState(Steve.SteveState.FIRST);
|
|
steveBlock.setGhost(true);
|
|
Block steveBlock2 = new Block("steve", SpriteLoader.SPRITES.STEVE);
|
|
steveBlock2.setSpriteState(Steve.SteveState.SECOND);
|
|
steveBlock2.setGhost(true);
|
|
|
|
int[] terrainHeight = generateTerrain();
|
|
|
|
game.getPlayer().setPlayerBlock1(steveBlock);
|
|
game.getPlayer().setPlayerBlock2(steveBlock2);
|
|
|
|
populateWorld(world, terrainHeight);
|
|
plantTrees(world, terrainHeight);
|
|
|
|
// Spawn player at a valid starting point
|
|
world[terrainHeight[256] - 1][256].add(steveBlock2);
|
|
world[terrainHeight[256] - 2][256].add(steveBlock);
|
|
}
|
|
|
|
private static void initializeWorld(List<Block>[][] world) {
|
|
for (int i = 0; i < 256; i++) {
|
|
for (int j = 0; j < 512; j++) {
|
|
world[i][j] = new CopyOnWriteArrayList<>();
|
|
}
|
|
}
|
|
}
|
|
|
|
private static int[] generateTerrain() {
|
|
Random random = new Random();
|
|
int baseHeight = 120;
|
|
int[] terrainHeight = new int[512];
|
|
|
|
terrainHeight[0] = baseHeight;
|
|
for (int i = 1; i < 512; i++) {
|
|
int heightChange = random.nextInt(3) - 1;
|
|
terrainHeight[i] = Math.max(100, Math.min(140, terrainHeight[i - 1] + heightChange));
|
|
}
|
|
|
|
for (int i = 2; i < 510; i++) {
|
|
terrainHeight[i] = (terrainHeight[i - 1] + terrainHeight[i] + terrainHeight[i + 1]) / 3;
|
|
}
|
|
|
|
return terrainHeight;
|
|
}
|
|
|
|
private static void populateWorld(List<Block>[][] world, int[] terrainHeight) {
|
|
for (int i = 0; i < 512; i++) {
|
|
int hillHeight = terrainHeight[i];
|
|
|
|
world[hillHeight][i].add(ItemBlockSupplier.getBlock("grass"));
|
|
|
|
for (int j = 1; j <= 4; j++) {
|
|
if (hillHeight + j < 256) {
|
|
world[hillHeight + j][i].add(ItemBlockSupplier.getBlock("dirt"));
|
|
}
|
|
}
|
|
|
|
for (int j = hillHeight + 5; j < 250; j++) {
|
|
world[j][i].add(ItemBlockSupplier.getBlock("stone"));
|
|
}
|
|
|
|
world[255][i].add(new Block("bedrock", SpriteLoader.SPRITES.BEDROCK));
|
|
}
|
|
|
|
for (List<Block>[] lists : world) {
|
|
for (List<Block> list : lists) {
|
|
list.addFirst(new Block("air", SpriteLoader.SPRITES.AIR, true, false));
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void plantTrees(List<Block>[][] world, int[] terrainHeight) {
|
|
Random random = new Random();
|
|
for (int i = 10; i < 502; i += random.nextInt(20) + 20) {
|
|
int treeBase = terrainHeight[i];
|
|
|
|
if (treeBase - 3 < 0) continue;
|
|
|
|
for (int j = 0; j < 3; j++) {
|
|
if (treeBase - j >= 0) {
|
|
world[treeBase - j - 1][i].add(ItemBlockSupplier.getBlock("oak_log"));
|
|
}
|
|
}
|
|
|
|
int leafY = treeBase - 4;
|
|
|
|
for (int layer = 0; layer < 3; layer++) {
|
|
int size = 5 - (layer * 2);
|
|
int offsetY = leafY - layer;
|
|
|
|
for (int dx = -size / 2; dx <= size / 2; dx++) {
|
|
for (int dy = -size / 2; dy <= size / 2; dy++) {
|
|
if (i + dx >= 0 && i + dx < world[0].length && offsetY >= 0) {
|
|
world[offsetY][i + dx].add(new Block("oak_leaves", SpriteLoader.SPRITES.OAK_LEAF, 1, ItemType.SHEARS, new ArrayList<>()));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|