Целевой JavaScript

В этом графическом примере с Canvas мы увидим, как простая функция делает JavaScript языком целевого программирования.

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

Показ

Цель - подпустить машину к правому краю рамы.

Код JavaScript

var car = new Image();
car.src="images/car-green.png";

var roadCanvas = document.getElementById("road");
var roadCtx = roadCanvas.getContext("2d");

function scenery() {
  roadCtx.fillStyle="white";
  roadCtx.rect(0,0,640,160);
  roadCtx.fill();
}

var xcar= 0;

car.onload=function() {
  roadCtx.drawImage(car, xcar, 60);
}	

var carInterval;
var stopFlag=false;
function startCar() {
  carInterval = setInterval(function() {
    scenery();
    roadCtx.drawImage(car, xcar, 60);
    xcar++;
    if(xcar >= 400 || stopFlag) {
      clearInterval(carInterval);
      return true;
    }	
  }, 20); 
}

HTML-код

<input type="button" value="Avancer" onClick="stopFlag=false;startCar()">
<input type="button" value="Stopper" onClick="stopFlag=true">

Возможно, можно добавить ограничение по времени, в этом случае ты просто пытаешься приблизиться к цели. Но с этим становится сложнее справиться, особенно если есть несколько объектов, которые нужно анимировать одновременно.

Однако ориентированное на цели программирование сделает все очень простым. Определяется функция «цель», которая имеет следующие аргументы:

  1. Условие, которое нужно выполнить, цель.
  2. Параметр максимальной продолжительности.
  3. И
  4. действия, которые должны быть совершены итеративно, чтобы приблизиться к цели.

Демонстрация, ориентированная на цель

Исходный код функции «цель»

var stopDuo=false;
var goal = function(condi, dur, actio) { 
    var iter = setInterval(function() {
      if(condi() || stopDuo) {
        clearInterval(iter); 
        clearTimeout(limiter);
        return;
      }
      actio();
    }, 0);
    if(dur == "&") dur = 2147483647;
    var limiter=setTimeout(function() { clearInterval(iter); }, dur);
}

Код JavaScript анимации

var orange = new Image();
orange.src="images/car-orange.png";

var green = new Image();
green.src="images/car-green.png";

var raceCanvas = document.getElementById("race");
var raceCtx = raceCanvas.getContext("2d");

var xgreen = 0;
var xorange = 0 ;

green.onload=function() {
  raceCtx.drawImage(green, xgreen, 220);
}

orange.onload=function() {
  raceCtx.drawImage(orange, xorange, 60);
}

function redraw() 
{
  raceCtx.fillStyle="white";
  raceCtx.rect(0,0,640,320);
  raceCtx.fill();
  raceCtx.drawImage(orange, xorange, 60);
  raceCtx.drawImage(green, xgreen, 220);
}

function startDuo() {
 goal( function() { return (xorange >= 400); }, "&", function() {
    redraw();
    xorange++;
 });
 goal( function() { return(xgreen >= 400); }, "&", function() {
    redraw();
    xgreen+=2;
 });
}

HTML-код

<input type="button" value="Avancer" onClick="stopDuo=false;startDuo()">
<input type="button" value="Stopper" onClick="stopDuo=true;">

Как видно, все это работает асинхронно. Обе машины двигаются одновременно, независимо друг от друга. Можно определить функцию назначения, действующую синхронно:

var goalSync=function(condi, dur, actio) { 
  stopFlag = false;
  if(dur == "&") dur = 2147483647;
  var limiter=setTimeout(function() { stopFlag=true; }, dur);
  while(stopFlag == false) {
    if(condi()) {
      clearTimeout(limiter);
      stopFlag=true;
      return;
    }
    actio();
  }
}

В этом случае машины двигались бы одна за другой.

Оба объекта являются частью фреймворка скриптол.js, используемого компилятором Script-JavaScript. Язык имеет более простой синтаксис для реализации целевой ориентации.