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<>()));
}
}
}
}
}
}
}