package cz.jzitnik.game.generation; import cz.jzitnik.game.Block; import cz.jzitnik.game.Game; import cz.jzitnik.game.SpriteLoader; import cz.jzitnik.game.items.ItemBlockSupplier; import cz.jzitnik.game.items.ItemType; import cz.jzitnik.game.sprites.Steve; import java.util.ArrayList; import java.util.List; import java.util.Random; 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); Block steveBlock2 = new Block("steve", SpriteLoader.SPRITES.STEVE); steveBlock2.setSpriteState(Steve.SteveState.SECOND); game.getPlayer().setPlayerBlock1(steveBlock); game.getPlayer().setPlayerBlock2(steveBlock2); int[] terrainHeight = generateTerrain(); 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[][] world) { for (int i = 0; i < 256; i++) { for (int j = 0; j < 512; j++) { world[i][j] = new ArrayList<>(); } } } 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[][] world, int[] terrainHeight) { for (int i = 0; i < 512; i++) { int hillHeight = terrainHeight[i]; world[hillHeight][i].add(ItemBlockSupplier.Blocks.grass()); for (int j = 1; j <= 4; j++) { if (hillHeight + j < 256) { world[hillHeight + j][i].add(ItemBlockSupplier.Blocks.dirt()); } } for (int j = hillHeight + 5; j < 250; j++) { world[j][i].add(ItemBlockSupplier.Blocks.stone()); } world[255][i].add(new Block("bedrock", SpriteLoader.SPRITES.BEDROCK)); } for (List[] lists : world) { for (List list : lists) { list.addFirst(new Block("air", SpriteLoader.SPRITES.AIR, true, false)); } } } private static void plantTrees(List[][] 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.Blocks.oakLog()); } } 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<>())); } } } } } } }