Показать сообщение отдельно
Старый 17.03.2016, 11:01
a7s1h1 вне форума Посмотреть профиль Отправить личное сообщение для a7s1h1 Найти все сообщения от a7s1h1
  № 1  
Ответить с цитированием
a7s1h1

Регистрация: Oct 2013
Сообщений: 126
Post проверьте, пожалуйста, пул

Здравствуйте!
Я наконец-то созрел для применения объектного пула. Проверьте, пожалуйста, пул ли у меня получился вообще и если да, правильно ли всё сделал?

Итак, есть объект "блок", вот его класс:
Код AS3:
package Objects  {
	import animation.AntActor;
	import flash.display.Sprite;
	import flash.events.Event;
	import rc.MyMath;
	import rc.TF;
	//@author 7_11
 
	public class Block extends Sprite {
 
		private var _img:AntActor
		private var _tree:AntActor;
		private var _text:TF;
 
		public var type:uint; // тип блока
 
		// CONSTRUCTOR
		public function Block() {
			_img = new AntActor(); // картинка блока
			_img.addAnimFromCache('Block_s') // присваивает изображение
			addChild(_img) //добавляем картинку
			// текстовое поле
			_text = new TF(40, 40, '' + type, 12 + type * 3, 'center', 0xffffff);
			addChild(_text);
 
			// ни объект, ни его дети не взаимодействуют с мышью
			mouseEnabled = false; 
			mouseChildren = false;
 
			addEventListener(Event.ADDED_TO_STAGE, init); // инициализация
			addEventListener(Event.REMOVED_FROM_STAGE, reset); // обнуление параметров при удалении со сцены
		};
 
		//INIT
		private function init(e:Event): void {
			// c вероятностью 15% создаём деревце
			if (MyMath.randomRange(0, 100) < 15) {
				_tree = new AntActor();
				_tree.addAnimFromCache('Tree_s');
				_tree.x = 40;
				addChild(_tree)
			}
			// обновляем текст, т.к. мог измениться тип блока (присваивается родителем, поэтому переменная type публичная)
			_text.update( '' + type);
		}
 
		// ОБНУЛЯЕМ ПАРАМЕТРЫ (при удалении со сцены)
		private function reset(e:Event): void {	
			// обнуляем параметры
			type = 0; // тип по умолчанию 0
                        // если есть деревце - удаляем его
			if (_tree) {
				_tree.free();
				//removeChild(_tree); // удалять дерево как ребёнка не нужно, метод free() заставил его удалиться само
				_tree=null;
			}
		};
 
		//CLEANUP (окончательная чистка при удалении со сцены родителя)
		public function cleanup(): void {
			// чистим слушателей
			removeEventListener(Event.ADDED_TO_STAGE, init);
			removeEventListener(Event.REMOVED_FROM_STAGE, reset);
                       // чистим акторов
			_img.free();
			_tree.free();
			// удаляем детей
			removeChildren();
			// обнуляем ссылки
			_img = null;
			_tree = null;
			_text = null;
		}
	};
};
В классе "world", который является родителем для всего, что находится и происходит в мире игры, есть два массива: с блоками, которые на сцене, и с пулом:
Код AS3:
private var _blocks:Vector.<Block>; 	// массив с блоками
private var _blocksPool:Vector.<Block>; // пул с блоками
При инициализации "мира" эти массивы создаются:
Код AS3:
_blocks = new Vector.<Block>(); 		// создаём массив блоков
_blocksPool = new Vector.<Block>(); 	// создаём пул блоков
в кадре проверяются все блоки на сцене и удаляются (переносятся в пул) те, которые оказались за краем. Вот кусок кода с удалением блока:
Код AS3:
...
put_block(b); // суём блок в пул
removeChild(b); // удаляем блок со сцены (при этом срабатывает внутренний метод блока reset() для обнуления параметров, но тех своих детей, которые нужны блоку всегда, он не удаляет)
_blocks.splice(i, 1); // удаляем блок 
...
А это кусок кода с добавлением блока из пула на сцену:
Код AS3:
...
var block:Block = get_block(); 		//берём последний блок из пула (в пуле его удаляем)
// присваиваем блоку координаты и тип
block.x = sx + BlockW * (b + 1);
block.y = GL;
block.type = _waves[wl][b];
// добавляем новый блок в масcив и на сцену
_blocks.push(addChild(block));
...
А это сами методы пула, которые я позаимствовал у Zebestov из вот этой темы:

Код AS3:
// Берём блок из пула
private function get_block():Block { 
	// если в пуле есть блоки - берём их оттуда, если нет - создаём
	return (_blocksPool.length) ? (_blocksPool.pop()) : (new Block());
}
 
// Кладём блок в пул
	private function put_block(block:Block):void {
_blocksPool[_blocksPool.length] = block;
}
Ну и наконец, чистка вектора и пула блоков при удалении со сцены класса "мира":
Код AS3:
// чистим массивы
var bl:int = _blocks.length;
for (var bi:uint = 0; bi < bl; bi++ ) { _blocks[bi].cleanup() };
_blocks.splice(0, _blocks.length);
var bpl:int = _blocksPool.length;
for (var bpi:uint = 0; bpi < bpl; bpi++ ) { _blocksPool[bpi].cleanup() };
_blocksPool.splice(0, _blocksPool.length);
_blocks = null;
_blocksPool = null;
Подскажите, пожалуйста, верно ли я понял принцип пула и насколько удачно его реализовал? (на глаз работает так же, как при создании-удалении экземпляров).


Последний раз редактировалось a7s1h1; 17.03.2016 в 13:26.