Выразительный JavaScript (Хавербеке) - страница 78

>  }

>};

Новый метод >letAct проверяет, было ли передано хоть какое-то действие, затем – есть ли функция, обрабатывающая его, и в конце – возвращает ли эта функция >true, показывая, что действие выполнено успешно. Обратите внимание на использование >call, чтобы дать функции доступ к мировому объекту через >this.

Если действие по какой-либо причине не сработало, действием по умолчанию для существа будет ожидание. Он теряет 0,2 единицы энергии, а когда его уровень энергии падает ниже нуля, он умирает и исчезает с сетки.

Обработчики действий

Самое простое действие – рост, его используют растения. Когда возвращается объект action типа >{type: "grow"}, будет вызван следующий метод-обработчик:

>actionTypes.grow = function(critter) {

>  critter.energy += 0.5;

>  return true;

>};

Рост всегда успешен и добавляет половину единицы к энергетическому уровню растения.

Движение получается более сложным.

>actionTypes.move = function(critter, vector, action) {

>  var dest = this.checkDestination(action, vector);

>  if (dest == null ||

>      critter.energy <= 1 ||

>      this.grid.get(dest) != null)

>    return false;

>  critter.energy -= 1;

>  this.grid.set(vector, null);

>  this.grid.set(dest, critter);

>  return true;

>};

Это действие вначале проверяет, используя метод >checkDestination, объявленный ранее, предоставляет ли действие допустимое направление. Если нет, или же в том направлении не пустой участок, или же у существа недостаёт энергии – >move возвращает >false, показывая, что действие не состоялось. В ином случае он двигает существо и вычитает энергию.

Кроме движения, существа могут есть.

>actionTypes.eat = function(critter, vector, action) {

>  var dest = this.checkDestination(action, vector);

>  var atDest = dest != null && this.grid.get(dest);

>  if (!atDest || atDest.energy == null)

>    return false;

>  critter.energy += atDest.energy;

>  this.grid.set(dest, null);

>  return true;

>};

Поедание другого существа также требует предоставления допустимой клетки направления. В этом случае клетка должна содержать что-либо с энергией, например существо (но не стену, их есть нельзя). Если это подтверждается, энергия съеденного переходит к едоку, а жертва удаляется с сетки.

И наконец, мы позволяем существам размножаться.

>actionTypes.reproduce = function(critter, vector, action) {

>  var baby = elementFromChar(this.legend,

>                             critter.originChar);

>  var dest = this.checkDestination(action, vector);

>  if (dest == null ||

>      critter.energy <= 2 * baby.energy ||

>      this.grid.get(dest) != null)

>    return false;

>  critter.energy -= 2 * baby.energy;