Chapter 7
Things
The things beside the road are its trees, its radio towers and its animals. We start with the animals. Here we learn how a thing becomes data, and how one function turns that data into a sprite. Here's a cow and a bull on the grass, from Safari Ride's own code:
A billboard stands in for an animal §
The ride has a lot of animals: herds of cows, some led by a bull, herds of pigs, ducks on the ponds, and an elephant at a bend in the road. The cat and the bird move, and they get chapters of their own.
Every other animal is a billboard: a flat picture of its emoji, standing on the grass and turned square to the camera, like a cardboard cutout. That takes far less code than modeling an animal, and it's charming.
A billboard faces left or right, and one that faces right is its emoji mirrored. That's the Billboard type from the “Types” chapter: an emoji, a height and a facing. We traced each emoji into polygons ahead of time, and the EmojiStill module holds them as plain data. So a billboard is data from end to end.
A species record names the animal §
A billboard animal starts from a record of the Billboard.Species type: its emoji, and how tall a grown one stands. A plain : names that type, so any module reads its fields. Here are the cow's and the bull's, from the CowHerd module:
cow : Billboard.Species
cow = { emoji: EmojiStill.cow, adult_height: Distance.metres(1.4) }
bull : Billboard.Species
bull = { emoji: EmojiStill.bull, adult_height: cow.adult_height.times(1.15) }
The bull's height comes from the cow's: cow.adult_height reads a field of the cow record, and .times(1.15) is a method call on that Distance. So the bull derives from the cow, and a change to the cow's height carries over to the bull.
A function picks the calves §
A herd looks better with a few calves in it. A herd's cows count from 0, and every fourth cow, starting with cow 1, is a calf: cows 1, 5, 9 and so on. A calf is a billboard half as tall as a grown cow. Here are twenty cows in a row, numbered:
One small function makes the choice:
## Every fourth cow, starting with cow 1, is a calf.
is_calf : U64 -> Bool
is_calf = |cow_number| cow_number.rem_by(4) == 1
is_calf takes a U64, a whole number from zero up, and returns a Bool, True or False. cow_number.rem_by(4) is the remainder after dividing by 4, and == compares it with 1, which gives the Bool.
A second function puts is_calf to work, and returns each cow's billboard:
## The billboard for the herd's cow at `cow_number`: young for a calf, grown
## for the rest.
cow_billboard : U64 -> Billboard
cow_billboard = |cow_number|
if is_calf(cow_number) {
Billboard.young_billboard(cow, FacesRight)
} else {
Billboard.adult_billboard(cow, FacesRight)
}
Its if picks one of two billboards: a young one when is_calf returns True, and a grown one when it returns False. A Billboard is opaque, so only the Billboard module builds one, and young_billboard and adult_billboard are two of its functions that do. CowHerd calls cow_billboard for every cow it places. So the herd's look comes down to two small functions over a number.
Every kind returns a sprite §
Calf, cow or bull, a billboard's sprite comes from a function called scenery_sprite, in the Billboard module. Every kind of thing beside the road has one, in its own module. The billboard's has a longer definition, built around a match, which the next chapter teaches, so here's its annotation alone:
scenery_sprite : Billboard, Sprite.Setting -> Sprite
It takes a Billboard and a setting, and returns a sprite. The Conifer module's scenery_sprite takes a tree instead, and the Tower module's takes a tower, but every one takes a setting and returns a sprite. A setting is a record:
## What a kind of object draws its sprite from: where it stands in the
## frame, the camera's focal length, and how dark the sky is.
Setting : {
spot : Spot,
focal_length : Pixels,
darkness : Fraction,
}
The focal_length says how strong the camera's lens is: the longer it is, the bigger everything looks, as when a camera zooms in. The darkness says how dark the sky is, from 0 by day to 1 at night, so everything beside the road can dim as night falls.
The spot comes from a camera: it's what a sighting holds. So the picture at the top of this chapter places the cow and the bull on the road by hand, the cow 10 metres ahead and 5 metres left of the middle, and sights them with a camera at the start of the road. The rider's own camera comes in the “The rider” chapter.
What comes back is a sprite, a list of shapes: for the cow, its emoji as polygons. So whatever its kind, a thing reaches the frame through one shape of function, a setting in and a sprite out.
At the bends in the road stand four more kinds of billboard animal: elephants, giraffes, zebras and rhinos. They come next, with the match that picks which ones to mirror.