Учебник РНР (перевод Alexandr Pyramidin) Размещено на PHPClub.Net
Назад Вперёд

SWFAction

(PHP 4 >= 4.0.5)

SWFAction - создаёт новую Action/Акцию.

Описание

new swfaction (string script)

Предупреждение!

Эта функция - ЭКСПЕРИМЕНТАЛЬНАЯ. Поведение, имя и всё остальное, что задокументировано для данной функции может быть изменено в будущих релизах РНР без предупреждения. Вы можете использовать эту функцию только на свой страх и риск.

swfaction() создаёт новую Action и компилирует данный скрипт в SWFAction-объект.

Синтаксис скрипта основан на языке C, но большими изъятиями - машина SWF-байтокода очень сильно упрощена. К примеру, мы не может реализовать вызовы функции без большого объёма дополнительной работы, поскольку jump-байтокод имеет жёстко кодированное значение смещения. Без push вашего вызывающего адреса в стэк и возвращения - каждой функции необходимо будет знать точно, куда возвращать.

Что же осталось? Компилятор распознаёт следующие лексемы:

  • break

  • for

  • continue

  • if

  • else

  • do

  • while

Типизированные данные отсутствуют; все значения в SWF action-машине хранятся как строки.
Следующие функции можно использовать в выражениях:

time()

Возвращает количество миллисекунд (?), прошедших после старта клипа.

random(seed)

Возвращает псевдо-случайное число в диапазоне 0-посеянное.

length(expr)

Возвращает длину данного выражения.

int(number)

Возвращает данное число, округлённое в сторону уменьшения до ближайшего integer.

concat(expr, expr)

Возвращает конкатенацию данных выражений.

ord(expr)

Возвращает ASCII-код данного символа

chr(num)

Возвращает символ с данным ASCII-кодом

substr(string, location, length)

Возвращает подстроку длиной length в точке location данной строки string

Кроме того, можно использовать следующие команды:

duplicateClip(clip, name, depth)

Дублирует именованный movie-клип (как sprite/спрайт). Новый movie-клип имеет имя name и глубину depth.

removeClip(expr)

Удаляет именованный movie-клип.

trace(expr)

Записывает данное выражение в trace log. Сомнительно, что plugin браузера сделает с ним что-нибудь.

startDrag(target, lock, [left, top, right, bottom])

Начинает перетаскивание целевого movie-клипа. Аргумент lock указывает, блокируется ли мышь (?) - 0 (FALSE) или 1 (TRUE). Необязательные параметры определяют границы области для перетаскивания.

stopDrag()

Остановить перетаскивание movie-клипа.

callFrame(expr)

Вызвать именованный кадр как

getURL(url, target, [method])

Загрузить данный URL в именованный target. Аргумент target соответствует целям HTML-документа (таким как "_top" или "_blank"). Необязательный аргумент method может быть POST или GET, если вы хотите отправить переменные обратно на сервер.

loadMovie(url, target)

Загружает данный URL в именованный target. Аргументом target может быть имя кадра (я думаю) или одно из магических значений: "_level0" (заместить текущий клип) или "_level1" (загрузить новый movie поверх текущего movie).

nextFrame()

Перейти в следующему кадру.

prevFrame()

Перейти к последнему (или всё же - к предыдущему?) кадру.

play()

Начать проигрывание movie.

stop()

Остановить проигрывание movie.

toggleQuality()

Переключает между высоким и низким качеством.

stopSounds()

Остановить проигрывание всех звуков.

gotoFrame(num)

Перейти к кадру номер num. Номера кадров начинаются с 0.

gotoFrame(name)

Перейти к именованному кадру name. Что даёт много хорошего, если я ещё не добавил ярлыки кадров.

setTarget(expr)

Устанавливает контекст акции. Или, как говорится - я не знаю, что  она действительно делает.

Есть и ещё нечто сверхъестественное. Выражение frameLoaded(num) может использоваться в операторах if и циклах while для проверки того, может ли данный кадр с номером быть загружен.
Это предполагается, ноя не тестировал её и сильно сомневаюсь, что она действительно работает. Вместо этого вы можете использовать просто /:framesLoaded.

Movie-клипы (с этого момента всё это - спрайты) имеют свойства. Вы можете читать все их и устанавливать некоторые из них:

  • x

  • y

  • xScale

  • yScale

  • currentFrame - (read-only)

  • totalFrames - (read-only)

  • alpha - уровень прозрачности

  • visible - 1=on, 0=off (?)

  • width - (read-only)

  • height - (read-only)

  • rotation

  • target - (read-only) (???)

  • framesLoaded - (read-only)

  • name

  • dropTarget - (read-only) (???)

  • url - (read-only) (???)

  • highQuality - 1=high, 0=low (?)

  • focusRect - (???)

  • soundBufTime - (???)

Так, можно установить позицию x спрайта как /box.x = 100;. Но почему слэш перед box? Таким способом flash отслеживает спрайты в клипе, точно как в файловой системе unix - здесь показано, что box находится на верхнем уровне. Если именованный бокс спрайта имел внутри себя другой именованный спрайт, вы можете установить его x-позицию: /box/biff.x = 100;. Как минимум, я так думаю; исправьте меня, если это не так (здесь и далее в этом файле это комментарии автора - прим. перев.).

Этот простой пример перемещает красный квадрат через окно.

Пример 1. swfaction()

<?php
 $s = new SWFShape();
  $f = $s->addFill(0xff, 0, 0);
  $s->setRightFill($f);

  $s->movePenTo(-500,-500);
  $s->drawLineTo(500,-500);
  $s->drawLineTo(500,500);
  $s->drawLineTo(-500,500);
  $s->drawLineTo(-500,-500);

  $p = new SWFSprite();
  $i = $p->add($s);
  $i->setDepth(1);
  $p->nextFrame();

  for($n=0; $n<5; ++$n)
  {
    $i->rotate(-15);
    $p->nextFrame();
  }

  $m = new SWFMovie();
  $m->setBackground(0xff, 0xff, 0xff);
  $m->setDimension(6000,4000);

  $i = $m->add($p);
  $i->setDepth(1);
  $i->moveTo(-500,2000);
  $i->setName("box");

  $m->add(new SWFAction("/box.x += 3;"));
  $m->nextFrame();
  $m->add(new SWFAction("gotoFrame(0); play();"));
  $m->nextFrame();

  header('Content-type: application/x-shockwave-flash');
  $m->output();
?>

Следующий простой пример отслеживает вашу мышь на экране.

Пример 2. swfaction()

<?php

  $m = new SWFMovie();
  $m->setRate(36.0);
  $m->setDimension(1200, 800);
  $m->setBackground(0, 0, 0);

  /* спрайт трэкинга мыши - пустой, но следует за мышью, так что мы можем
     получить её x и y координаты */

  $i = $m->add(new SWFSprite());
  $i->setName('mouse');

  $m->add(new SWFAction("
    startDrag('/mouse', 1); /* '1' означает блокировать спрайт на мыши */
  "));

  /* можно также отключить antialiasing, поскольку это просто квадраты */

  $m->add(new SWFAction("
    this.quality = 0;
  "));

  /* morphing box */
  $r = new SWFMorph();
  $s = $r->getShape1();

  /* Заметьте, это backwards нормальных фигур. Не знаю, зачем. */
  $s->setLeftFill($s->addFill(0xff, 0xff, 0xff));
  $s->movePenTo(-40, -40);
  $s->drawLine(80, 0);
  $s->drawLine(0, 80);
  $s->drawLine(-80, 0);
  $s->drawLine(0, -80);

  $s = $r->getShape2();

  $s->setLeftFill($s->addFill(0x00, 0x00, 0x00));
  $s->movePenTo(-1, -1);
  $s->drawLine(2, 0);
  $s->drawLine(0, 2);
  $s->drawLine(-2, 0);
  $s->drawLine(0, -2);

  /* контейнер спрайта для morphing box -
     это просто timeline w/ box morphing */

  $box = new SWFSprite();
  $box->add(new SWFAction("
    stop();
  "));
  $i = $box->add($r);

  for($n=0; $n<=20; ++$n)
  {
    $i->setRatio($n/20);
    $box->nextFrame();
  }

  /* этот спрайт-контейнер даёт нам возможность использовать
     один код акции многократно */

  $cell = new SWFSprite();
  $i = $cell->add($box);
  $i->setName('box');

  $cell->add(new SWFAction("

    setTarget('box');

    /* ...x обозначает x-координату parent, т.е. (..).x */
    dx = (/mouse.x + random(6)-3 - ...x)/5;
    dy = (/mouse.y + random(6)-3 - ...y)/5;
    gotoFrame(int(dx*dx + dy*dy));

  "));

  $cell->nextFrame();
  $cell->add(new SWFAction("

    gotoFrame(0);
    play();

  "));

  $cell->nextFrame();

  /* наконец, добавим пачку ячеек в movie */

  for($x=0; $x<12; ++$x)
  {
    for($y=0; $y<8; ++$y)
    {
      $i = $m->add($cell);
      $i->moveTo(100*$x+50, 100*$y+50);
    }
  }

  $m->nextFrame();

  $m->add(new SWFAction("

    gotoFrame(1);
    play();

  "));

  header('Content-type: application/x-shockwave-flash');
  $m->output();
?>

Вот то же, что и выше, но более красиво раскрашенные шарики ...

Пример 3. swfaction()

<?php

  $m = new SWFMovie();
  $m->setDimension(11000, 8000);
  $m->setBackground(0x00, 0x00, 0x00);

  $m->add(new SWFAction("

this.quality = 0;
/frames.visible = 0;
startDrag('/mouse', 1);

  "));

  // спрайт трэкинга мыши
  $t = new SWFSprite();
  $i = $m->add($t);
  $i->setName('mouse');

  $g = new SWFGradient();
  $g->addEntry(0, 0xff, 0xff, 0xff, 0xff);
  $g->addEntry(0.1, 0xff, 0xff, 0xff, 0xff);
  $g->addEntry(0.5, 0xff, 0xff, 0xff, 0x5f);
  $g->addEntry(1.0, 0xff, 0xff, 0xff, 0);

  // градиент фигуры
  $s = new SWFShape();
  $f = $s->addFill($g, SWFFILL_RADIAL_GRADIENT);
  $f->scaleTo(0.03);
  $s->setRightFill($f);
  $s->movePenTo(-600, -600);
  $s->drawLine(1200, 0);
  $s->drawLine(0, 1200);
  $s->drawLine(-1200, 0);
  $s->drawLine(0, -1200);

  // нужно сделать это спрайтом, чтобы мы могли multColor его
  $p = new SWFSprite();
  $p->add($s);
  $p->nextFrame();

  // поместить in фигуры здесь, каждый кадр своим цветом
  $q = new SWFSprite();
  $q->add(new SWFAction("gotoFrame(random(7)+1); stop();"));
  $i = $q->add($p);

  $i->multColor(1.0, 1.0, 1.0);
  $q->nextFrame();
  $i->multColor(1.0, 0.5, 0.5);
  $q->nextFrame();
  $i->multColor(1.0, 0.75, 0.5);
  $q->nextFrame();
  $i->multColor(1.0, 1.0, 0.5);
  $q->nextFrame();
  $i->multColor(0.5, 1.0, 0.5);
  $q->nextFrame();
  $i->multColor(0.5, 0.5, 1.0);
  $q->nextFrame();
  $i->multColor(1.0, 0.5, 1.0);
  $q->nextFrame();

  // наконец, код акции
  $p = new SWFSprite();
  $i = $p->add($q);
  $i->setName('frames');
  $p->add(new SWFAction("

dx = (/:mousex-/:lastx)/3 + random(10)-5;
dy = (/:mousey-/:lasty)/3;
x = /:mousex;
y = /:mousey;
alpha = 100;

  "));
  $p->nextFrame();

  $p->add(new SWFAction("

this.x = x;
this.y = y;
this.alpha = alpha;
x += dx;
y += dy;
dy += 3;
alpha -= 8;

  "));
  $p->nextFrame();

  $p->add(new SWFAction("prevFrame(); play();"));
  $p->nextFrame();

  $i = $m->add($p);
  $i->setName('frames');
  $m->nextFrame();

  $m->add(new SWFAction("

lastx = mousex;
lasty = mousey;
mousex = /mouse.x;
mousey = /mouse.y;

++num;

if(num == 11)
  num = 1;

removeClip('char' & num);
duplicateClip(/frames, 'char' & num, num);

  "));

  $m->nextFrame();
  $m->add(new SWFAction("prevFrame(); play();"));

  header('Content-type: application/x-shockwave-flash');
  $m->output();
?>

Следующий простой пример обрабатывает акции клавиатуры. (Вам, возможно нужно щёлкнуть на окне для передачи ему фокуса. И, возможно, вы должны будете также оставить мышь в кадре. Если вы знаете, как передавать фокус кнопкам программно, это не обязательно.)

Пример 4. swfaction()

<?php

  /* спрайт имеет одну букву на кадр */

  $p = new SWFSprite();
  $p->add(new SWFAction("stop();"));

  $chars = "abcdefghijklmnopqrstuvwxyz".
       "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
           "1234567890!@#$%^&/*()_+-=/[]{}|;:,.<>?`~";

  $f = new SWFFont("_sans");

  for($n=0; $nremove($i);
    $t = new SWFTextField();
    $t->setFont($f);
    $t->setHeight(240);
    $t->setBounds(600,240);
    $t->align(SWFTEXTFIELD_ALIGN_CENTER);
    $t->addString($c);
    $i = $p->add($t);
    $p->labelFrame($c);
    $p->nextFrame();
  }

  /* захватить область для кнопки - весь кадр */

  $s = new SWFShape();
  $s->setFillStyle0($s->addSolidFill(0, 0, 0, 0));
  $s->drawLine(600, 0);
  $s->drawLine(0, 400);
  $s->drawLine(-600, 0);
  $s->drawLine(0, -400);

  /* проверка нажатия клавиши кнопки, отправка спрайта в кадр */

  $b = new SWFButton();
  $b->addShape($s, SWFBUTTON_HIT);

  for($n=0; $naddAction(new SWFAction("

setTarget('/char');
gotoFrame('$c');

    "), SWFBUTTON_KEYPRESS($c));
  }

  $m = new SWFMovie();
  $m->setDimension(600,400);
  $i = $m->add($p);
  $i->setName('char');
  $i->moveTo(0,80);

  $m->add($b);

  header('Content-type: application/x-shockwave-flash');
  $m->output();

?>


Назад Оглавление Вперёд
ming_useswfversion ВверхSWFBitmap->getHeight