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 released. It boasts multiple improvements compared to the previous version but the biggest for me is the documentation. Finally, the great tool Enu is has the docs it deserves, beautiful and comprehensive.

To celebrate the new release, I decided to try and build a game with Enu and publish a tutorial on the process.

The Game #

The game I’m having in mind is a capture the flag kinda game. I’m seeing a bumpy terrain covered with trees, with monsters walking around, and a randomly placed flag. The player needs to capture the flag and not get caught my the monsters. I’d like to implement the game mechanics where the monster can see or otherwise sense the player and when it does, it rushes to the player. The player has to sneak around to remain unnoticed.

Terrain #

We’ll start with generating our terrain. This is the topic of this tutorial.

Let’s first list some basic ideas:

  1. the terrain consists of randomly placed hills
  2. a hill consists of layers placed one upon another
  3. a hill’s height is linearly proportionate to its diameter, which is random
  4. a layer is a solid circle

The plan is to implement layer first, than hill, and finally terrain with many random hills.

In Enu, there are two ways to implement something reusable: prototype and command. I’ve tried using prototypes first but it turns out they’re hard to keep track of, so we’ll use commands, which are basically just functions.

Place a regular block, select the Code tool, and click on the block. No we’re ready to start coding.

Layer #

The code for layer looks like this:

# command definition
- layer(diameter = 10):
  for circleDiameter in 1..diameter:

# convert diameter to circle length we don't care about accuracy,
# so assume the length roughly equals 3 times the diameter
    let stepCount = circleDiameter * 3

# to position the circle center at the starting point,
# move one radius to the left first
    left circleDiameter / 2

    stepCount.times:

# draw the actual circle bit and turn slightly
      forward 1
      turn 360 / stepCount

# return to the starting point
    right circleDiameter / 2

Hill #

To draw a hill, we’ll draw a number of layer one upon another:

- hill(diameter = 10):
  var
    layerDiameter = diameter
    layerNum = 1

# start underground
  down 1

  while layerDiameter > 0:
# move to the desired height
    up 1

# draw a layer there
    layer(layerDiameter)

# decrease the diameter with every layer
    layerDiameter -= layerNum

# go to the next layer
    inc layerNum

# return to the starting point
  down(layerNum-2)

Terrain #

A terrain is a random arrangement of random hills:

- randomTerrain(hillCount = 10, minHillDiameter = 5, maxHillDiameter = 60, minDistance = 30, maxDistance = 60):

  hillCount.times(hillNum):

# draw a hill
    hill(minHillDiameter..maxHillDiameter)

# turn anywhere
    turn(-180..180)

# get underground
    down 1

# move the new position
    forward(minDistance..maxDistance)       

# get back to the ground
    up 1

Result #

Finally, we call the randomTerrain command and get a random terrain:

# speed things up
speed = 100

# draw
randomTerrain(hillCount = 30)
 
41
Kudos
 
41
Kudos

Now read this

7 улучшений для Ульяновска

Я живу в Ульяновске, в общем-то, всю жизнь, почти 28 лет, и пока не планирую отсюда уезжать. Поэтому меня остро волнует судьба города. Хочу, чтобы он был комфортным для меня, моей семьи и горожан. На 2016 год надо признать, что Ульяновск... Continue →