/potapenko.com/articles/conveyor (part 6)/

Анимируем

Перейдем к методам ставок.

Нам нужно переместить мувиклипы со стопками фишек в нужное положение (выигрыш – к игроку, проигрыш – к дилеру).


private function win() 
{
var bet = this.bet_mc;
var end_point = _root.player_mc;

var numSteps =
Math.floor(
Math.sqrt(
Math.abs(end_point._x-bet._x)+
Math.abs(end_point._y-bet._y)
)/5);

// двигаем по гипотенузе
// по пять пикселей к игроку
for (var i=1;i<numSteps;i++)
{
Conv.put(bet, "_x", 0,
bet._x+
((end_point._x-bet._x)/
(numSteps/i)));

Conv.put(bet, "_y", "1",
bet._y+
((end_point._y-bet._y)/
(numSteps/i)));

}

Conv.put(bet, "_x", "1",
end_point._x);

Conv.put(bet, "_y", 0,
end_point._y);

Conv.put(bet, "setBet", 0, 0);
}
private function loose() 
                         { 
   var bet = this.bet_mc; 
   var end_point = _root.dealer_mc; 
   
   var numSteps = 
   Math.floor( 
     Math.sqrt( 
     Math.abs(end_point._x-bet._x)+ 
     Math.abs(end_point._y-bet._y) 
   )/5); 
   
   // двигаем по гипотенузе 
   // по пять пикселей к дилеру
   for (var i=1;i<numSteps;i++) 
   { 
   Conv.put(bet, "_x", 0, 
     bet._x+
     ((end_point._x-bet._x)/
     (numSteps/i))); 
   
   Conv.put(bet, "_y", "1", 
     bet._y+
     ((end_point._y-bet._y)/
     (numSteps/i))); 
   } 
   
   Conv.put(bet, "_x", "1",
     end_point._x); 
   
   Conv.put(bet, "_y", 0, 
     end_point._y); 
   
   Conv.put(bet, "setBet", 0, 0); 
}

Conv.anim

Все отлично. Несколько громоздко, да и код практически повторяется в двух методах. И движение было бы неплохо сделать с возрастанием скорости вначале и затуханием в конце (twinning).

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

А не сделать ли универсальный механизм для анимации с помощью конвейера? Который будет создавать действия, двигающие мувиклип в нужную нам точку. Делать список перемещений.

Да чтобы можно было с ускорением - затуханием скорости, чтобы можно было управлять скоростью движения? Да и scale пригодилось бы при анимации.

Так и сделаем. Зачем писать один и тот же код тысячу раз.

Перепишем данные два метода, но уже с использованием метода конвейера anim :


private function win() 
{ 
  var bet = this.bet_mc; 
  var end_point = _root.player_mc; 
  
  // увеличить размер 
  // стопки ставки 
  // на размер выигрыша
  
  Conv.put(bet, "setBet", "4", 
    this.bet + this.winsValue); 
  
  // анимировать движение 
  // к игроку
  Conv.anim(bet, end_point, 
    {to_end:true}) 
} 

private function loose() 
{ 
  var bet = this.bet_mc; 
  var end_point = _root.dealer_mc; 
  
  // анимировать движение 
  // к диллеру 
  Conv.anim(bet, end_point, 
    {to_end:true, speed:10}) 
}

Да, разница ощутима. Во-первых, коротко, во-вторых, скорость у анимации выигрыша сделали поменьше, чтобы продлить этот волнующий момент для игрока :)

Метод anim создает список положений мувиклипа из его первоначальной точки до точки, указанной во втором аргументе. Второй аргумент может быть не только мувиклипом, но и просто объектом с двумя обязательными параметрами: _x и _y ( {_x:20, y:120} ).

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

Задавать параметры в виде объекта в данном случае более удобно, так как если бы они задавались в виде аргументов, нам нужно было бы перечислять их все и в строгом порядке.

К новому методу мы вернемся чуть позже, а сейчас взглянем на код рулетки еще раз одним блоком.

Класс контролер:

 
//------------------------------
//  метод spin
//------------------------------
private function spin()
{
  // блокировать интерфейс
  this.lock();

  // вычислить игровой результат
  this.createGameResult(); 
  
  // начать движение колеса 
  // (время 100 кадров)
  Conv.put(this, "startWeel", "100");
  
  // остановить колесо
  Conv.put(this, "stopWeel", 0); 
  
  // озвучить игровой результат
  // время – две секунды
  Conv.put(
    this, 
    "gameSounds", 
    2000);
  
  // анимационно убрать 
  // проигравшие ставки
  Conv.include(this, "looses"); 
  
  // анимационно показать 
  // выигрыш всех выигравших 
  // ставок(если такие имеются) 
  Conv.include(this, "wins");

  // разблокировать интерфейс 
  // игрового приложения
  Conv.put(this, "unlock", 0)
}

//------------------------------
//  метод looses
//------------------------------
private function looses()
{
  for (
    var i=0;
    ii<this.looses_array.length;
    i++)
  {
    // анимационно убрать 
    // проигравшие ставки
    Conv.include(
      this.looses_array[i], 
      "loose");
  }
}

//------------------------------
//  метод wins
//------------------------------
private function wins()
{
  for (
    var i=0;
    ii<this.wins_array.length;
    i++)
  {
    // анимационно показать 
    // выигрыш у каждой ставки
    Conv.include(
      this.wins_array[i], 
      "win");
    
    this.balance += 
      this.wins_array[i].winsValue;
    
    // покажем на дисплее 
    // баланса игрока 
    // увеличение баланса
    Conv.put(
      _root.balanceDisplay_mc, 
      "setBalance", 
      this.balance);
  }  
}

Класс ставки:


//------------------------------
//  метод win класса ставки
//------------------------------

private function win()
{
  var bet = this.bet_mc;
  var end_point = _root.player_mc;
  
  // увиличить размер 
  // стопки ставки 
  // на размер выигрыша
  Conv.put(
    bet, 
    "setBet", 
    "4", 
    this.bet + this.winsValue);
  
  // анимировать движение 
  // к игроку 
  Conv.anim(
    bet, 
    end_point, 
    {to_end:true})
}

//------------------------------
//  метод loose класса ставки
//------------------------------

private function loose()
{
  var bet = this.bet_mc;
  var end_point = _root.dealer_mc;
  
  // анимировать 
  // движение к диллеру
  Conv.anim(
    bet, 
    end_point, 
    {to_end:true, speed:10})
}

По сравнению с первым вариантом код стал значительно яснее. Можно легко «читать» последовательность команд.

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

Сделаем выводы

Еще раз пройдемся по тем возможностям, которые мы реализовали с помощью конвейера.

  1. Мы описали последовательность действий и распределили ее во времени. Каждое действие совершается независимо друг от друга одно за другим.
  2. Мы использовали вложенные списки. Один элемент содержит инструкции для создания другого списка. Списки действий создаются не сразу, а по мере необходимости и при готовности данных для этих действий. Вложенные списки структурируют наш код.
  3. Мы распределили вычисления во времени. Структура кода может развиваться как угодно сложно, и мы не будем думать о том, что плеер не сможет выполнить работу, которую мы ему даем.
  4. Мы стали использовать мощнейшую и универсальную технологию для анимации мувиклипов. И когда нам нужно будет анимационно переместить мувиклип с одной точки в другую, нам нужно будет написать только одну строчку!

Ну а теперь вернемся к методу anim и опишем его подробно:

Conv.anim

Conv.anim(movieClip, endPoint[, paramsObject])

Parameters

movieClip – перемещаемый мувиклип.

endpoint – финальная точка перемещения. Та, куда движется мувиклип. Это может быть мувиклип или объект, с двумя обязательными параметрами (например, {_x:100, _y:100} ).

paramsObject – объект, хранящий дополнительные параметры анимации: скорость, scale и тд.

Параметры paramsObject:

speed – средняя скорость перемещения. Количество пикселей в один кадр. Чем значение меньше, тем меньше скорость.

to_end – буллевое значение, показывающее, что анимация доходит до последней точки. Если true, то финальная точки анимации будет endpoint, если false, то анимация будет не до конца. По умолчанию равно true

scale – показывает, что во время анимации scale анимированного мувиклипа будет достигать значения финальной точки. То есть, если мувиклип вначале имел _xscale равное 100%, а у финальной точки это значение равно 200%, то мувиклип во время анимации будет постепенно увеличивать это значение, пока оно не достигнет 200 процентов. Если при этом в виде финальной точки используется объект, то объект должен иметь поля _xscale и _yscale (например, {_x:100, _y:100, _xscale:200, _yscale:200} ).

delta – дополнительная точка, повторяющая формат финальной точки и позволяющая создавать анимацию не по прямой, а по дуге. Анимируемый мувиклип, сначала по дуге пройдет эту точку и продолжит движение до финальной точки. Как и финальная точка – это может быть как мувиклип, так и объект.

func – функция управления стилем движения. По умолчанию скорость возрастает в начале пути и затухает в конце пути. Используется функция из стандартной библиотеки – mx.transitions.easing.Strong.easeInOut. Можно использовать другие стандартные функции движения из пакета mx.transitions.easing или же создать свой вариант, основываясь на аргументах и возвращаемых значениях данных функций.

duration – длительность анимации. По умолчанию длительность вычисляется из количества кадров необходимых для прорисовки всех шагов анимации. Если указать длительность в миллисекундах, то анимация будет длиться строго определенное время.

frame_value – с помощью можно управлять скоростью движения используя «виртуальный fps». Количество миллисекунд на кадр. Скорость анимации и обновление экрана не будет зависеть от "глобального fps" Flash-файла.

Объект параметров имеет следующие значения по умолчанию:

speed:20,
to_end:false,
scale:false,
delta:null,
duration:null,
frame_value:"1"

Returns

Ничего

Description

Метод создает список конвейера для создания анимации мувиклипа из точки в точку. Начальной точкой является положение мувиклипа. С помощью объекта параметров указываются параметры анимации.

Usage

Движение к мувиклипу


Conv.anim(any_mc, second_mc);

Пример показывает реализацию анимации мувиклипа по треугольнику десять раз.


for (var i=1;i<=10;i++) 
{ 
  Conv.include(function() 
  { 
    Conv.anim (
      any_mc, 
      {_x:400, _y:200}, 
      {speed:20}); 
  }); 
  Conv.include(function() 
  { 
    Conv.anim (
      any_mc, 
      {_x:100, _y:200}, 
      {speed:20}); 
  }); 
  Conv.include(function() 
  { 
    Conv.anim (
    any_mc, 
    {_x:20, _y:20}, 
    {speed:20}); 
  }); 
}

Предыдущая часть | Следующая часть
[1] [2] [3] [4] [5] [6] [7]