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
Спасибо за то, что поделились!

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