|
|
|||||
Регистрация: Jun 2014
Сообщений: 558
|
Создать экземпляр класса в Pool
Доброго времени суток, возник вопрос, делаю универсальный пул, код ниже
package package_cl{ import flash.display.MovieClip; import flash.events.Event; public class VectorPool_cl { public var vectorPool: Vector.<MovieClip>; private var lengthVector: int; private var movieClip: MovieClip; public function VectorPool_cl(_lengthVector: int, _movieClip: MovieClip) { lengthVector = _lengthVector; movieClip = _movieClip; var i = lengthVector; vectorPool = new Vector.<MovieClip>(i + 1); while (--i > -1){ vectorPool[i] = movieClip; } } public function fn_push_pool (i):void{ vectorPool.push(vectorPool[i]); } public function fn_add_pool ():void{ var vectorMovieClip = movieClip; vectorPool.push(vectorMovieClip); } } } |
|
|||||
...
модератор форума
Регистрация: Sep 2006
Адрес: Minsk
Сообщений: 4,286
|
|
|
|||||
Если коротко:
package package_cl{ import flash.display.MovieClip; public class VectorPool_cl { // Вектор может динамически расширяться - не надо его пересоздавать под каждый размер private var vector:Vector.<MovieClip> = new Vector.<MovieClip>(); public function VectorPool_cl() { } pulbic function fn_get():MovieClip{ if (vector.length > 0) { // Фишка пула - это не создавать новый экземпляр, // если можно использовать ранее созданный return vector.pop(); } // Не создавали раньше ничего - значит всё-таки надо создать return new MovieClip(); } public function fn_push(movieClip:MovieClip):void{ vector.push(movieClip); } } } public static var pool:VectorPool_cl = new VectorPool_cl(); ... a = pool.fn_get() addChild(a); ... removeChild(a) // Вторая фишка пула - нужно _вручную_ туда добавлять ставшие ненужными объекты, // иначе все время будет вызываться new MovieClip(); и от пула не будет никакого толку pool.fn_push(a); ... // И только здесь начинается выгода от использования пула, // b присваивается то, что было в a, без создания MovieClip заново b = pool.fn_get() Решения: 1. Как в приведённой выше ссылке назначить пулу фабрику объектов (вместо фабрики подойдет просто функция, создающуя объект, или просто класс объекта) 2. А нужна ли вам универсальность? Просто копипастим класс пула и меняем MovieClip на нужный тип. Что? Копипаста не всегда является злом: - С одной стороны - это дублирование двух функций. Но с другой - это строгая типизация и не надо громоздить фабрик. Плюс в этих функцях мало что дублируется - там if один всего - Вы особо и не накопипастите - не будет у вас много пулов. Вы будете заводить пул только когда: а) Объекты часто создаются и часто "уничтожаются" (перестают использоваться) б) Создание экземпляров этих объектов является узким местом в приложении с) Вы можете сказать, когда объект стал ненужным, т.е. знаете в каком месте написать: |
|
|||||
Регистрация: Jun 2014
Сообщений: 558
|
expl спасибо большое за объяснение
"универсальный" для моего приложения, у меня в пуле будут либо спрайты, либо мувики, соответственно выбрал мувик. Меня интересовала, как из класса в класс переслать мувик и наделать его экземпляров, тем самым получить пул, в который я смогу отправить нужный мувик, пулов мне понадобиться около 5-7, вот и заморочился, так то я быстро сделаю для каждого отдельный пул, но хочется красоты) Добавлено через 1 час 2 минуты package package_cl{ import flash.display.MovieClip; import flash.events.Event; public class Vector_Pool_cl { public var vectorPool: Vector.<MovieClip> = new Vector.<MovieClip>; private var lengthVector: int; private var movieClip: MovieClip; public function Vector_Pool_cl(_lengthVector: int, _movieClip: MovieClip) { lengthVector = _lengthVector; movieClip = _movieClip; var i = lengthVector; while (--i > -1){ vectorPool.push(movieClip); //как тут создать экземпляр класс? Используя параметры этой функции } } public function fn_push_pool (i):void{ vectorPool.push(vectorPool[i]); } public function fn_add_pool ():void{ var vectorMovieClip = movieClip; vectorPool.push(vectorMovieClip); } } } в общем решение нашёл такое, хотя есть вопрос, код до конца не понимаю package package_cl{ import flash.display.MovieClip; import flash.events.Event; import flash.utils.*; public class Vector_Pool_cl { public var vectorPool: Vector.<MovieClip> = new Vector.<MovieClip>; private var lengthVector: int; private var movieClip: MovieClip; public function Vector_Pool_cl(_lengthVector: int, _movieClip: MovieClip) { lengthVector = _lengthVector; movieClip = _movieClip; var i = lengthVector; //********************************************************* var movieClipDef:Class = MovieClip(movieClip).constructor; //что мы тут делаем, объясните подробно, кому не сложно, // что происходит, после объявления типа класс //мы в итоге получаем экземпляр класса? //************************************************************ while (--i > -1){ var movieClipView = new movieClipDef (); vectorPool.push(movieClipView); } } public function fn_push_pool (i):void{ vectorPool.push(vectorPool[i]); } public function fn_add_pool ():void{ var movieClipDef:Class = MovieClip(movieClip).constructor; var movieClipView = new movieClipDef (); vectorPool.push(movieClipView); } } } Последний раз редактировалось neonoviiwolf; 21.01.2015 в 04:59. |
|
|||||
Цитата:
Использование: Не понимаю, каким образом вы используете эту функцию, она же просто дублирует ссылку: Отсутствует функция добавления отработавших объектов в пул (без создания новых) А объекты вы вызовом pool.vectorPool.pop() забираете? Не, может оно так и надо, но это не совсем пул и я не могу понять, что вам нужно от пула Просто на данный момент ваш класс заменяется следущим кодом: Так зачем усложнять? |
|
|||||
буду краток
модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
|
Делать пул мувиков бессмысленно.
MovieClip используется только если он сделан во FlashIDE При динамическом создании через конструктор - всегда создавайте Sprite. кода не должно быть нигде (разве, что для передачи в кривонаписаный метод с анимациями) Добавлено через 22 минуты Xм. Я кажется понял задачу. API должно быть что-то вроде.. Уже в самом пуле заводим словарик, в качестве ключа - класс, в качестве значений - вектор объектов.
__________________
Отряд Котовскага Последний раз редактировалось Котяра; 21.01.2015 в 13:26. |
|
|||||
Цитата:
А пулы из тех же FlashIDE-шных MovieClip-ов я видел в логических играх, там это убирало подтормаживание при добавлении/удалении шариков на экране Цитата:
А тут, я так понял, человеку надо сначала вообще разобраться что такое пул и как его использовать. |
|
|||||
буду краток
модератор форума
Регистрация: Sep 2003
Адрес: Ближайшее Замкадье
Сообщений: 3,110
Записей в блоге: 28
|
Цитата:
только юз конкретных классов со своими заморочками... как-то очистка перед передачей в пул, установкой максимальной длины пула итп. Ну именно для задачи топикстартера можно было бы и регать каждый конкретнотипный мувик в своём конкретном пуле, через общую обёртку. Перед добавлением добавить проверок на то, что он(мувик) остановлен, что у него нет родителя. Что у него нет подписок на события итп
__________________
Отряд Котовскага |
|
|||||
Регистрация: Jun 2014
Сообщений: 558
|
Мне пришлось использовать мувик, т.к. класс наследуется от мувика, который нарисован и добавлен в библиотеку. По коду у меня организовано думаю так себе, т.к. писал ровно так, как хватало знаний, я не использую *.pop(не понимаю как его использовать в пуле), сделал проще для себя. Объекты живут разное время, но совсем недолго, просто отживший мувик я удаляю со сцены и кидаю ссылку на новый объект в вектор, увеличивая длину вектора, потом удаляю слушатель для мувика, потом ссылку в null, и убираю из вектора ненужный элемент, перевожу индекс на последний элемент добавленный на сцене, что позволяет при вызове не искать свободный мувик, а сразу вывести.
собственно код, написан некрасива, потихоньку исправляюсь, когда пишу новое package package_cl { import flash.events.Event; import package_cl.global_variable_cl; public class bullet_cl extends bullet_mc { private var gl_variable: global_variable_cl = new global_variable_cl(); public function bullet_cl() { this.addEventListener(Event.ADDED_TO_STAGE, fn_speed); } public function fn_speed(e: Event): void { x -= gl_variable.speed_bullet * Math.cos(rotation * Math.PI / 180); y -= gl_variable.speed_bullet * Math.sin(rotation * Math.PI / 180); } } } package package_cl { import flash.events.Event; import package_cl.Vector_Pool_cl; import package_cl.global_variable_cl; //*************************************************************************************** public class Control_bullet_cl { private var fire_ship_Boolean: Boolean = false; private var stageX: int; private var stageY: int; private var _stage: * ; private var vectorBullet: Vector_Pool_cl; private var bullet: bullet_cl = new bullet_cl(); private var gl_variable: global_variable_cl = new global_variable_cl(); public function Control_bullet_cl(stage) { _stage = stage; stageX = _stage.stageHeight - 20; //высота/ширина stageY = _stage.stageWidth - 20; vectorBullet = new Vector_Pool_cl(gl_variable.max_vector_bullet, bullet); _stage.addEventListener(Event.ENTER_FRAME, fn_null_bullet); } //*************************************************************************************** public function fn_fire_down(_x, _y, _rotation): void { if (gl_variable.index_bullet == vectorBullet.vectorPool.length) { vectorBullet.fn_add_pool(); fn_fire_down(_x, _y, _rotation); //рекурсия } else { vectorBullet.vectorPool[gl_variable.index_bullet].x = _x; vectorBullet.vectorPool[gl_variable.index_bullet].y = _y; vectorBullet.vectorPool[gl_variable.index_bullet].rotation = _rotation; _stage.addEventListener(Event.ENTER_FRAME, vectorBullet.vectorPool[gl_variable.index_bullet].fn_speed) _stage.addChild(vectorBullet.vectorPool[gl_variable.index_bullet]); ++gl_variable.index_bullet; } } public function fn_fire_up(_x, _y, _rotation): void { if (gl_variable.index_bullet == vectorBullet.vectorPool.length) { vectorBullet.fn_add_pool(); fn_fire_up(_x, _y, _rotation); //рекурсия } else { vectorBullet.vectorPool[gl_variable.index_bullet].x = _x; vectorBullet.vectorPool[gl_variable.index_bullet].y = _y; vectorBullet.vectorPool[gl_variable.index_bullet].rotation = _rotation; _stage.addEventListener(Event.ENTER_FRAME, vectorBullet.vectorPool[gl_variable.index_bullet].fn_speed) _stage.addChild(vectorBullet.vectorPool[gl_variable.index_bullet]); ++gl_variable.index_bullet; } } //*************************************************************************************** public function fn_null_bullet(e: Event): void { var i = vectorBullet.vectorPool.length; while (--i > -1) { if (vectorBullet.vectorPool[i] != null) { if (vectorBullet.vectorPool[i].stage != null) { if (vectorBullet.vectorPool[i].y > stageX || vectorBullet.vectorPool[i].y < 150 || vectorBullet.vectorPool[i].x > stageY || vectorBullet.vectorPool[i].x < 10) { _stage.removeEventListener(Event.ENTER_FRAME, vectorBullet.vectorPool[i].fn_speed); vectorBullet.fn_push_pool(i); _stage.removeChild(vectorBullet.vectorPool[i]); vectorBullet.vectorPool[i] = null; vectorBullet.vectorPool.splice(i, 1); --gl_variable.index_bullet; } } } } } } } package package_cl{ import flash.display.MovieClip; import flash.events.Event; import flash.utils.*; public class Vector_Pool_cl { public var vectorPool: Vector.<MovieClip> = new Vector.<MovieClip>; private var lengthVector: int; private var movieClip: MovieClip; public function Vector_Pool_cl(_lengthVector: int, _movieClip: MovieClip) { lengthVector = _lengthVector; movieClip = _movieClip; var i = lengthVector; var movieClipDef:Class = MovieClip(movieClip).constructor; while (--i > -1){ var movieClipView = new movieClipDef (); vectorPool.push(movieClipView); } } public function fn_push_pool (i):void{ vectorPool.push(vectorPool[i]); } public function fn_add_pool ():void{ var movieClipDef:Class = MovieClip(movieClip).constructor; var movieClipView = new movieClipDef (); vectorPool.push(movieClipView); } } } |
|
|||||
Судя по всему у вас пул используется не для оптимизации, а чтобы хранить список объектов, причём как-то странно
Там есть забирание мувиклипов из буфера и набивание _новых_ мувиклипов в буффер(который зовется пулом почему-то), а так, чтобы повторно использовались удалённые с экрана мувиклипы - не нашёл Как бы оно могло выглядеть вообще БЕЗ пула (логика изменена, т.к. маловато кода для её восстановления, идентификаторы переименованы чисто для себя - у вас слишком суровый стиль кодирования): //Пуля та же, только переименования package package_cl { import flash.events.Event; import package_cl.GlobalVariables; public class Bullet extends bullet_mc { private var globalVariables: GlobalVariables = new GlobalVariables(); public function Bullet() { addEventListener(Event.ADDED_TO_STAGE, onEnterFrame); } public function onEnterFrame(e: Event): void { x -= globalVariables.speed_bullet * Math.cos(rotation * Math.PI / 180); y -= globalVariables.speed_bullet * Math.sin(rotation * Math.PI / 180); } } } package package_cl { import flash.events.Event; import flash.display.Stage; import package_cl.MovieClipPool; public class BulletsController { private var stageX: int; private var stageY: int; private var _stage: Stage; private var activeBullets:Vector.<Bullet> = new Vector.<Bullet>();// Это не пул, это просто список public function BulletsController(stage:Stage) { _stage = stage; stageX = _stage.stageHeight - 20; stageY = _stage.stageWidth - 20; _stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); } public function onEnterFrame(e: Event): void { spawnSomeBullets(); removeInvisibleBullets(); } private function spawnSomeBullets():void { // Вашу задумку не могу угадать, поэтому просто создадим 10 пуль for (var i:int = 0; i < 10; i++) { var bullet:Bullet = new Bullet(); bullet.x = _x; bullet.y = _y; bullet.rotation = i * 30; // Не знаю зачем здесь слушатель ещё и на стейдж, но пусть будет _stage.addEventListener(Event.ENTER_FRAME, bullet.onEnterFrame) _stage.addChild(bullet); activeBullets.push(bullet); } } private function removeInvisibleBullets(): void { for (var i:int = activeBullets.length; i-- > 0;) // --> - оператор DownTo :) { Bullet bullet = activeBullets[i]; if (bullet != null) { if (bullet.stage != null) { if (bullet.y > stageX || bullet.y < 150 || bullet.x > stageY || bullet.x < 10) { _stage.removeEventListener(Event.ENTER_FRAME, bullet.onEnterFrame); _stage.removeChild(bullet); activeBullets.splice(i, 1); } } } } } } } package package_cl { import flash.events.Event; import flash.display.Stage; import package_cl.MovieClipPool; public class BulletsController { private var stageX: int; private var stageY: int; private var _stage: Stage; private var activeBullets:Vector.<Bullet> = new Vector.<Bullet>();// Это не пул, это просто список private var pool = new BulletPool();// ИЗМЕНЕНИЕ 1 public function BulletsController(stage:Stage) { _stage = stage; stageX = _stage.stageHeight - 20; stageY = _stage.stageWidth - 20; _stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); } public function onEnterFrame(e: Event): void { spawnSomeBullets(); removeInvisibleBullets(); } private function spawnSomeBullets():void { // Вашу задумку не могу угадать, поэтому просто создадим 10 пуль for (var i:int = 0; i < 10; i++) { var bullet:Bullet = pool.newBullet();// ИЗМЕНЕНИЕ 2 bullet.x = _x; bullet.y = _y; bullet.rotation = i * 30; // Не знаю зачем здесь слушатель ещё и на стейдж, но пусть будет _stage.addEventListener(Event.ENTER_FRAME, bullet.onEnterFrame) _stage.addChild(bullet); activeBullets.push(bullet); } } private function removeInvisibleBullets(): void { for (var i:int = activeBullets.length; i-- > 0;) // --> - оператор DownTo :) { Bullet bullet = activeBullets[i]; if (bullet != null) { if (bullet.stage != null) { if (bullet.y > stageX || bullet.y < 150 || bullet.x > stageY || bullet.x < 10) { _stage.removeEventListener(Event.ENTER_FRAME, bullet.onEnterFrame); _stage.removeChild(bullet); activeBullets.splice(i, 1); pool.releaseBullet();// ИЗМЕНЕНИЕ 3 } } } } } } } package package_cl{ import flash.display.MovieClip; public class BulletPool { private var vector:Vector.<Bullet> = new Vector.<Bullet>(); public function BulletPool() { } public function newBullet():Bullet{ if (vector.length > 0) return vector.pop();// pop удаляет последний элемент и возвращает его return new Bullet(); } public function releaseBullet(movieClip:Bullet):void{ vector.push(movieClip); } } } |
Часовой пояс GMT +4, время: 20:48. |
|
« Предыдущая тема | Следующая тема » |
|
|