Framework: Eventer & Simulation

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

Eventer

elmortem.game.Eventer
package elmortem.game {
        import flash.events.Event;
        import flash.events.IEventDispatcher;
        
        public class Eventer {
                private var _events:Array;
                
                public function Eventer() {
                        _events = [];
                }
                public function free():void {
                        _events = null;
                }
                
                public function add(dispatcher:IEventDispatcher, event:Event):void {
                        _events.push( { dispatcher:dispatcher, event:event } );
                }
                
                public function step():void {
                        if (_events.length > 0) {
                                        var e:Object = _events[0];
                                        _events.splice(0, 1);
                                        e.dispatcher.dispatchEvent(e.event);
                        }
                }
        }
}


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

Simulation

elmortem.game.Simulation
В этом классе происходит хранение и обработка всех элементов игры, к которым относятся сущности (Entity) и сенсоры (ISense).
package elmortem.game {
        import elmortem.game.entities.EntityManager;
        import elmortem.game.senses.ISense;
        import flash.events.Event;
        
        public class Simulation {
                // Менеджер сущностей
                public var entityManager:EntityManager;
                public var eventer:Eventer;
                // Массив сенсоров
                private var senses:/*ISense*/Array;
                private var isPause:Boolean = false;
                
                public function Simulation() {
                        entityManager = new EntityManager(this);
                        eventer = new Eventer();
                        senses = [];
                }
                public function free():void {
                        entityManager.free();
                        entityManager = null;
                        
                        for (var i:int = 0; i < senses.length; i++) {
                                senses[i].free();
                        }
                        senses = null;
                        
                        eventer.free();
                        eventer = null;
                }
                
                // SENSE
                public function addSense(s:ISense):ISense {
                        senses.push(s);
                        return s;
                }
                public function removeSense(s:ISense):Boolean {
                        if (s == null) return false;
                        var i:int = senses.indexOf(s);
                        if (i >= 0) {
                                senses.splice(i, 1);
                                return true;
                        }
                        return false;
                }
                public function removeSenseByName(name:String):Boolean {
                        return removeSense(getSense(name));
                }
                public function getSense(name:String):ISense {
                        for (var i:int = 0; i < senses.length; i++) {
                                if (senses[i].name == name) return senses[i];
                        }
                        return null;
                }
                
                // PAUSE
                public function get pause():Boolean {
                        return isPause;
                }
                public function set pause(val:Boolean):void {
                        isPause = val;
                }
                
                // Метод обработки игры
                public function update(delta:Number):void {
                        if (!isPause) {
                                for (var i:int = 0; i < senses.length; i++) {
                                        senses[i].update(delta);
                                }
                                entityManager.update(delta);
                                entityManager.render();
                        }
                        // Важный момент, Eventer работает даже если игра на паузе
                        eventer.step();
                }
        }
}


Собственно, вот и весь двиган. За кадром остались классы, реализующие различные сенсоры и примеры использования всего этого добра. Если кому-то интересно, как всё это использовать — пишите, могу набросать простейших примеров.

Так же мне было бы очень интересно поглядеть на ваши движки. Расскажете?

P.S. Про оптимизацию. Как видно из кода оптимизациями я не очень-то занимался, везде массивы и не оптимизированные циклы. Считаю это не страшным, но в планах, конечно, заняться этим серьёзнее.
  • +4

Комментарии (4)

0
Спасибо за то, что поделились!

Да, было бы интересно посмотреть, как это все в комплексе работает.
  • abyss
  • abyss
0
Спасибо! Очень-очень интересно смотреть на чужие исходники. Особенно инди-разработчикам у которых нет команды, с которой они могли бы общаться. Как полезно посмотреть на оформление кода, так и на логику. Я думаю, для логического завершения было бы отлично получить пример. Будем ждать с нетерпением.
  • Regul
  • Regul
0
Наверное имеет смысл записать скринкас, т.к. кода достаточно много будет и в посте не очень красиво получится… Подумаю над этим.
0
Можно выложить исходники, а в посте прокомментировать.
Писать скринкаст не быстрое дело, наверное.
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.