diff --git a/src/level/blockExt.ts b/src/level/blockExt.ts new file mode 100644 index 0000000..e2fc73b --- /dev/null +++ b/src/level/blockExt.ts @@ -0,0 +1,73 @@ +import type { NoiseFunction2D } from 'simplex-noise' +import {blockTypes as T, level as L, probability as P, type Block} from './def' + +function trees(r: number, i: number, row: Block[], previousRow: Block[]) { + const max = row.length - 1 + const h = i - 1 + const j = i + 1 + + if (row[i] === T.treeTopMiddle) { + if (i) { + if (row[h] === T.treeTopRight) row[h] = T.treeTopLeftMixed + else row[h] = T.treeTopLeft + } + if (i < max) row[j] = T.treeTopRight + + } else if (previousRow[i] === T.treeTopMiddle) { + row[i] = T.treeCrownMiddle + if (i) { + if (row[h] === T.treeCrownRight) row[h] = T.treeCrownLeftMixed + else row[h] = T.treeCrownLeft + } + if (i < max) row[j] = T.treeCrownRight + } else if (previousRow[i] === T.treeCrownMiddle) { + row[i] = T.treeTrunkMiddle + if (i) { + if (row[h] === T.treeTrunkRight) row[h] = T.treeTrunkLeftMixed + else row[h] = T.treeTrunkLeft + } + if (i < max) row[j] = T.treeTrunkRight + } else if (previousRow[i] === T.treeTrunkMiddle) { + row[i] = T.treeRootMiddle + if (i) { + if (row[h] === T.treeRootRight) row[h] = T.treeRootLeftMixed + else row[h] = T.treeRootLeft + } + if (i < max) row[j] = T.treeRootRight + } +} + +function ground(r: number, i: number, row: Block[], previousRow: Block[]) { + const rootParts = [T.treeRootLeft, T.treeRootMiddle, T.treeRootRight] + const prevBlock = previousRow[i] + + if (prevBlock === T.air) { + if (r < P.soilHole) row[i] = T.air + else if (row[i] === T.soil) row[i] = T.grass + } else if (rootParts.indexOf(prevBlock) >= 0) { + if (row[i] === T.soil) row[i] = T.grass + } +} + +function rock(r: number, i: number, row: Block[], previousRow: Block[]) { + if (previousRow[i] === T.soil && r < P.fray) row[i] = T.soil +} + +function underground(r: number, i: number, row: Block[], previousRow: Block[]) { + if (previousRow[i] === T.stone && r < P.fray) row[i] = T.stone +} + +export default function createBlockExtender(rand: NoiseFunction2D) { + function extendBlocks(level: number, column: number, row: Block[], previousRow: Block[]) { + for (let i = 0; i < row.length; i++) { + const r = rand(level, column + i) + + if (level < L.ground) trees(r, i, row, previousRow) + else if (level < L.rock) ground(r, i, row, previousRow) + else if (level < L.underground) rock(r, i, row, previousRow) + else underground(r, i, row, previousRow) + } + } + + return extendBlocks +} diff --git a/src/level/blockGen.ts b/src/level/blockGen.ts index 4315df8..f7c27b9 100644 --- a/src/level/blockGen.ts +++ b/src/level/blockGen.ts @@ -1,9 +1,7 @@ import type { NoiseFunction2D } from 'simplex-noise' import {blockTypes as T, level as L, probability as P, type Block} from './def' -export default function createBlockGenerator(noise2D: NoiseFunction2D) { - const rand: NoiseFunction2D = (x, y) => 0.5 + 0.5 * noise2D(x, y) - +export default function createBlockGenerator(rand: NoiseFunction2D) { // randomly generate a block // level: number, smaller is "higher" // column: number, the x-axis diff --git a/src/level/index.ts b/src/level/index.ts index 6f54946..5efc75d 100644 --- a/src/level/index.ts +++ b/src/level/index.ts @@ -1,18 +1,18 @@ import alea from 'alea' -import { createNoise2D } from 'simplex-noise' +import { createNoise2D, type NoiseFunction2D } from 'simplex-noise' import createBlockGenerator from './blockGen' +import createBlockExtender from './blockExt' import {blockTypes as T, level as L, type Block} from './def' -//import BlockGen from './first-iteration' -//import BlockExt from './second-iteration' -//import PlayerChanges from './third-iteration' export default function createLevel(width: number, height: number, seed = 'very random seed') { const prng = alea(seed) const noise2D = createNoise2D(prng) + const rand: NoiseFunction2D = (x, y) => 0.5 + 0.5 * noise2D(x, y) const _grid: Block[][] = new Array(height) - const blockGen = createBlockGenerator(noise2D) + const blockGen = createBlockGenerator(rand) + const blockExt = createBlockExtender(rand) // Apply changes, coming from the player (tocktocktock-plopp!) function change (level: number, column: number, newBlock: Block) { @@ -26,6 +26,7 @@ export default function createLevel(width: number, height: number, seed = 'very const previousRow = i ? _grid[i-1] : [] as Block[] blockGen(level, column, row, previousRow) + blockExt(level, column, row, previousRow) _grid[i] = row }