X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=core%2Fsrc%2Fru%2Fdeadsoftware%2Fcavedroid%2Fgame%2Fworld%2FGameWorldGenerator.kt;h=bc5ffa4cc4afdaf382e2b626844667fb0fe96e3e;hb=7cb80fd35da9bb41a3f2b96dd898d4bbb1e9b718;hp=dd64c6a04077d02c1cce66c567311749a304e2f1;hpb=7bd07c5544488066e1d940305f1da53138859545;p=cavedroid.git diff --git a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldGenerator.kt b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldGenerator.kt index dd64c6a..bc5ffa4 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldGenerator.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldGenerator.kt @@ -7,6 +7,13 @@ import kotlin.random.Random object GameWorldGenerator { + private const val BIOME_MIN_SIZE = 64 + + private enum class Biome { + PLAINS, + DESERT + } + private fun generateHeights(width: Int, min: Int, max: Int, random: Random) = IntArray(width).apply { set(0, (min + max) / 2) for (x in 1 until width) { @@ -22,6 +29,68 @@ object GameWorldGenerator { } } + private fun generateBiomes(width: Int, random: Random) = buildMap { + val xSequence = sequence { + var lastX = 0 + var count = 0 + + while (lastX < width - BIOME_MIN_SIZE - 1) { + yield(lastX) + + lastX = random.nextInt(lastX + BIOME_MIN_SIZE, width) + count++ + } + } + + return xSequence.associateWith { Biome.values()[random.nextInt(Biome.values().size)] } + } + + private fun plainsBiome( + foreMap: Array, + backMap: Array, + width: Int, + height: Int, + x: Int, + xHeight: Int, + random: Random, + ) { + foreMap[x][xHeight] = GameItems.getBlockId("grass") + foreMap[x][height - 1] = GameItems.getBlockId("bedrock") + backMap[x][xHeight] = GameItems.getBlockId("grass") + backMap[x][height - 1] = GameItems.getBlockId("bedrock") + + for (y in xHeight + 1 until height - 1) { + foreMap[x][y] = when { + y < xHeight + random.nextInt(5, 8) -> GameItems.getBlockId("dirt") + else -> GameItems.getBlockId("stone") + } + backMap[x][y] = foreMap[x][y] + } + } + + private fun desertBiome( + foreMap: Array, + backMap: Array, + width: Int, + height: Int, + x: Int, + xHeight: Int, + random: Random, + ) { + foreMap[x][xHeight] = GameItems.getBlockId("sand") + foreMap[x][height - 1] = GameItems.getBlockId("bedrock") + backMap[x][xHeight] = GameItems.getBlockId("sand") + backMap[x][height - 1] = GameItems.getBlockId("bedrock") + + for (y in xHeight + 1 until height - 1) { + foreMap[x][y] = when { + y < xHeight + random.nextInt(5, 8) -> GameItems.getBlockId("sand") + else -> GameItems.getBlockId("stone") + } + backMap[x][y] = foreMap[x][y] + } + } + /** * Generates world of given width and height with given seed * @param width world width @@ -34,22 +103,19 @@ object GameWorldGenerator { val foreMap = Array(width) { IntArray(height) } val backMap = Array(width) { IntArray(width) } val heightsMap = generateHeights(width, height / 2, height * 3 / 4, random) + val biomesMap = generateBiomes(width, random) + + var biome = Biome.PLAINS for (x in 0 until width) { val xHeight = heightsMap[x] + biome = biomesMap[x] ?: biome - foreMap[x][xHeight] = GameItems.getBlockId("grass") - foreMap[x][height - 1] = GameItems.getBlockId("bedrock") - backMap[x][xHeight] = GameItems.getBlockId("grass") - backMap[x][height - 1] = GameItems.getBlockId("bedrock") - - for (y in xHeight + 1 until height - 1) { - foreMap[x][y] = when { - y < xHeight + random.nextInt(5, 8) -> GameItems.getBlockId("dirt") - else -> GameItems.getBlockId("stone") - } - backMap[x][y] = foreMap[x][y] + when (biome) { + Biome.PLAINS -> plainsBiome(foreMap, backMap, width, height, x, xHeight, random) + Biome.DESERT -> desertBiome(foreMap, backMap, width, height, x, xHeight, random) } + } return Pair(foreMap, backMap) }