Как стать автором
Обновить

15 полезных сниппетов от сайтов Snipplr.com и Active.TutsPlus

Время на прочтение 11 мин
Количество просмотров 2K
Как то раз, зимним вечером делать мне было нечего и решил я перевести полезный, как мне тогда показалось, пост о 15 сниппетах для Action Script 3. Оригинал можно-увидеть-там-если-кликнуть-на-это-длинное-словосочетание-через-дефис, а перевод статьи можно увидеть тут, и никуда (кроме хабраката) кликать и не нужно.

Многие дополнительные примеры кода, которых не было в оригинальной статье, предоставлены юзером Flashist.

1. Случайная сортировка

for (var i:uint = 0; i < myArray.length; i++)
{
  var rand:uint = int(Math.random() * myArray.length);
  myArray.push( myArray.splice( rand, 1 )[0] );
}

* This source code was highlighted with Source Code Highlighter.


Авторы статьи предлагают представить себе массив, в качестве колоды карт, из которой, на каждом шаге цикла, «достаётся» случайная карта, после чего она же добавляется в конец этой колоды. Лично мне не понятно, почему они не использовали стандартную функцию сортировки массивов (и векторов) с помощью которой можно было бы сделать примерно следующее:
/**
* Специальная функция сортировки массива сортировки массива
*
* @param  obj1 ссылка на 1-й элемент массива.
* @param  obj2 ссылка на 2-й элемент массива.
*
* @return  число, которое будет определять сортировку массива (-1, 0 или 1).
*/
public function randomizeSortFunction(obj1:Boolean, obj2:Object):int
{
  var randNum:int = -1 + Math.floor((Math.random() * 3));
  
  return randNum;
}

// Создаём ммассив и случайно сортируем его
var array:Array = [0, 1, 2, 3, 4];
array.sort(ArrayTools.randomizeSortFunction);
trace(array);

* This source code was highlighted with Source Code Highlighter.

Второй способ кажется мне, более понятным. Тем более, что это встроенное средство AS3.

2. Позиционирование объектов по сетке

Авторы предлагают такой вот простой и короткий способ позиционирования обектов. Оператор остатка от деления (%) позволяет корректно позиционировать объекты по оси X, а деление с округлением в меньшую сторону (Math.floor) помогает разобраться с расстановкой по Y.
for (var i:uint = 0; i < 20; i++)
{
  var displayObject:MyDisplayObject = new MyDisplayObject();
  displayObject.x = displayObject.width * ( i % 5 );
  displayObject.y = displayObject.height * Math.floor( i / 5 );
  addChild(displayObject);
}


* This source code was highlighted with Source Code Highlighter.

В примере создаётся 20 объектов некоего вымышленного класса MyDisplayObject, которые располагаются внутри сетки с 5-ю столбцами. Как вы уже могли догадаться, цифра 5 в коде означает количество столбцов сетки, т.е. если бы столбцов было 7, то вместо цифры 5 мы бы ставили 7.

3. Удаление всех «детей» у DisplayObjectContainer

Базовый класс для всех контейнеров с визуальным содержимым (я сейчас говорю про DisplayObjectContainer, да да), не имеет своего метода для удаления сразу всех дочерних объектов. Не беда! =) Сделаем такой метод сами, благо, делается он совсем не сложно:
/**
* Удаление всех дочерних клипов внутри какого-то родительского клипа.
*
* @param  parentClip ссылка на клип, внутри которого нужно будет удалить все дочерние клипы.
*/
static public function removeAllChildren(parentClip:DisplayObjectContainer):void
{
  // Пока в клипе есть хотя бы 1 дочерний клип, удаляем клип на самом нижнем слое
  while(parentClip.numChildren > 0)
  {
    parentClip.removeChildAt(0);
  }
}

* This source code was highlighted with Source Code Highlighter.

В качестве дополнения, презент вам от пользователя Flashist, который делится ещё парой функций для работы с DisplayObjectContainer и их «детьми»:
/**
* Скрытие всех дочерних клипов внутри какого-то родительского клипа.
*
* @param  parentClip ссылка на клип, внутри которого нужно будет скрыть все дочерние клипы.
*/
static public function hideAllChildren(parentClip:DisplayObjectContainer):void
{
  var childrenCount:int = parentClip.numChildren;
  for (var childrenIndex:int = 0; childrenIndex < childrenCount; childrenIndex++)
  {
    parentClip.getChildAt(childrenIndex).visible = false;
  }
}
/**
* Показывание всех дочерних клипов внутри какого-то родительского клипа.
*
* @param  parentClip ссылка на клип, внутри которого нужно будет показать все дочерние клипы.
*/
static public function showAllChildren(parentClip:DisplayObjectContainer):void
{
  var childrenCount:int = parentClip.numChildren;
  for (var childrenIndex:int = 0; childrenIndex < childrenCount; childrenIndex++)
  {
    parentClip.getChildAt(childrenIndex).visible = true;
  }
}

/**
* Удаление дочерним клипом самого себя из родительского клипа.
*
* @param  child ссылка на дочерний клип.
*/
static public function childRemoveItselfFromParent(child:DisplayObject):void
{
  // Если клип не создан, то прерываем функцию
  if (child == null || child.parent == null)
  {
    return;
  }
  
  child.parent.removeChild(child);
}

    parentClip.removeChildAt(0);
  }
}

* This source code was highlighted with Source Code Highlighter.


4. Получение URL страницы, в которую встроена SWF

Чтобы получить URL страницы, в которую встроена флешка необходимо использовать класс ExternalInterface. Чтобы не вдаваться в лишние детали, скажу лишь, что в примере мы используем ExternalInterface для того, чтобы обратиться к DOM (Document Object Model) HTML страницы, в которую встроена наша флешка.

Недостатком этого подхода является то, что, флешка должна быть встроена в HTML страницу, с параметром allowscriptaccess установленным в sameDomain or always. Если вы сами контролируете встраивание флешки в HTML страницу, то для вас это может не быть проблемой, однако, если флешка встраивается другими людьми, этот способ может и не сработать. Для использования этого кода, не забудьте импортировать flash.external.ExternalInterface класс к себе в документ:
function get currentURL():String
{
  var url:String;
  if (ExternalInterface.available)
  {
    return ExternalInterface.call("window.location.href");
  }
  return url;
}


* This source code was highlighted with Source Code Highlighter.

В качестве альтернативы можно использовать свойство url у объекта loaderInfo, к этому свойству нужно обращаться через корневой объект флешки (или через stage (прим. автора)). Используя этот способ, вы не узнаете URL HTML страницы, где расположена флешка, но сможете узнать где находится сама флешка. Этот способ позволит вам узнать, на каких доменах выложена ваша флешка.
root.loaderInfo.url;
* This source code was highlighted with Source Code Highlighter.


От себя добавлю, что для того, чтобы знать, где выложена ваша флешка, а так же для сбора другой очень полезной статистической информации, можно использовать крутой-супер-пупер сервис MochiBot, я так и делаю, ага )

5. Округление координат DisplayObjectContainer объектов и их «детей»

Этот сниппет меня самого немного порадовал, так как, несмотря на его очевидность и простоту, я не задумывался о нём раньше. Смысл в том, что передавая в функцию DisplayObjectContainer мы запускаем рекурсивный вызов этой функции, который округляет координаты самого контейнера и всех его дочерних объектов. Ну а если один из дочерних объектов является сам представителем класса DisplayObjectContainer, то в функцию передаётся уже он, и так до последнего, пока все вложенные контейнеры не будут перебраны.

function roundPositions(displayObjectContainer:DisplayObjectContainer):void
{
  if (!(displayObjectContainer is Stage))
  {
    displayObjectContainer.x = Math.round(displayObjectContainer.x);
    displayObjectContainer.y = Math.round(displayObjectContainer.y);
  }
  for (var i:uint = 0; i < displayObjectContainer.numChildren; i++)
  {
    var child:DisplayObject = displayObjectContainer.getChildAt(i);
    if (child is DisplayObjectContainer)
    {
      roundPositions(child as DisplayObjectContainer);
    }else
    {
      child.x = Math.round(child.x);
      child.y = Math.round(child.y);
    }
  }
}


* This source code was highlighted with Source Code Highlighter.

Ах, да, проверка на Stage стоит для того, чтобы случайно не попробовать обратиться к свойствам x и y объекта Stage, который их не поддерживает (выдастся эксепшн).

6. Случайное число в между 2-мя числами

Ну, тут уж совсем всё просто, даже и объяснять ничего не хочется ) Просто бери и юзай.
function random(min:Number, max:Number):Number
{
  return min + Math.random() * (max - min);
}


* This source code was highlighted with Source Code Highlighter.

И очередной дополнительный презент от Flashist. В этот аналог функции «встроены», внимание, возможность:
а) Автоматически округлять к меньшему целому числу.
б) Автоматически округлять к ближайшему целому числу.
в) Автоматически округлять к большему целому числу.

Вау, это и правда круто:
/**
* Возвращение случайного числа в заданных рамках.
*
* @param  minNum минимальное значение для случайного числа.
* @param  maxNum максимальное значение для случайного числа.
* @param  isNeedFloor нужно ли округлять к меньшему целому числу.
* @param  isNeedRound нужно ли округлять к ближайшему целому числу.
* @param  isNeedCeil нужно ли округлять к большему целому числу.
*
* @return  случайное число в заданных рамках.
*/
static public function getRandomNum(minNum:Number, maxNum:Number, isNeedFloor:Boolean = false, isNeedRound:Boolean = false, isNeedCeil:Boolean = false):Number
{
  var randNum:Number = minNum + Math.random() * (maxNum - minNum);
  
  if (isNeedFloor)
  {
    randNum = Math.floor(randNum);
  }
  
  if (isNeedRound)
  {
    randNum = Math.round(randNum);
  }
  
  if (isNeedCeil)
  {
    randNum = Math.ceil(randNum);
  }
  
  return randNum;
}

* This source code was highlighted with Source Code Highlighter.


7. Случайное булево значение

Опять же, ничего особо сложного в этом нет, все и так должны понять. Простая и часто требуемая функция:
function get randomBoolean():Boolean
{
  return Math.random() >= 0.5;
}

* This source code was highlighted with Source Code Highlighter.


8. Нахождение угла между 2-мя точками

А это уже поинтереснее. Подобные функции часто требуются при разработке игр или приложений, где нужно реагировать на движение/положение курсора мышки:
function getAngle (x1:Number, y1:Number, x2:Number, y2:Number):Number
{
  var dx:Number = x2 - x1;
  var dy:Number = y2 - y1;
  return Math.atan2(dy,dx);
}

* This source code was highlighted with Source Code Highlighter.

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

9. Перевод градусов в радианы и обратно

/**
* Функции для работы с углами.
*/
/**
* Перевод величины угла из градусов в радианы.
*
* @param angle величина угла в градусах.
*
* @return величина угла в радианах.
*/
static public function convertAngleToRadians(angle:Number):Number
{
 var radians:Number = angle / 180 * Math.PI;
 
 return radians;
}
/**
* Перевод величины угла из радианов в градусы.
*
* @param radians величина угла в радианах.
*
* @return величина угла в градусах.
*/
static public function convertRadiansToAngle(radians:Number):Number
{
 var angle:Number = radians * 180 / Math.PI;
 
 return angle;
}


* This source code was highlighted with Source Code Highlighter.


10. Проверка корректности Email

Полезный сниппет для создания сайтов и всяких-там регистраций в играх.
function isValidEmail(email:String):Boolean
{
  var emailExpression:RegExp = /([a-z0-9._-]+?)@([a-z0-9.-]+)\.([a-z]{2,4})/i;
  return emailExpression.test(email);
}

* This source code was highlighted with Source Code Highlighter.

Стоит понимать, что 100% гарантии данный RegExp не даёт (прим. автора: к сожалению, пока я не видел ни одного RegExp, который бы не ошибался). В моих трёхминутных эксперементах он ошибся по-крайней мере в 3 случаях. Попробуйте проверить адреса: -mymail@mail.mail, .mymail@mail.mail и mymail@mail.mail.

11. Удаление пробелов

Если у вас когда-нибудь была необходимость в удалении некоторых символов из строки, то вот решение ваших проблем =)
function stripSpaces(string:String):String
{
  var s:String = string;
  return s.split(" ").join("");
}


* This source code was highlighted with Source Code Highlighter.

Добродушный Flashist делится с нами «продвинутой» версией этого сниппета, с помощью которого вы можете удалять любые подстроки (не только пробелы) и вставлять на их место так же, любые подстроки (не только пустую строку):
/**
* Функция, которая будет заменять в тексте все найденные последовательности символов на новые последовательности символов.
*
* @param sourceString исходная строка, которую нужно будет очистить.
* @param oldString текст, который нужно будет заменить.
* @param newString текст, на который будет происходить замена.
*
* @return текст, с заменёнными последовательностями необходимого текста.
*/
static public function replaceText(sourceString:String, oldString:String, newString:String):String
{
  // Разбиваем строку при нахождении искомой подстроки и соединяем, добавляя новую подстроку
  var replacedString:String = sourceString.split(oldString).join(newString);
  
  // Возвращаем переменную с очищенным текстом
  return replacedString;
}

* This source code was highlighted with Source Code Highlighter.


12. Slugify

Наверно, термин Slug, правильнее всего на русский язык будет переверсти, как ЧПУ (человеко-понятные урлы), т.е. такая ссылка, которую человек может легко прочитать.
function slugify(string:String):String
{
  const pattern1:RegExp = /[^\w- ]/g; // Matches anything except word characters, space and -
  const pattern2:RegExp = / +/g; // Matches one or more space characters
  var s:String = string;
  return s.replace(pattern1, "").replace(pattern2, "-").toLowerCase();
}

* This source code was highlighted with Source Code Highlighter.

Данный сниппет берёт исходную строку и вырезает из неё все некорректные для формирования URL символы, т.е. все символы кроме латиницы, цифр, дефиса и подчёркивания. Пробелы между «корректными» словами заменяются дефисами. Так, если передать в функцию строку «Привет, это статья про Flash !^@#&*!@^#*&, ActionScript, Adobe, сниппеты и тому_подобные_штуки-дрюки», то в ответ она вернёт «-flash-actionscript-adobe-__-».

13. Удаление из подстрок http:// или https:// и опциональное удаление www из какой-нибудь строки

Честно говоря, данный функционал, за, наверно, уже 4 года Flash-разработок мне ни разу не потребовался, но я не исключаю, что он может быть кому-то полезен, мало ли какие-задачи встречаются у разработчиков.
function stripHttp(string:String, stripWWW:Boolean = false):String
{
  var s:String = string;
  var regexp:RegExp = new RegExp(!stripWWW ? "https*:\/\/" : "https*:\/\/(www\.)*", "ig");
  return s.replace(regexp, "");
}

* This source code was highlighted with Source Code Highlighter.


14. Удаление HTML разметки

А это уже интереснее, куда интереснее ) В общем сниппет позволяет очистить текст от символов HTML разметки и оставить только «чистый» текст. Вводите «Click here to find out more», а вам оставляют только «Click here to find out more.», клёво, что ещё сказать.
function stripTags(string:String):String
{
  var s:String = string;
  var regexp:RegExp = new RegExp("<[^<]*<", "gi");
  return s.replace(regexp, "");
}

* This source code was highlighted with Source Code Highlighter.


15. Удаление пространств имён XML

Опять же, с проблемой конфликтов пространств имён в XML я тоже никогда не сталкивался, но в оригинальной статье говорится, что такие проблемы иногда случаются, когда XML загружаются из разных источников.
function stripXMLNamespaces(xml:XML):XML
{
  var s:String = xml.toString();
  var pattern1:RegExp = /\s*xmlns[^\'\"]*=[\'\"][^\'\"]*[\'\"]/gi;
  s = s.replace(pattern1, "
");
  var pattern2:RegExp = /<[\/]{0,1}(\w+:).*?>/i;
  while(pattern2.test(s)) {
    s = s.replace(pattern2.exec(s)[1], "
");
  }
  return XML(s);
}

* This source code was highlighted with Source Code Highlighter.


P.S.:

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

Ещё раз повторюсь, что свои примеры кода к посту любезно предоставил Flashist, которому изрядно подпортили карму другие пользователи после отчаянного поста, где он советовал подумать нам всем о том, как они ничтожны. Не судите о нём строго =) Он уже и сам немного пожалел о таком теге к посту и немного дерзких комментариях. Собственно этот пост, наверно, с удовольствием опубликовал бы он сам, да только карма не позволяет (это я так типо пытаюсь выбить ему пару плюсов в карму.
Теги:
Хабы:
+2
Комментарии 24
Комментарии Комментарии 24

Публикации

Истории

Ближайшие события

PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн
Weekend Offer в AliExpress
Дата 20 – 21 апреля
Время 10:00 – 20:00
Место
Онлайн