# `Cauldron2D.Projection.FirstPerson`
[🔗](https://github.com/jaman/cauldron/blob/v0.2.2/cauldron_2d/lib/cauldron_2d/projection/first_person.ex#L1)

Renders the world from a point inside it, looking along a heading: standing arts as
textured walls of their height, floors textured to the horizon, movers and the
standing arts of no height as billboards, everything fading towards the atlas's void
colour with distance.

    Cauldron2D.Projection.FirstPerson.render(:my_game,
      position: {12.5, 8.5},
      heading: :math.pi() / 2,
      cell: &MyGame.cell/1,
      size: {320, 200},
      movers: [{:guard, {14.5, 8.5}, 0.0}]
    )

## Options

  * `:position` — `{x, y}` in tiles, where the eye is, required
  * `:heading` — radians, `0` along `+x`, required
  * `:cell` — `fn {x, y} -> cell end`, as `Cauldron2D.Surface` takes cells; `:void`
    ends a ray, required
  * `:size` — `{width, height}` of the picture in pixels, required
  * `:eye` — how far above the ground the eye is, in tiles, so that a figure of a given
    height looks out from its own head rather than a fixed point. A cell is one tile
    across and a storey one tile tall, so an art standing `1.5` tiles looks from about
    `1.35`; `Cauldron2D.Atlas.eye_height/2` answers for an art. Default `0.6`
  * `:pitch` — `-1.0..1.0`, how far the horizon is moved down or up the picture.
    Default `0.0`
  * `:aspect` — a pixel's width over its height, so a picture drawn into cells
    that are not square keeps its proportions. Default `1.0`
  * `:fov` — the horizontal field of view in degrees. Default `70`
  * `:range` — how many tiles away things fade out entirely. Default `24`
  * `:sky` — `{top, bottom}` colours above the horizon. Default a blue gradient
  * `:movers` — `[{art, {x, y}}]` or `[{art, {x, y}, heading}]`; a mover shows its
    `:front` pose when heading towards the eye, `:back` away, `:side` across
    (mirrored one way); with no heading it faces the eye. Default `[]`
  * `:volumes` — coloured regions of space, as `Cauldron2D.Projection.Volume`
    describes them, tinting whatever the eye sees through them and nothing in front of
    them. Default `[]`
  * `:at` — the time in milliseconds an animated art's frame is chosen for. Default `0`

A wall is the cell's standing arts stacked, base first then its overlays in order,
each the storeys of its height with the face towards the eye — `:north`, `:east`,
`:south` or `:west`, else `:side` — as its texture, repeated per storey. A floor is
the base's `:top` face. An
overlay of height `0` stands at its tile's centre facing the eye, drawn as a mover
with no heading is, at its own size against the tile.

# `option`

```elixir
@type option() ::
  {:position, {number(), number()}}
  | {:heading, number()}
  | {:cell, ({integer(), integer()} -&gt; Cauldron2D.Surface.cell())}
  | {:size, {pos_integer(), pos_integer()}}
  | {:pitch, number()}
  | {:aspect, number()}
  | {:fov, number()}
  | {:eye, number()}
  | {:range, number()}
  | {:sky, {{byte(), byte(), byte()}, {byte(), byte(), byte()}}}
  | {:movers, [tuple()]}
  | {:volumes, [map()]}
  | {:at, integer()}
```

# `render`

```elixir
@spec render(Cauldron2D.Atlas.name() | Cauldron2D.Atlas.t(), [option()]) ::
  FrenchCurve.Raster.t()
```

The picture, as the module documentation describes.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
