← Natura·Docs/Modules/Source

creatures/creatures.js

44 lines · in natura-src-1.0.0.zip as natura/creatures/creatures.js · a module · its entry in the module reference · its test: creatures/creatures.test.js

// creatures/creatures.js -- Creatures: the FACADE that composes the layers.
//
// The one public entry point. It wires the three concern-modules together and hands a caller a
// small, stable surface, so a consumer (the First Light meadow piece, or a Natura-world renderer
// drawing its agents as models) never reaches into species/render/behaviour directly:
//
//   Creatures.draw(ctx, name, x, y, dir, phase, scale, pose)   -- resolve `name`, dispatch to the
//                                                                  right body-plan builder
//   Creatures.SPEC(name)      -- the proportion def (either table)
//   Creatures.isBird(name)    -- which body plan
//   Creatures.BEH / .GALLOP / .targetOf(c, e)   -- behaviour loops + the current-segment picker
//   Creatures.mulberry / .clamp                 -- the seeded RNG + clamp, for scene use
//
// This is the "composer" in factory-and-composer terms: species.js is the factory data, render.js
// and behaviour.js are the factories/engines, and this file composes them into a usable whole.
//
// UMD. Browser: load species.js, render.js, behaviour.js FIRST (they attach to window), then this.
// Node: it requires them relatively (used by the test).
(function (root, factory) {
  if (typeof module !== 'undefined' && module.exports)
    module.exports = factory(require('./species'), require('./render'), require('./behaviour'));
  else root.Creatures = factory(root.CreatureSpecies, root.CreatureRender, root.CreatureBehaviour);
})(typeof self !== 'undefined' ? self : this, function (Species, Render, Behaviour) {
  'use strict';

  const SPEC = name => Species.get(name);
  const isBird = name => Species.isBird(name);
  const isSnake = name => Species.isSnake(name);

  // resolve a name to its def + body plan, then draw it; a no-op on an unknown name
  function draw(ctx, name, x, y, dir, phase, scale, pose) {
    const def = SPEC(name); if (!def) return;
    if (isSnake(name)) Render.drawSnake(ctx, def, name, x, y, dir, phase, scale, pose);
    else if (isBird(name)) Render.drawBird(ctx, def, name, x, y, dir, phase, scale, pose);
    else Render.drawCreature(ctx, def, name, x, y, dir, phase, scale, pose);
  }

  return {
    SPEC, isBird, isSnake, draw,
    SPECIES: Species.SPECIES, BIRDS: Species.BIRDS, SNAKES: Species.SNAKES,
    BEH: Behaviour.BEH, GALLOP: Behaviour.GALLOP, TROT: Behaviour.TROT, targetOf: Behaviour.targetOf,
    mulberry: Render.util.mulberry, clamp: Render.util.clamp, setLight: Render.setLight,
  };
});