FlashImp Flash Implosion new generation

29Дек/110

Структуры данных: MagicObject

source:

Название MagicObject, имхо, явно лучше E4XMap и подобных названий.

Intro.

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

Сегодня хочу поделиться простенькой реализацией e4x в Объекте, где основной фишкой является расширение нативного e4x, который не позволяет callDescendants.

Например вот так:

object..method(args)

Зачем это нужно?
Допустим, дано:
- StateMachine и сложное дерево состояний;
- Анимация игрового объекта завязана на состояния, точнее, на смены состояний;
- Есть VO (ValueObjects) и есть рендеры, которые визуализируют изменения в VO;
- Рендеры имеют сложную иерархию, уровни вложенности.

Как происходит изменение состояния и отображение изменений при использовании MagicObject:
- Изменяем состояние в StateMachine;
- При удачном изменении состояния обновляем данные в VO;
- Вызываем обновление во всех рендерах внутри игрового уровня:

// magic = MagicObject instance
// magic[keyA] = Renderer instance
// magic[keyB] = Renderer instance
// magic[keyB][keyC] = Renderer instance - sub-renderer
// magic.subMagic.[keyD] = Renderer instance - sub-renderer
(magic..update)();
// или так:
(magic..update)(magic.changes);

Метод update() вызовется последовательно у всех объектов, имеющих этот метод.

Поясню как работает:
magic..update достаёт со всех уровней вложенности значения всех полей с именем update. Если там есть экземпляры класса Function, то всё это хозяйство оборачивается noname-фукцией, а ей задаются все свойства массива (для итеративного пробега) и пары, типа ключ-значение, где значение - каждое найденое поле с именем update.
На примере:

const result:Object = magic..update;
// можно вызвать:
result(); // or result(args);
// можно получить определённый элемент:
for(var key:String in magic)
	trace('in', magic, ':', key, '=', magic[key]),
	// или вызвать:
	magic[key] is Function && magic[key]();

History tracking:

const magic:MagicObject = new MagicObject();
magic.x = 0;
magic.x = 1;
 
// вернёт все изменения на первом уровней вложенности:
trace(magic.changes); // :Vector.<MagicNode>
 
// вернёт все изменения на всех уровнях вложенности:
trace(magic..changes); // [:Vector.<MagicNode>,..] или Vector.<MagicNode> если элемент один.
 
// чистим историю изменений:
magic.clearChanges();
// or magic..clearChanges();

Уведомления об изменениях:
Создали экземпляр:

 const magic:MagicObject = new MagicObject();

Дали ссылку на колбэк:

magic.notificationCallback = function():void
	{
		trace('new changes:', magic.changes);
	}

или так:

magic.notificationCallback = function(changes:Vector.<MagicNode>):void
	{
		trace('new changes:', changes);
	}

сдели какие-то изменения:

 magic.x = 0;
magic.x = 1;

.. и мы сразу получаем эти изменения в колбэк.

Собственно сам класс лежит здесь.

Вот пример расширения на деле:

package ru.kozlovskij.game.objects.data
{
	import ru.kozlovskij.utils.data.MagicNode;
	import ru.kozlovskij.utils.data.MagicObject;
 
	/**
	 * @author Aleksandr Kozlovskij (created: Dec 27, 2011)
	 */
	public dynamic class GameObjectData extends MagicObject
	{
		protected static const PRIVATE_ACCESSOR_PREFIX:String = '_';
 
		private var _notificationCallback:Function;
 
		//------------ constructor ------------//
 
		public function GameObjectData()
		{
			super();
			super.notificationCallback = __notificationCallback;
		}
 
		//------------ initialize ------------//
 
		//--------------- ctrl ---------------//
 
		//------------ get / set -------------//
 
		public function get selected():Boolean
		{
			return this._selected;
		}
 
		public function set selected(value:Boolean):void
		{
			this._selected = value;
		}
 
 
		override public function get notificationCallback():Function
		{
			return _notificationCallback;
		}
 
		override public function set notificationCallback(value:Function):void
		{
			_notificationCallback = value;
		}
 
		//------- handlers / callbacks -------//
 
		protected function __notificationCallback(changes:Vector.<MagicNode>):void
		{
			const ns:Namespace = nodeResetNS;
			for each(var node:MagicNode in changes)
			{
				const property:String = node.public::property;
				if(property.charAt() == PRIVATE_ACCESSOR_PREFIX)
					node.ns::property = property.substr(1);
			}
 
			// finally:
			_notificationCallback && (_notificationCallback.length ? _notificationCallback(changes) : _notificationCallback());
		}
	}
}

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

30Ноя/110

Flex 4.6 Released

Вчера был выпущен в паблик Flex 4.6.0 (Release).

Метки записи: Нет комментариев
28Ноя/110

TexturePacker

Открыл для себя прекрасный генератор атласов тектур под OS X. Зовут "TexturePacker".
Бесплатен. И Про-версию раздают.
Фичи многообещающи.
screenshot

Связано с категорией: Новости Нет комментариев
28Окт/110

Определятор статуса, типа и представления экранной клавиатуры.

Приветствую, коллеги.

Коротко о главном:
В комбинации AIR + iOS + {желание работать с текстом, клавой} есть одна большая проблема - это и есть большая проблема.

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


  • Предлагаю вам, товарищи, мой детектор статуса, типа и представления экранной клавиатуры. Только для iOS. Актуализирован для работы под iOS 5.0.

    iOS Split Keyboard
    Он скажет вам:

  • Тип представления экранной клавиатуры
  • Экранная клавиатура активирована;
  • Экранная клавиатура деактивирована;
  • Сменился relatedObject;
  • Пользователь изменил тип представления экранной клавиатуры (сдвинул или раздвинул).
  • Note:
    Работает с обычными текстовыми полями и с новеньким StageText.
    В симуляторе не работает и не должно, ибо он крив и только лживо симулирует. Только iOS.

    Это не ANE. Only pure AS3.

    Да, только библиотека SWC + демо-проект + дока.

    Метки записи: , , , Нет комментариев
    9Март/110

    Wallaby prerelease

    Вышел обещанный н MAX'e фрэймворк для конвертации Flash-контента в HTML5.

    На самом деле это AIR-приложение, сыренькое. Конвертируются только .FLA, состряпанные в Flash Pro CS5.

    Link on labs. Help.

    Метки записи: , Нет комментариев
    9Март/110

    Adobe Flash Player 10.3 Beta

    Flash Player 10.3 for Windows, Mac, and Linux introduces new developer features and enhanced user privacy protection, such as:

    • Media Measurement
    • Acoustic Echo Cancellation
    • Integration with browser privacy control for local storage
    • Native Control Panel
    • Auto-Update Notification for Mac OS

    Link.

    Метки записи: , Нет комментариев
    9Сен/100

    Apple снимает ограничения для Flash – разработчиков.

    Сегодня Apple сообщили, что ограничения в использовании средств разработки под iOS будут сняты.

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

    Метки записи: , , Нет комментариев
    15Авг/100

    I’m alive. FlashImp too.

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

    Связано с категорией: Новости Нет комментариев
    17Июнь/101

    It’s Adobe :) LOL

    Check out cool app description...Adobe Dreamweaver Widget Browser

    Adobe Dreamweaver Widget Browser


    download link

    Связано с категорией: Новости 1 комментарий
    28Апр/101

    UINativeWindow

    package ru.kozlovskij.air
    {
    	import flash.display.DisplayObject;
    	import flash.display.DisplayObjectContainer;
    	import flash.display.NativeWindow;
    	import flash.display.NativeWindowInitOptions;
    	import flash.events.Event;
     
    	import mx.core.IUIComponent;
    	import mx.events.FlexEvent;
    	import mx.managers.WindowedSystemManager;
     
    	/**
    	 * Composition of <code>NativeWindow</code> and <code>IUIComponent</code>.
    	 * 
    	 * @author Aleksandr.Kozlovskiy
    	 */	
    	public class UINativeWindow extends NativeWindow
    	{
    		protected var systemManager:WindowedSystemManager;
    		protected var childDisplayObject:IUIComponent;
    		protected var rootDisplayObject:IUIComponent;
     
    		/**
    		 * After initialization <code>childDisplayObject</code> added to <code>systemManager</code>'s displaylist.
    		 * 
    		 * 
    		 * @param initOptions:NativeWindowInitOptions - Analogically NativeWindow initOptions.
    		 * @param rootDisplayObject:IUIComponent - Root Application or other IUIComponent implementation. Mast extends DisplayObject.
    		 * @param childDisplayObject:IUIComponent - Container. Child Application or other IUIComponent implementation. Mast extends DisplayObject.
    		 * 
    		 */		
    		public function UINativeWindow(initOptions:NativeWindowInitOptions,
    									   rootDisplayObject:IUIComponent,
    									   childDisplayObject:IUIComponent)
    		{
    			super(initOptions);
    			this.rootDisplayObject = rootDisplayObject;
    			this.childDisplayObject = childDisplayObject;
     
    			addChildren();
     
    			stage.addEventListener(Event.RESIZE, stageResizeHandler);
    		}
     
    		protected function addChildren():void
    		{
    			childDisplayObject.addEventListener(FlexEvent.CREATION_COMPLETE, childCreationCompleteHandler, false, 0, true);
    			(stage.addChild(systemManager = new WindowedSystemManager(rootDisplayObject)) as DisplayObjectContainer)
    				.addChild(childDisplayObject as DisplayObject);
     
    			stageResizeHandler();
    		}
     
    		protected function childCreationCompleteHandler(e:FlexEvent):void
    		{
    			childDisplayObject.removeEventListener(FlexEvent.CREATION_COMPLETE, childCreationCompleteHandler);
    			stageResizeHandler();
    		}
     
     
    		// ------------------ resize ----------------------- //
     
    		protected function stageResizeHandler(e:Event = null):void
    		{
    			childDisplayObject.width = stage.stageWidth;
    			childDisplayObject.height = stage.stageHeight;
    		}
    	}
    }
    Метки записи: , , , 1 комментарий