Created
January 2, 2019 15:12
-
-
Save hayleigh-dot-dev/6bdc49cffc5dbc52c4037de864679fa8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Generators.World exposing ( generateWorld ) | |
import List.Extra | |
import Utils.Interpolate exposing ( interpolateFloatList ) | |
import Utils.Noise as Noise | |
import Random | |
import Types exposing (..) | |
------------------------------------------------- | |
-- Main functions | |
-- Read these first to get a high-level idea of | |
-- what this module does. | |
generateWorld : World -> List Tile | |
generateWorld params = | |
List.range 0 (params.height - 1) | |
|> List.concatMap (\row -> List.Extra.zip | |
(List.range 0 params.width) | |
(List.repeat params.width row) ) | |
|> List.map (generateTile params) | |
generateTile : World -> (Int, Int) -> Tile | |
generateTile params (x, y) = | |
let | |
nx = (toFloat x) / (toFloat params.width) | |
ny = (toFloat y) / (toFloat params.height) | |
tg = calculateScalar params.terrainGradient (nx, ny) | |
cg = calculateScalar params.climateGradient (nx, ny) | |
noise = positiveNoise params.seed params.scale nx ny | |
in | |
( generateTerrain noise params.octaves params.persistence tg, | |
generateClimate noise cg ) | |
generateTerrain : Float -> List Int -> Float -> Float -> Int | |
generateTerrain noiseVal octaves persistence gradient = | |
List.repeat (List.length octaves) persistence | |
|> List.indexedMap (\i n -> n ^ (toFloat i)) | |
|> List.Extra.zip octaves | |
|> List.foldl (\(oct, amp) el -> el + (noiseVal * amp) / (1 + (toFloat oct))) 0 | |
|> (*) gradient | |
|> (*) 8 | |
|> floor | |
|> min 7 | |
generateClimate : Float -> Float -> Int | |
generateClimate noiseVal gradient = | |
noiseVal * gradient | |
|> (*) 3 | |
|> floor | |
|> min 2 | |
------------------------------------------------- | |
-- Utility functions | |
-- These functions exist to reduce the vertical | |
-- footprint of the "main" functions while also | |
-- serving as their own documentation of what | |
-- this module does. | |
calculateScalar : Gradient -> (Float, Float) -> Float | |
calculateScalar gradient (nx, ny) = | |
let | |
x = interpolateFloatList gradient.x nx | |
y = interpolateFloatList gradient.y ny | |
in | |
max (x * y) (min x y) | |
-- Perlin / Simplex noise produces values between | |
-- -1 and 1. | |
positiveNoise : Int -> Float -> Float -> Float -> Float | |
positiveNoise seed scale nx ny = | |
Random.initialSeed seed | |
|> Noise.permutationTable | |
|> Tuple.first | |
|> Noise.noise2d | |
|> (\noise2d -> ((noise2d (nx * scale) (ny * scale)) + 1) / 2) | |
------------------------------------------------- | |
-- Internal types | |
-- These types aren't used outside of this module | |
-- but they help to clean up function signatures. | |
type alias Gradient = { | |
x : List Float, | |
y : List Float | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment