1.3. Повторение задачи в течение некоторого интервала времени
Класс Timer появился в ActionScript 3.0, и он призван заменить использовавшиеся ранее функции setInterval() и setTimeout(). Будучи созданным, экземпляр класса Timer вырабатывает события timer через равные промежутки времени. Интервал между событиями и их количество можно задать в конструкторе Timer:
var timer:Timer = new Timer(delay, repeatCount);
Настройка метода, обрабатывающего эти события, осуществляется с помощью метода addEventListener. После того как таймер создан и настроен слушатель его событий, запуск и остановка таймера осуществляются с помощью методов start() и stop().
Класс Timer представляет собой часть пакета flash.utils; также есть класс TimerEvent в пакете flash.events. Их необходимо импортировать:
package {
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Example4 extends Sprite
{
// Объявляем и инициализируем переменную
// для хранения предыдущего значения таймера.
private var PreviousTime:Number = 0;
public function Example4()
{
var tTimer:Timer = new Timer(500, 10);
tTimer.addEventListener(TimerEvent.TIMER, onTimer);
tTimer.start();
}
private function onTimer(event:TimerEvent):void
{
// Выводим разницу между текущим значением таймера
// и его значением на момент последнего вызова функции.
trace(flash.utils.getTimer() - PreviousTime);
PreviousTime = flash.utils.getTimer();
}
}
}
Функция getTimer() входит в пакет flash.utils. Она возвращает количество миллисекунд, прошедших с момента запуска приложения.
В предыдущем примере интервал теоретически составляет 500 миллисекунд, но в реальности время зависит от производительности компьютера, который может выполнять и другие задачи, занимающие ресурсы процессора. Отсюда следует:
1. Не стоит полагаться на таймеры, если требуется очень высокая точность.
2. Не стоит полагаться на интервалы таймера, длительность которых меньше 10 миллисекунд.
Чтобы сымитировать работу функции setInterval() из ActionScript 2.0, счетчик повторений устанавливается на нуль, тогда события таймера будут формироваться бесконечно. В этом случае метод stop() аналогичен функции clearInterval() из AS 2.0 и прекращает формирование событий таймером.
Аналогично, если необходимо создать дубликат функции setTimeout() из AS 2.0, то счетчику повторений присваивается значение 1. Таймер ожидает заданное количество времени, формирует одно событие и останавливается.
Класс Timer позволяет создавать анимации, не зависящие от частоты смены кадров ролика, и осуществлять вызовы метода с любым интервалом.
Пример 5. Задан таймер. Один для квадратного спрайта (с частотой 50 миллисекунд).
package {
import flash.display.Sprite;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Example1 extends Sprite
{
private var square1:Sprite; // создаем объект и потом нарисуем на этом объекте квадрат
public function Example1() // тут начинается конструктор гл. кл. прогр.
{
// Создаем и отрисовываем спрайт
square1 = new Sprite(); // вызываем конструктор спрайта
square1.graphics.beginFill(0xff0000); // заливка
square1.graphics.drawRect(0, 0, 100, 100); // рисуем на square1 квадрат
square1.graphics.endFill(); // окончание заливки
addChild(square1); // добавляем square1 в список отображения
square1.x = 100; // Начальные координаты объекта square1
square1.y = 50;
// 1. Создаем таймер
var squareTimer:Timer = new Timer(50, 0); // 1. Создание таймера squareTimer
// 50 – это интервал повторения события (50 мс)
// 0 – число повторений (0 значит бесконечное число)
// 2. Добавляем слушателя onSquareTimer события TimerEvent.TIMER
squareTimer.addEventListener(TimerEvent.TIMER, onSquareTimer);
// 3. Запускаем таймер squareTimer
squareTimer.start();
}
// 4. Определяем тело метода-обработчика события таймера
private function onSquareTimer(event:TimerEvent):void
{
square1.x++; // перемещаем некоторый объект
}
}
}
Для выполнения повторяющегося в течение некоторого времени действия (или действий) можно использовать событие enterFrame спрайта. Но технология Timer предлагает некоторые преимущества по сравнению с событием enterFrame. Важнее всего, что появляется возможность создавать временные интервалы, отличающиеся от частоты смены кадров, а в случае применения enterFrame обработчик вызывается с частотой смены кадров.
Существуют ситуации, когда лучше применять enterFrame. Например, что-то должно происходить с частотой смены кадров. Один из таких сценариев - воспроизведение кадров клипа в обратном порядке.
Задача 2. Переместить 2 шарика по таймеру. См. каталог primer2.
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.utils.Timer;
public class Example1 extends Sprite
{
// Переменные для 1-го шара
var stepy:Number;
var stepx:Number;
var ball1:ball;
var n:int;
var dir:int;
// Переменные для 2-го шара
var stepy2:Number;
var stepx2:Number;
var ball2:ball;
var n2:int;
var dir2:int;
public function Example1()
{
// Для 1-го шара
n = 50;
dir = 0; // задает направление движение. Если dir = 0, то шар движется из
// (550;0) в (0; 400). Если dir = 1, то шар движется из (0;400) в (550;0).
stepy = 400 / n; // Рассчитывается шаг перемещения по оси y
stepx = 550 / n; // Рассчитывается шаг перемещения по оси x
ball1 = new ball();
addChild(ball1);
ball1.x = 550; // Задание начальное координаты шара по оси x
ball1.y = 0; // Задание начальное координаты шара по оси y
var timer1:Timer = new Timer(50, 0);
timer1.addEventListener(TimerEvent.TIMER, fun1);
timer1.start();
// Для 2-го шара
n2 = 50;
dir2 = 0; // задает направление движение. Если dir = 0, то шар движется из
// (0;0) в (550; 400). Если dir = 1, то шар движется из (550;400) в (0;0).
stepy2 = 400 / n; // Рассчитывается шаг перемещения по оси y
stepx2 = 550 / n; // Рассчитывается шаг перемещения по оси x
ball2 = new ball();
addChild(ball2);
ball2.x = 0; // Задание начальное координаты шара по оси x
ball2.y = 0; // Задание начальное координаты шара по оси y
var timer2:Timer = new Timer(40, 0);
timer2.addEventListener(TimerEvent.TIMER, fun2);
timer2.start();
}
private function fun1(event:TimerEvent):void
{ // Листенер для 1-го таймера
if (dir == 0)
{ // Шар движется из (550;0) в (0; 400)
ball1.y += stepy;
ball1.x -= stepx;
if (ball1.x < 0)
dir = 1; // Изменение направления движения шара
}
else { // Шар движется из (0;400) в (550;0)
ball1.y -= stepy;
ball1.x += stepx;
if (ball1.x > 550)
dir = 0; // Изменение направления движения шара
}
}
private function fun2(event:TimerEvent):void
{
switch(dir2)
{
case 0: // если dir2 == 0
ball2.y += stepy2;
ball2.x += stepx2;
if (ball2.x > 550 - ball2.width/2)
dir2 = 1; // Изменение направления движения шара
break;
case 1: // если dir2 == 1
ball2.y -= stepy2;
ball2.x -= stepx2;
if (ball2.x < 0 + ball2.width/2)
dir2 = 0; // Изменение направления движения шара
break;
} // конец switch
}
}
}
Задания к 3-й лабораторной работе: написать две программы:
Два шарика перемещаются по событию ENTER_FRAME;
Два шарика перемещаются по событию TIMER.
Требования: к листенерам должны быть построены блок-схемы. Использовать оператор switch.
Варианты:
Задания пониженной сложности: переместить 2 шарика:
