Adding trees to random terrains in Enu 0.2

Read the first part →

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:

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:

 
3
Kudos
 
3
Kudos

Now read this

Generating random terrains in Enu 0.2

Enu is an interactive programming sandbox that helps learn programming through game creation. The author made it with children convenience in mind so it’s great for teaching kids programming. Just days ago, a long-awaited Enu 0.2 was... Continue →