Flex и RIA блоги
2008-02-01 |
Средства программной анимации: где взять, что и получить за это. Большинство наверое использовала в своих проектах для программной анимации класс mx.transitions.Tween, так знайте он не одинок в своем роде). Кто его не видел — исправляетесь, прочитав его описание с примерами. Всего существует несколько проектов, которые помогают программировать анимацию, в начале классы от “родного” производителя:
Оба класса имеют недостатки: если экземпляр класса описан как локальная переменная то мусорщик свободно может его убить и эффект не до играет до конца. И классы от стороннего производителя:
Отдельно о тестах. В данной статье я не рассматривал классы которые имею только AS2 версию, потому что это уже не актуально! |
Ошибка при отсутствии атрибута в XML Возьмем простой xml типа <data> Нам необходимо получить все записи, у которых owner = "Andrey". Делаем как всегда: var res:XML = httpServ.lastResult as XML; Вылезает ошибка: ReferenceError: Error #1065: Variable @owner is not defined. Чтобы решить эту проблему в лоб, нужно для всех узлов прописать атрибут owner, что не очень хорошо. Поэтому есть альтернативные виды получения этой информации: 1 способ: var rows:XMLList = res.row.(attribute("owner")=="Andrey"); 2 способ: var xml:XMLList = res.row.(hasOwnProperty("@owner")==true && @owner=="Andrey"); |
Сайт Ukrainian Adobe Flash Platform User Group - свершилось :) Вчерашнее обсуждение насчет попить пива в Киеве настолько сильно захотело превратиться во встречу Ukrainian Adobe Flash Platform User Group, что привело к появлению сайта UAFPUG - fpug.org.ua :) |
Класс SFSEvent. SmartFoxServer Класс SFSEvent - представляет все события, которые обрабатываются объектом SmartFoxClient. Полное определение класса: it.gotoandplay.smartfoxserver.SFSEvent Потомок Event. Свойства: params : Object - объект, содержащий параметры обрабатываемого события. Методы: clone () : Event toString () : String События: onBuddyList : String onBuddyListError : String onBuddyListUpdate : String onBuddyPermissionRequest : String onBuddyRoom : String onConfigLoadFailure : String onConfigLoadSuccess : String onConnection : String onConnectionLost : String onCreateRoomError : String onDebugMessage : String onExtensionResponse : String onJoinRoom : String onJoinRoomError : String onLogin : String onLogout : String onModeratorMessage : String onObjectReceived : String onPrivateMessage : String onPublicMessage : String onRandomKey : String onRoomAdded : String onRoomDeleted : String onRoomLeft : String onRoomListUpdate : String onRoomVariablesUpdate : String onRoundTripResponse : String onSpectatorSwitched : String onUserCountChange : String onUserEnterRoom : String onUserLeaveRoom : String onUserVariablesUpdate : String |
Напоминалка о RAFPUG-3 с помощью Sprout Builder
Говорят, предыдущее приложение (созданное в Sprout Builder) глючит в дебаг-версии проигрывателя. А как работает это? |
FPUG-3: Developer Anonymous Нижеследующая идея возникла от воздействия FPUG-излучения. Нужна критика! В предыдущей записи RAFPUG-цикла "Обмен стилями и потенциально совместимые команды" я предположил, что для создания хорошей команды нужны люди, как можно лучше знающие друг друга. Этому очень способствуют встречи типа Flash Platform User Group-3.Но не всегда есть возможность попасть на встречу, да и информация может со временем улетучиваться из памяти. Нужен сайт, где разработчики могут знакомиться ближе. Интерактивные профили разработчиковМы хотим делать интересные проекты? Думаю, да. Как попасть в интересный проект? Нужно выглядеть интересно (например, весьма неплох профиль Алексея Акулиничева, создателя mos2.ru). Теперь представим, что вы — автор интересного проекта и хотите найти себе напарника-двух, да не просто кодеров — будущих единомышленников! Где искать? Фиг его знает. Специального сайта нет. Есть МойКруг, есть вКонтакте, на базе которых возможно создание интерактивных профилей разработчиков. Что это за профили?Профель разработчега отображает его рабочие характеристики, ключевые с точки зрения других разработчиков. Зачем? Затем, что именно эти характеристики важны для совместной работы. Как такие характеристики определить? Только сознательным усилием: каждый должен вспомнить, какие самые приятные / конфликтные / несуразные ситуации он встречал на своем проекте и чем это было вызвано. Нужно собрать такой список. Есть идея? Пиши в комменты, а пост потом дочитаешь. Как работает Профиль РазработчикаЕсть ресурс, где каждый пожелавший того разработчик представлен собственной страницей. На ней он рассказывает о себе: где живет, что интересного делал, какие проблемы решал, в чем он пишет свой код, как он пишет свой код, как он форматирует свой код, как он любит и ненавидит свой код, и какой код он хотел бы писать и для чего, плюс предпочитаемые режимы работы разработчегово организма. Да, и как он относится к использованию компонентов. Еще нужно проанализировать все холиворы последних пяти лет, там найдется несколько важных для совместной работы показателей.В общем, профиль разработчика открывает о нем всю информацию, кроме реального имени и фото. Вместо них используются придуманные внутренние никнеймы и аватары. Это сделано для того, чтобы снизить шум, не связанный с рабочей информацией. И над этим нужно еще думать. Любой желающий может посмотреть профили разработчегов. Но получить их контакты может только другой зарегистрированный участник ресурса. Для начала регистрациии нужно создать собственный профиль и опубликовать его — профиль попадает в список претендентов на регистрацию, отображаемых на стартовой странице. Для завершения регистрации нужно, чтобы не менее трех участников ресурса дали "добро" на регистрацию нового члена, нажав кнопку "Берем". Дополнительные фичи, о которых некогда писать, но нужно подумать: 1) Роли внутри системы (программер, менеджер, тестер, инвестер) 2) Разработчеги могут задавать вопросы в профиле другого разработчега и там же публикуются ответы. Таким образом, система должна давать людям, заинтересованным в повышении качества своих проектов, возможность контактировать друг с другом. Напомню еще раз, что это пока просто мысли вслух. Мне очень интересны ваши мнения. |
Flex Builder 3 Beta 3 - закончился триал Если у Вас закончился триал на Flex 3 Beta 3 и никакие методы не помогают из перепробованных (удаление хитрых файлов и т.п ps. только что опробовали на рабочей машине с закончившимся триалом, и все помогло. |
Класс SmartFoxClient. SmartFoxServer Класс SmartFoxClient - главный класс SmartFoxServer API. Полное определение класса: it.gotoandplay.smartfoxserver.SmartFoxClient Потомок EventDispatcher Конструктор: SmartFoxClient (debug:Boolean = false) debug - включить сообщения отладки. Свойства: ipAddress : String - IP-адрес SmartFoxServer. port : int - порт для соединения со SmartFoxServer. defaultZone : String - зона логина по умолчанию. blueBoxIpAddress : String - IP адрес BlueBox (фича, позволяющая организовать соединение для клиентов, которые находятся за Proxy или Firewall. Прямое сокетное соединение для них не доступно, и связь осуществляется через HTTP-туннель). blueBoxPort : Number - порт для соединения с BlueBox. smartConnect : Boolean - позволяет включать BlueBox при отсутствии прямого сокетного соединения. buddyList : Array - список друзей. Массив объектов, содержащих параметры каждого друга. myBuddyVars : Array - ассоциативный массив, содержащий переменные друзей. debug : Boolean - включает вывод отладочной информации на клиенте. Выводятся все принятые/отправленные сообщения. myUserId : int - идентификатор текущего пользователя, который SmartFoxServer присваивает пользователю при его успешном подключении. myUserName : String - имя текущего пользователя. Доступно только после успешной авторизации пользователя. playerId : int - идентификатор текущего пользователя (или слот) в игровой комнате. Доступен только после подключения к игровой комнате. Отсчет начинается с 1. amIModerator : Boolean - показывает, что сервер опознал пользователя как модератора. activeRoomId : int - идентификатор комнаты, к которой последней раз подключался текущий пользователь. httpPort : int - TCP-порт, который прослушивает встроенный в SmartFoxServer веб-сервер. По умолчанию 8080. rawProtocolSeparator : String - разделительный символ для протокола String (raw). Должен совпадать со значением <RawProtocolSeparator> в конфигурации сервера.isConnected : Boolean - показывает, что текущий пользователь соединен с сервером. httpPollSpeed : int - минимальный интервал в миллисекундах между двумя запросами к SmartFoxServer при использовании BlueBox. По умолчанию 750. Не рекомендуются значения меньше 50. Методы: loadConfig (configFile:String = "config.xml", autoConnect:Boolean = true) : void Загружает файл внешней конфигурации клиента. configFile - имя файла внешней конфигурации клиента. Не следует путать с файлом конфигурации сервера. autoConnect - после успешной загрузки файла конфигурации, автоматически вызвать метод connect(). Пример файла конфигурации: <SmartFoxClient> <ip>127.0.0.1</ip> <port>9339</port> <zone>simpleChat</zone> <debug>true</debug> <blueBoxIpAddress>127.0.0.1</blueBoxIpAddress> <blueBoxPort>9339</blueBoxPort> <smartConnect>true</smartConnect> <httpPort>8080</httpPort> <httpPollSpeed>750</httpPollSpeed> <rawProtocolSeparator>%</rawProtocolSeparator> </SmartFoxClient> getConnectionMode () : String Возвращает текущий режим соединения: CONNECTION_MODE_DISCONNECTED - нет соединения. CONNECTION_MODE_SOCKET - сокетное соединение. CONNECTION_MODE_HTTP - соединение по http-туннелю. connect (ipAdr:String, port:int = 9339) : void Устанавливает соединение с SmartFoxServer. ipAdr - IP-адрес сервера port - порт сервера disconnect () : void Закрывает соединение с SmartFoxServer. addBuddy (buddyName:String) : void Добавляет пользователя в список друзей. buddyName - имя добавляемого пользователя. autoJoin () : void Автоматически присоединяет пользователя к комнате, заданной в текущей зоне как комната для соединения по умолчанию. clearBuddyList () : void Удаляет всех пользователей из списка друзей. (Устаревший) createRoom (roomObj:Object, roomId:int = -1) : void Динамически создает комнату в текущей зоне. Если комната игровая, то пользователь автоматически присоединяется к вновь созданной комнате. name, maxUsers, maxSpectators, isGame, uCount, vars, extension - аналогичны параметрам конфигурации комнат. password : Устанавливает пароль на комнату и делает ее приватной. exitCurrentRoom: Если комната игровая - присоединяться к комнате сразу после ее создания. getAllRooms () : Array Возвращает список всех комнат в текущей зоне. Каждый из элементов - объект it.gotoandplay.smartfoxserver.data.Room. Возвращается список комнат, который хранится на клиенте. Запрос на сервер не отправляется. getBuddyByName (buddyName:String) : Object Получить объект с параметрами друга из списка друзей используя имя. buddyName - имя друга. getBuddyById (id:int) : Object Получить объект с параметрами друга из списка друзей используя идентификатор. id - идентификатор друга. Возвращаемый объкт содержит свойства: id : идентификатор друга. name : имя друга. isOnline : друг в режиме on=line. isBlocked : друг заблокирован variables : переменные друга. getBuddyRoom (buddy:Object) : void Послать запрос на получение идентификатора комнаты, в которой находится друг. buddy - объект искомого друга из списка друзей. getRoom (roomId:int) : Room Получить объект комнаты из списка комнат, используя идентификатор. getRoomByName (roomName:String) : Room Получить объект комнаты из списка комнат, используя имя комнаты. getRoomList () : void На сервер отправляется запрос на получение списока всех комнат в текущей зоне. Затем, обработав событие onRoomListUpdate, можно получить свежий список комнат. getActiveRoom () : Room Возвращает объект текущей активной комнаты. Сервер позволяет присоединяться к нескольким комнатам одновременно. getRandomKey () : void Послать запрос серверу на получение строки с уникальной последовательностью случайных символов. Затем, обработав событие onRandomKey, можно получить строку с ключом. getUploadPath () : String Получить http-адрес директории для закачки на сервер файлов по умолчанию. getVersion () : String Получить версию SmartFoxServer Flash API. joinRoom (newRoom:*, pword:String = "", isSpectator:Boolean = false, dontLeave:Boolean = false, oldRoom:int = -1) : void Подключиться к комнате. newRoom - Если String, то имя комнаты, если int - идентификатор. pword - пароль для входа, если комната приватная. isSpectator - присоединиться в качестве наблюдателя. dontLeave - покидать ли текущую комнату. oldRoom - идентификатор покидаемой комнаты. leaveRoom (roomId:int) : void Покинуть комнату. roomId - идентификатор комнаты. loadBuddyList () : void Загрузить список друзей для текущего пользователя. login (zone:String, name:String, pass:String) : void Осуществить стандартную процедуру авторизации. Авторизация подтверждается событием onLogin. logout () : void Выйти из текущей зоны. Выход подтверждается событием onLogout. removeBuddy (buddyName:String) : void Удалить друга из списка друзей. buddyName - имя друга. roundTripBench () : void Послать запрос на определение скорости соединения. Ответ можно получить по событию onRoundTripResponse. sendBuddyPermissionResponse (allowBuddy:Boolean, targetBuddy:String) : void Послать запрос на разрешение добавить себя в список друзей. allowBuddy - разрешить/не разрешить. targetBuddy - имя друга. sendPublicMessage (message:String, roomId:int = -1) : void Послать массовое сообщение в текущую комнату. message - текст сообщения. roomId - идентификатор комнаты, в случае если пользователь соединен с несколькими комнатами. sendPrivateMessage (message:String, recipientId:int, roomId:int = -1) : void Послать приватное сообщение пользователю. message - текст сообщения. recipientId - идентификатор пользователя, которому отправляется сообщение. roomId - идентификатор комнаты, в случае если пользователь соединен с несколькими комнатами. sendModeratorMessage (message:String, type:String, id:int = -1) : void Послать сообщение модератора в текущую зону, комнату, или конкретному пользователю в текущей комнате. message - текст сообщения. type - MODMSG_TO_USER: сообщение пользователю, MODMSG_TO_ROOM: сообщение в комнату, MODMSG_TO_ZONE: сообщение в зону. id - идентификатор зоны, комнаты, или пользователя. sendObject (obj:Object, roomId:int = -1) : void Послать объект Actionscript пользователям текущей комнаты. obj - объект Actionscript. roomId - идентификатор комнаты, в случае если пользователь соединен с несколькими комнатами. sendObjectToGroup (obj:Object, userList:Array, roomId:int = -1) : void Послать объект Actionscript пользователям текущей комнаты. obj - объект Actionscript. userList - список идентификаторов пользователей. roomId - идентификатор комнаты, в случае если пользователь соединен с несколькими комнатами. sendXtMessage (xtName:String, cmd:String, paramObj:*, type:String = "xml", roomId:int = -1) : void Запрос на выполнение серверного скрипта (расширения). xtName - имя серверного скрипта. cmd - имя команды (функции), предусмотренной в скрипте. paramObj - объект, содержащий данные для передачи в серверный скрипт type - тип протокола для сериализации запроса. XTMSG_TYPE_XML: формат XML XTMSG_TYPE_STR: строка с разделителем (raw протокол) XTMSG_TYPE_JSON: протокол JSON. Для сокращения трафика не рекомендуется использовать XML. roomId - идентификатор комнаты, в случае если пользователь соединен с несколькими комнатами. setBuddyBlockStatus (buddyName:String, status:Boolean) : void Заблокировать/разблокировать пользователя в списке друзей. buddyName - имя друга status - true - заблокировать, false - разблокировать. setBuddyVariables (varList:Array) : void Установить переменные друга для текущего пользователя (сам пользователь рассматривается как чей-то друг). varList - ассоциативный массив, где ключ - имя переменной, значение - значение переменной. setRoomVariables (varList:Array, roomId:int = -1, setOwnership:Boolean = true) : void Установить переменные комнаты. Переменные комнаты полезны для организации централизованного хранилища данных, доступных всем клиентам комнаты. При изменении/добавлении/удалении данных все пользователи уведомляются об этом событием onRoomVariablesUpdate . varList - массив объектов переменных. roomId - идентификатор комнаты, в случае если пользователь соединен с несколькими комнатами. setOwnership - false - для предотвращения изменения переменной в случае, если ее значение изменено другим пользователем. Объект переменной: name : String - имя переменной. val : * - значение переменной. priv : Boolean - если true, изменять переменную может только ее создатель. persistent : Boolean - если true, переменная существует до тех пор, пока ее создатель подключен к зоне, если false - переменная существует до тех пор, пока ее создатель подключен к комнате. По умолчанию - false. setUserVariables (varObj:Object, roomId:int = -1) : void Установить переменные одного или нескольких пользователей. varObj - объект, в котором каждое из свойств является переменной для установки/изменения. roomId - идентификатор комнаты, в случае если пользователь соединен с несколькими комнатами. switchSpectator (roomId:int = -1) : void Переключиться из режима наблюдателя в режим игрока. Работает при условии наличия свободного слота. Смена подтверждается событием onSpectatorSwitched. roomId - идентификатор комнаты, в случае если пользователь соединен с несколькими комнатами. uploadFile (fileRef:FileReference, id:int = -1, nick:String = "", port:int = -1) : void Загрузить файл на встроенный в SmartFoxServer веб-сервер. Upload a file to the embedded webserver. fileRef - объект flash.net.FileReference. id - идентификатор текущего пользователя. nick - имя текущего пользователя. port - порт встроенного веб-сервера |
2008-01-31 |
Sprout Builder в действии: отжиг из бета-версии. Песня! Совсем на днях открылся Sprout Builder — онлайновый флэш-редактор типа WYSIWYG (подробнее у Сергея Фунина). Я попробовал его в действии, и вот что получилось:
Это аццкая машина. На ТехноРанчо тоже в восторге. В моем Файерфоксе откыто 102 вкладки и Sprout работает.. |
SmartFoxServer. Конфигурация зон. Конфигурация зон располагается в контейнерном теге <Zones/> . Каждая зона представлена тегом <Zone/> в Config.xml .Параметры зоны: name - имя зоны uCountUpdate - Вкл/выкл (true/false) посылку сервером сообщений о количестве пользователей. Это необходимо для мониторинга в реальном времени статуса комнат. Для экономии трафика лучше отключить. maxUsers - максимальное число пользователей, которым доступна зона. maxRooms - максимальное число комнат в зоне, которое могут создать пользователи. Без ограничения равно -1. maxRoomsPerUser - максимальное число комнат, которое может создать пользователь за один сеанс. По умолчанию равно 5. emptyNames - Вкл/выкл (true/false) возможность анонимного входа. Если параметр включен, и пользователь входит анонимно, ему присваивается имя "Guest_"+номер. roomListVars - Если "true", то при запросе списка комнат сервер будет выдавать все переменные каждой из комнат. BuddyList - список друзей. Устаревший параметр - не будем его пользовать. В новых версиях список задается во вложенном теге <BuddyList/> .Зона может содержать следующие теги: <Moderators/> - список модераторов. Это контейнер, содержащий список тегов <Mod/> , с двумя параметрами: name и pwd - имя и пароль модератора.<DisabledSysEvents/> , список событий сервера, которые необходимо блокировать. Это контейнер, содержащий список тегов <event/> заключающих в себя название события.<DisabledSysActions/> , список действий сервера, которые необходимо блокировать. Это контейнер, содержащий список тегов <action/> заключающих в себя название действия.<UserNameAvoidChars/> - запрещенные символы в именах пользователей. Указываются в виде строки, заключенной в CDATA.<RoomNameAvoidChars/> - запрещенные символы в именах комнат. Указываются в виде строки, заключенной в CDATA.<MaxUserNamesLen/> - максимальное число символов в именах пользователей.<MaxRoomNamesLen/> - максимальное число символов в именах комнат.<AutoReloadExtensions/> - разрешает немедленное обновление серверных скриптов после их модификации.Ниже рассмотрены другие теги, которые включены в зону. Параметры списка друзей Тег <BuddyList/> определяет конфигурацию списка друзей.Параметр active включает активность списка. Базовые параметры: <mode/> - режим работы: basic (поддерживает совместимость со старыми версиями) и advanced (позволяет использовать новые возможности).<size/> - максимальное число пользователей.<maxBuddyVars/> - максимальное число переменных на каждого друга.Новые параметры: <addBuddyPermission/> , <permissionTimeOut/> , <mutualAddBuddy/> , <mutualRemoveBuddy/> -параметры взаимодействия пользователей в списках друзей.<offLineBuddyVariables/> позволяет включить режим передачи запросов off-line пользователю с ожиданием, когда он выйдет в on-line.<persisterClass/> - позволяет указать имя другого класса для обработки списков друзей.Параметры конфигурации комнат. name - имя комнаты isPrivate - требует пароль для входа pwd - пароль для входа в комнату isGame - включает дополнительные функции, необходимые для игрового сервера. limbo - Специальная комната, которая может содержать тысячи не взаимодействующих посетителей. Такие комнаты не генерируют определенных событий, не позволяют рассылать массовые сообщения и т.п. maxUsers - максимум пользователей, которые могут одновременно присоединиться к комнате. Рекомендуется от 2 до 50 пользователей. maxSpectators - максимум наблюдателей. autoJoin - по команде клиента autoJoin(), пользователь по-умолчанию войдет в эту комнату. uCountUpdate - аналогично одноименному параметру зоны. Для игр лучше установить "false". Переменные по умолчанию <Vars/> содержит список тегов <Var/> . Каждый из тегов содержит параметры переменной:name - имя переменной. type - тип переменной private - если true, переменная является приватной. Серверные скрипты (или расширения) <Extensions/> содержит список тегов <extension/> .Каждый из тегов содержит параметры скрипта: name - имя скрипта. className - имя файла скрипта. type - "script" для ActionScript, "python" для Python, "java" для Java. Другие параметры. Были замечены другие параметры. Для Zone: customLogin Для Room isTemp Их значение выясним позже. |
Настраиваем SmartFoxServer Панель управления SmartFoxServer предоставляет довольно богатый набор возможностей. Для начала заменим пароль администратора сервера. По умолчанию это sfs_admin/sfs_pass, что не очень удобно вводить при старте. Да и сообщение с просьбой сменить пароль надоедает быстро. Идем в раздел Config.xml и находим строку <!-- Adminisitrator login --> . Меняем логин и пароль на более удобные для нас. Пароль должен быть не меньше 6ти символов. Для того, чтобы изменения вступили в силу необходимо рестартовать сервер.В разделе панели Zone Browser можно просмотреть состояние зон. По умолчанию, на сервере уже создано много зон под разные нужды - в основном для работы примеров. Чтобы добавить свою зону нам необходимо опять вернуться к Config.xml. Конфигурацию зон мы рассмотрим в следующем посте. Попробуем дублировать тег Zone для simpleChat. Переименуем имя, установим параметры. Теперь в разделе Zone Browser появилась наша зона и мы можем просмотреть ее комнаты и параметры. Теперь дело за клиентской частью. |
Инструмент для администрирования SmartFoxServer В поставке SmartFoxServer инструмент для администрирования в виде SWF-файла. Если попытаться воспользоваться им локально, локальная политика безопасности Flash Player не даст подключиться к серверу. Чтобы избежать этой проблемы, я нашел два средства:
Теперь можно комфортно администрировать сервер. |
DisplayObjectWrapper от G.Skinnerа. Flex Как сделать, чтобы такие ассеты как Flash-символы или изображения были совместимы с Flex-компонентами? Грант Скиннер (Grant Skinner) предлагает свой способ: "обернуть" ассет в объект UIComponent, который будет транслировать API трансформирования Flex в API трансформации Flash-объектов DisplayObject. Класс "обертки" можно взять здесь. Пимер использования в MXML: // mxml, syntax 1: <local:DisplayObjectWrapper> <DisplayObjectToWrap/> </local:DisplayObjectWrapper> // mxml, syntax 2: <local:DisplayObjectWrapper content="com.gskinner.MyClass"/> // where content is either a qualified class name as a string // mxml, synax 3: <local:DisplayObjectWrapper content="{ myInstance }"/> Пример использования в ActionScript: // in a script block (ex. in an initialization handler):
var dow:DisplayObjectWrapper = new DisplayObjectWrapper(); dow.content = new Sprite(); // or any DisplayObject instance myContainer.addChild(dow); |
Уроки по PureMVC — много, понятно и на русском Flash-, Flex- и AIR-фреймфорк PureMVC (я когда-то начал писать цикл статей о нем (и закончу)) набирает популярность, в том числе и в рунете. Я неоднократно слышал нарекания: мол, новинка вышла, а ничего не понятно, как ею пользоваться — неизвестно. Но не в случае с PureMVC. Уже сейчас на русском языке есть масса статей по этому компактному и фреймворку, в том числе и переводных. В частности, Injun написал о PureMVC несколько отличных постов, за что ему отдельные респект и уважуха:
По поводу моей серии. Моей изначальной целью было последовательное ознакомление с концепциями, заложеннными в PureMVC — и я буду придерживаться этого подхода. Сочетая прикладные аспекты, изложенные в указанных выше статьях Injun'а, со следующими более теоретическими материалами, читатель получит максимально широкое понимание фреймворка PureMVC и не только:
Друзья, еще раз спасибо за массу полезных комментариев к статьям. Я уверен, что ни одна из написанных вами строк не пропадет зря и кому-то (с кем вам, возможно, еще придется работать) поможет разобраться с лучшими практиками разработки. |
Использование embed изображений в стилях Путь скинизации посредством css тернист и многотруден. Особенно если каждый стиль требуют собственных скинов для виджетов (иконок, кнопок и т.д). Предположим нам надо подгрузить картинку. Для примера создадим класс наследованный от UIComponent и требующий подгрузки картинки описанной в css. Назовем класс Example.as.
И после компиляции картинку благополучно не видим. Почему? Потому, что по умолчанию ее размеры составляют 0 x 0. Для того чтобы она отобразилась корректно требуется задать ей реальные размеры, каковые нам любезно предоставляют свойства measuredWidth и measuredHeight. Однако не следует забывать, что актуальные значения ширины и высоты будут доступны только после вызова (автоматического) метода protected function measure(): void UIComponent, о котором доступна подробная информация в хелпе. Ну и собственно результат:
Следует отметить, что подобных проблем с размерами не возникает в mxml-e. |
Видео во Flash/Flex. Проблемы позиционирования. Задачу быстро сделать проигрыватель видео (управление видео-презентацией) я оценил в пару часов. Т.к. совсем недавно разобрался с воспроизведением высококачественного видео, с тех-частью проблем не должно было возникнуть. Проект начал делать на Flex, дабы лишний раз попрактиковаться. Воспроизводить видео действительно получилось быстро. Класс VideoDisplay, управляемый несколькими кнопками и слайдером. И тут встали более сложные задачи.
Первая задача создала одну основную проблему: Получить видео-файл, содержащий сигнальные-точки (cue points). Видео мы выгоняли из AfterEffects в MOV кодеком H.264. Можно ли туда загнать сигнальные-точки (которые, собственно были расставлены в тайм-лайне) и как это сделать - не смогли выяснить. Решили экспортировать в FLV (задрав качество до порядка 3000) - расставить сигнальные точки пришлось вручную в "Adobe Flash CS3 Video Encoder". В принципе, была идея выгнать видео в MOV (высокое качество) и FLV (минимального качества), использовать сигнальные точки FLV а воспроизводить MOV. Для получения сигнальных точек использую следующий код: private function onMeta(event:MetadataEvent):void { this.slider.maximum=event.info.duration; this.__cue_points=event.info.cuePoints; } . . . <mx:VideoDisplay metadataReceived="this.onMeta(event)" . . . > . . . Таким образом, по событию metadataReceived - когда Flex получает метаданные видео-файла - мы получаем массив сигнальных точек. Внимание - свойство cuePoints класса VideoDisplay не будет содержать сигнальные точки, которые находятся в метаданных видео-файла. Это свойство нужно для "ручной" установки сигнальных точек. Управление (добавление/удаление) сигнальными точками cuePoints осуществляется менеджером сигнальных точек cuePointManager. Можно задать их прямо во Flex: <mx:VideoDisplay . . . > <mx:cuePointManagerClass>mx.controls.videoClasses.CuePointManager</mx:cuePointManagerClass> <mx:cuePoints> <mx:Array> <mx:Object time="0" name="point1"/> <mx:Object time="3.034" name="point2"/> <mx:Object time="4.774" name="point3"/> <mx:Object time="8.344" name="point4"/> <mx:Object time="12.271" name="point5"/> </mx:Array> </mx:cuePoints> </mx:VideoDisplay> Итак, мы можем контролировать сигнальные точки. Переходим к обработке пауз на этих точках. Событие cuePoint отлично справляется с нашей задачей: private function onCue(event:CuePointEvent):void { this.video_display.pause(); } <mx:VideoDisplay id="video_display" cuePoint="this.onCue(event)" . . . > При обработке события сигнальной точки, воспроизведение видео останавливается четко в том месте, которое задает сигнальная точка. Это превосходно. Задача номер два. А теперь начинается самое нехорошее. Мы имеем массив точек (каждый элемент содержит объект с двумя свойствами: name - имя маркера, time - время в секундах), и можем позиционировать воспроизведение видео по его элементам. Казалось бы, чего проще: private function onClickNext(event:FlexEvent):void { this.video_display.playheadTime=cue_points[position].time; } Ан нет. Видео позиционируется не точно в указанную позицию - то перескочет на пару секунд, то недотянет. Причем точность настолько низка, что нам пришлось отказаться от такого способа позиционирования. По этому поводу, в документации Flex к свойству playheadTime сказано, что для FLV-файла позиционирование происходит в ключевой фрейм, ближайший к указанной позиции, причем эти ключевые фреймы формируются во время кодирования видео. Поэтому, извиняйте, но точно спозиционироваться в указанное место не получится, если там по близости нет ключевого фрейма. Попробовал позиционировать по тем же контрольным точкам MOV файл. Та же петрушка. Эксперименты показали, что если видео экспортировать в SWF и позиционироваться по фреймам тайм-лайна, точность позиционирования абсолютна. Раз нельзя реализовать нормальную навигацию по подгружаемому MOV/FLV видео, то дальнейшая разработка этого проекта на Flex потеряла всякий смысл. Проще было импортировать видео в SWF, загнать его в мой старый, проверенный презентационный AS2 движок и обработать массив фреймов (составленный вручную за 15 минут), что и было сделано примерно за час. Отрицательный результат - тоже результат. Потратив день на разборки, я узнал мгного нового и получил хороший опыт Flex-разработки. |
2008-01-30 |
Валидаторы данных для Flash Расширяемый набор валидаторов данных для Flash, AS3. Функциональность аналогична валидаторам из Flex SDK. Можно использовать как во Flash-, так и во Flex-приложениях. Валидаторы выполняют стандартную проверку email-адресов, почтовых индексов, номеров кредиток, URL и т.п. Библиотека расширяема под нужды конкретных проектов. Рекомендуется бегло изучить классы библиотеки перед применением. Скачать flash_validators_v0.5.zip. |
Применение HTTPService — новая статья во Flex-wiki Buran опубликовал во Flex-вики новую мини-статью "Применение HTTPService" — об использовании компонента, упрощающего выполнение HTTP-запросов. Попросил ногами не бить :) |
2008-01-29 |
Долой Vista Не зря все-таки Windows Vista считают Именно тогда, хоть мне Vista и нравилась, у меня появилось некое чувство отчужденности к этой операционке. Я не жаловался на тормоза, но вот эта самая несовместимость с продуктами которыми я пользовался, выводила из себя. Мне жалко, тех людей, кто покупает ноуты. Сейчас практически все ноуты поступают с предустановленной Windows Vista. Да я знаю их реакцию, сначала вроде бы все тип-топ и все вроде бы красиво, но потом… Потом встает вопрос ее сноса и переход обратно на XP. Буквально сегодня, на одном сайте по ремонту ноутбуков(!), нашел статью, где все подробно расписывается, на тему сноса Vista. Да… Даже если компании, занимающиеся ремонтов ноутов (которых видимо припарило заниматься проблемами с Vista) , размещают такие статьи… Мало того, Стоит задуматься :) Я и сомневаюсь, что тут поможет сервис пак, который вот-вот выйдет. |
Встреча RAFPUG-3 состоится 17 февраля 2008 года Третья встреча Russian Adobe Flash Platform User Group пройдет 17 февраля 2008 года в Москве в офисе Adobe (подробности по ссылке). Обещает быть интересной: на ней выступят сразу несколько новых докладчиков, в частности, Александр Козловский поделится простым способом создания трёхмерного AIR-приложения. Также будут награжены победители Adobe Prerelease Raffle (а вы внимательно читали отчеты о RAFPUG-2). // via 0xFFFFFF — самый быстрый гуглопочточитатель. |
10 советов по разработке игр для Flash Lite 14 января 2008 года в Mobile and Devices Developer Center появилась статья "Ten tips to help you develop better Flash Lite games". Ее вольный перевод следует ниже. Совет №1: Начинайте с базовой сборки, затем портируйте игруРазные мобильные устройства предлагают разные возможности, в частности, может сильно варьироваться разрешение экрана — от 176x208 до 240x320 пикселей. Выберите разрешение, описанное в спецификации вашей целевой платформы и делайте игру под него — это называется базовой сборкой (base build). Так вы покроете максимум устройств. Хоть и считается, что векторная природа Flash позволяет без проблем масштабировать флэш-приложения, не забывайте, что растровые шрифты и картинки при этом все же пострадают, да и разные пропорции могут привести к обрезанию приложения. После разработки базового билда портируйте игру под другие важные для вашей игры экранные разрешения.Совет № 2: Проектируйте игру с учетом традиций мобильной игровой навигацииПользователи мобильных телефонов привыкли использовать определенные клавиши в играх, так что позаботьтесь о том, чтобы не создавать им сложностей при освоении вашей игры. Ваша игровая навигация должна быть максимально интуитивной. Например, не заставляйте игроков жать клавишу "9" для перемещения вниз там, где более привычно использование джойстика. Старайтесь дублировать такую функциональность, поддерживая оба способа. Изучите традиции игровой мобильной навигации и используйте их. Лучше всего, когда вашу игру не нужно специально осваивать вообще.Совет № 3: Используйте переменные и логику, чтобы ваш код оставался гибкимПопулярная ошибка разработчиков мобильных флэш-игр — это "хардкод" переменных величин, таких, как экранное разрешение. Они просто вписаны в код во множестве мест. Так делать нельзя. Это вылезет боком, когда вы захотите портировать игру под другие устройства, и вообще при внесении любых изменений. Помните: в идеальном коде не бывает чисел кроме нуля в начале цикла. Все переменные должны быть вынесены в отдельный конфигурационный блок кода — и когда вам нужно будет что-то изменить, вы будете четко знать, где искать переменные.Совет № 4: Используйте математику для определения столкновенийЗадача определения столкновений очень популярна в играх. Есть удобный методhitTest , который, однако, не всегда оптимален по производительости. В некоторых случаях нужно отказываться от него и использовать простую математику, работая со свойствами x , y , width и height объектов. Это может оказаться в разы выгоднее.
Совет № 5: Выберите наилучшую структуру событий для вызовов функцийВы можете использовать два генератора событий: кадры или время (setInterval ). Частота событий кадров зависит от FPS вашего приложения. Частота событий времени определяется параметром, указанным вами в вызове setInterval . Хорошей практикой считается умеренное использование событий кадров, так как они могут понизить производительность при неаккуратном обращении. Учитывайте это, и найдите оптимальный для вашего случая вариант. Часто лучшим для вашей игры будет сочетание этих двух генераторов событий.
Совет № 6: Вовлекайте пользователя в игруПредставьте себе игру, где нужно собрать 10 камней за 60 секунд. Теперь представьте, что в ней нет индикаторов, отображающих таймер и количество собранных камней. Это сразу делает игровой процесс в разы скучнее. Даже самые феерические игры могут сильно пострадать, если игрок не видит своего статуса и прогресса. Важным элементом является также таблица рекордов. Люди очень любят сравнивать свои результаты и улучшать их. Сделайте все, чтобы игрок имел стимул играть еще и еще.Совет № 7: Держите код в порядке, используйте ООПДля Flash Lite можно писать приложения на языках ActionScript 1.0 или ActionScript 2.0. Известно, что AS2-код в результате компилируется в AS1. Но именно AS2 предлагает вам ООП, от которого многие до сих пор необдуманно отказыватся, аргументируя это якобы низкой производительностью. Это полная чушь. При грамотной разрабоке ООП не снижает производительность, но дает такие оргомные преимущества, как легкая расширяемость приложений за счет использования четких объектных структур, наследования и других принципов ООП. Вы не пожалеете. Особенно учитывая скорый приход AS3 во Flash Lite, а там без ООП вообще никуда.Совет № 8: Вдумчиво используйте шрифтыРазделите шрифты на декоративные и пиксельные. Декоративные хорошо подходят для крупных красивых надписей, но сьедают больше ресурсов. Пиксельные шрифты хороши там, где нужно вывести много мелкого текста.Используйте целочисленные значения для координат надписей. Избегайте полужирных начертаний (bold). Старайтесь задавать выравнивание текста по левому краю там, где это возможно. Используйте размер шрифта, кратный 8: 6, 16, 24, 32 и т.д. Это позволит выиграть в производительности. Совет № 9: Для игр под FlashLite 1.1 заменяйте массивы строкамиХоть у нас уже есть FlashLite 3.0, самым популярным все же пока остается FlashLite 1.1. Часто вам придется учитывать его популярность, чтобы охватить максимальную аудиторию игроков. Для FlashLite 1.1 может потребоваться симуляция массивов с помощью строк конструкцией видаeval("number" add 1) = 1;
Совет № 10: Тестируйте игру на реальном устройствеЛюбой код может привести к ошибкам выполнения, поэтому вам очень важно проверять свои игры на предмет ошибок в работе. Разделим ошибки на две категории: технические и ошибки производительности. Технические ошибки возникают от синтаксических ошибок в коде или в логике игры. Их легко находить на эмуляторах устройств, это экономит вам время, так как не нужно постоянно закачивать игру на телефон для тестирования.Однако, ошибки производителности часто возникают только на реальных мобильных устройствах. Они связаны с переполнением памяти. Они могут зависеть от других функций устройства, таких, как звонки, SMS и т.п. Поэтому так важно тестировать игру на реальном телефоне, когда уже исправлены технические ошибки, проверенные на эмуляторах Adobe Device Central. Чтобы захватить максимальный круг устройств при тестировании, привлекайте к этому друзей, рассылая им свою игру. Выпускайте игру на рынок только после тщательной проверки качества. Одиннадцатый совет: почитайте оригинал статьи, там есть иллюстрации, ссылки и подробности. Кстати, а кто в рунете делает мобильные игры? |
Переопределение методов с неограниченным числом параметров Это очень короткий пост о том, как в подклассе переопределить метод надкласса, принимающий неограниченное количество параметров. |
Тег [Bindable]. Flex Если нам необходимо связать два свойства так, чтобы при изменении первого (источника) Flex автоматически копировал данные во второе (приемник), мы можем использовать метатег [Bindable]. Указав [Bindable] перед свойством-источником, мы даем понять Flex, что при изменении свойства надо генерировать событие. [Bindable] Если событие не указано явно, то по умолчанию создается событие propertyChange. Тег [Bindable] используется в трех случаях:
ВАЖНО: Если после изменения, свойство не приобрело новое значение, Flex не генерирует событие. Проверка осуществляется по принципу ВАЖНО: Если свойство содержит ссылку на объект и эта ссылка заменяется на другую, то событие генерируется. Если же изменяется объект, на который ссылается свойство, событие генерироваться не будет. Свойства read-only и static по-умолчанию являются источниками связывания данных. В этом примере установщик обновляет значение свойства, и вызывает событие для обновления связываемых свойств. // Define private variable. private var _maxFontSize:Number = 15; [Bindable(event="maxFontSizeChanged")] // Define public getter method. public function get maxFontSize():Number { return _maxFontSize; } // Define public setter method. public function set maxFontSize(value:Number):void { if (value <= 30) { _maxFontSize = value; } else _maxFontSize = 30; // Create event object. var eventObj:Event = new Event("maxFontSizeChanged"); dispatchEvent(eventObj); } Работа с цепочками связываемых свойств. Слкдующий пример показывает довольно длинную цепочку связываемых свойств:<mx:Text id="myText" text="{user.name.firstName.text}"/> Для того, чтобы механизм связывания данных поймал изменения свойства text, достаточно сделать свойство text связываемым. Однако, если необходимо присвоить новое значение какому-либо элементу цепочки на этапе выполнения, то все они должны быть связываемыми. С другой стороны, изменение любого из элементов приведет к неспособности механизма связывания отслеживать изменение свойства text. В случае работы с такими цепочками, можно пользоваться методами BindingUtils.bindProperty() или BindingUtils.bindSetter() . Пример использования bindProperty(): bindProperty(myText, 'text', user, ["name","firstName","text"]); Здесь представлена цепочка в виде ["name","firstName","text"] относительно объекта user. При этом user не является элементом цепочки. В MXML цепочка связываемых свойств всегда задается относительно this: bindProperty(myText, 'text', this, ["user", "name","firstName","text"]);
|
Deep Linking. Flex Новая (ОЧЕНЬ ВАЖНАЯ) фича Flex 3, предоставляющая Flex-приложению возможность управлять данными URL с использованием якорей "#" (также именуемая псевдо-URL). Эта возможность позволяет контролировать изменения URL адресной строки броузера, а также вносить в него изменения. Новые классы: mx.events.BrowserChangeEvent; mx.managers.IBrowserManager; mx.managers.BrowserManager; mx.utils.URLUtil; Application.historyManagementEnabled Пример: Deep Link 1 Deep Link 2 |
AdvancedDataGrid. Flex Стоит задача: список, элементы которого могут содержать изображения, разветвляться. Из всех доступных компонентов, мне показался наиболее подходящим AdvancedDataGrid. Хочется посмотреть, как люди его используют. Покопаем интернет.
В процессе тестирования выяснилось (и сразу вспомнилось, что об этом говорилось на последнем съезде RAFPUG), что advancedDataGrid не является бесплатным компонентом. Об этом, собственно, вещает надпись на компоненте в конечном Flex-приложении. Кроме того, в подобном преступлении был уличен и компонент OLAPDataGrid. Пока оставим этот компонент в покое и перейдем к компоненту попроще - DataGrid. |
Презентации с Flex 3 Prerelease Tour
PS. Оптические эффекты в этом посте спонсированы фирмой Adobe |
2008-01-28 |
HTML завернутый во Flash, снова и снова Подсмотрел у Шаграта: народные умельцы сделали флэш-тему для WordPress. По-моему, мимикрия удалась. А с внедрением в новом Flash Player 10 продвинутых текстовых функций будет еще лучше. Эта блог-тема — одна из иллюстраций возможностей проекта htmlwapper, есть и аналогичный флэш-сайт. Но все равно меня терзает один вопрос. Что это на самом деле — кричащий пример безжалостно убитого времени или действительно перспективная разработка? |
Фокус на кастомном Flex-компоненте Внедряется кастомный компонент, в котором задействована клавиатура. После того, как последовательность интерфейсов доходит до экрана с этим компонентом, он активируется. Но не принимает события от клавиатуры. Необходимо установить на него фокус: Либо добавить в параметры MXML-тега: creationComplete="setFocus();" Либо инициализировать в скрипте: this.[component_name.]setFocus();
|
Eartmine — поиск по реальностиМесто Flash Platform среди лучших стартапов рейтинга The Crunchies 2007На сайте ideablog выложен полный список победителей в главном конкурсе стартапов.Многие из этих проектов так или иначе используют технологию Flash. Но: кроме предсказуемой победы в категории "видео" (сервис Hulu) и такой же очевидной победы сайта флэш-игр Kongregate (лучший “убийца времени”), в победители попал проект с намного более серьезными последствиями. Earthmine — главная технологическая инновация 2007 годаПроект Earthmine индексирует реальность (это их слоган, и он недалек от истины). Эта компания собирает визуальные данные и рендерит их в трехмерную карту Земли. Учитываются не только естественные ландшафты, но даже мелкие объекты, созданные человеком — например, дорожные знаки. Технически, это происходит так: автомобили Earthmine c видеокамерами на крыше ездят и снимают улицы. По этим данным составляется детальная трехмерная модель. Для визуализации модели используется флэш-движок Papervision3D в режиме интерактивной панорамы — можно кликать по объектам и редактировать их. Интересно, что получится, если познакомить этих ребят с парнями из Альтернативы.Демонстрация работы Earthmine: Представьте, куда это может завести. |
2008-01-27 |
Новое дерево Гранта "Садовника" Скиннера Я знаю, почему у Гранта все так хорошо получается с деревьями и вообще. Грант постиг суть флэша — я имею в виду неограниченную вложенность движения. Это свойство делает флэш похожим на живую природу. Грант видит и фиксирует эту самую естественную сторону технологии. Грант медитирует, не торопится и выдает шедевры. Чего и вам желаю: начиная с понедельника — новой жизни всем! Интересной, но не суетной. |