Adding trees to random terrains in Enu 0.2
In this tutorial, I’ll add some trees to the random terrain that we’ve created last time. For the impatient, here is the complete code: https://gist.github.com/moigagoo/d40a76beee5a62d2fec7679ebc033730
As before, let’s first write down the basic ideas:
- trees grow on hills
- a tree consists of a trunk and a crow
- to draw the crown, I’ll use layers from the previous part
Tree #
Here’s the command that draws a tree:
- tree(height = 5, width = 3):
let
# trees use their own colors so we need to preserve the original one
defaultColor = color
# a tree is roughly half trunk and half crown
trunkHeight = height div 2
crownHeight = height - trunkHeight
# we'll build from the top down, so first we got up
up height - 1
height.times(stepNum):
# if we're still within the crown height, draw green layers
if stepNum < crownHeight:
color = green
layer 1..width
# if we're on the last crown level, switch to black
if stepNum == crownHeight - 1:
color = black
# go to the next level
down 1
# revert the color
color = defaultColor
Hill #
Now we need to incorporate trees in hill generation. We’ll use a param called treeDensity
to define how dense we want the resulting forest to be. When we draw a layer, we’ll try and place trees depending on the layer diameter and treeDensity
.
# introduce tree-related arguments
- hill(diameter = 10, treeDensity = 3, treeMinHeight = 2, treeMaxHeight = 10, treeMinWidth = 2, treeMaxWidth = 10):
var
layerDiameter = diameter
layerNum = 1
down 1
while layerDiameter > 0:
up 1
layer(layerDiameter)
# this is the new part where we plant the trees
# the number 5 was chosen subjectively through trial and error
(layerDiameter div 5).times:
# we give each tree a `treeDensity` chance to get planted
if treeDensity in 10:
# we want trees to be placed randomly on the layer edge
# turn to the random direction
turn(-180..180)
# go to the edge
forward layerDiameter / 2
# get out of the layer
up 1
# plant the tree
tree(treeMinHeight..treeMaxHeight, treeMinWidth..treeMaxWidth)
# return to the layer center
back layerDiameter / 2
layerDiameter -= layerNum
inc layerNum
down(layerNum-2)
Terrain #
Finally, we need to add tree-related params to our terrain generation command and pass them to the hill generating command.
# add the same arguments that we added earlier to `hill``
- randomTerrain(hillCount = 10, minHillDiameter = 5, maxHillDiameter = 60, minDistance = 30, maxDistance = 60, treeDensity = 5, treeMinHeight = 2, treeMaxHeight = 30, treeMinWidth = 5, treeMaxWidth = 10):
hillCount.times(hillNum):
down 1
forward(minDistance..maxDistance)
up 1
# pass the tree-related params to `hill`
hill(minHillDiameter..maxHillDiameter, treeDensity, treeMinHeight, treeMaxHeight, treeMinWidth, treeMaxWidth)
turn(-180..180)
speed = 100
randomTerrain(30)
Here’s the end result: