Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как выводить много одинаковых изображений одновременно? (http://www.flasher.ru/forum/showthread.php?t=206559)

Agiliter 11.02.2014 17:24

Как выводить много одинаковых изображений одновременно?
 
Суть вот в чем: Есть *.fla и класс *.as. Сцена пустая. В классе я добавляю изображение корабля, который стреляет со своих бортов ядрами. По 5-10 ядер одновременно. Используются всего две картинки ship.png и cannonball.png

Код AS3:

private var ship:Loader;
private var cannonball_1 :Loader;
//...
private var cannonball_10 :Loader;
//...
ship = new Loader();
ship.load(new URLRequest("ship.png"));
cannonball_1 = new Loader();
cannonball_1.load(new URLRequest("cannonball.png"));
cannonball_2 = new Loader();
cannonball_2.load(new URLRequest("cannonball.png"));
cannonball_3 = new Loader();
cannonball_3.load(new URLRequest("cannonball.png"));
//....
cannonball_10 = new Loader();
cannonball_10.load(new URLRequest("cannonball.png"));
 
addChild(cannonball_1);
//...
addChild(cannonball_10);
addChild(ship);

Каждый раз новый объект создавать.. Это ж свихнуться можно. А потом еще и каждое ядро отдельно надо наделить координатами и направлением полета..
А если мне нужно 100500 одинаковых объектов задавать? Должно же быть простое решение. Подскажите выход из ситуации.

samana 11.02.2014 17:33

А вам обязательно загружать эти картинки? Если вы работаете во Flash IDE, то можно просто поместить их с библиотеку и доставать оттуда. Или воспользоваться тегами enbed, чтобы встроить изображение в класс. В какой среде вы работаете?

illuzor 11.02.2014 17:33

Для этих целей существуют циклы. Координаты и направления полёта можно поместить в массив.
Не нужно грузить один и тот же файл много раз. Достаточно загрузить его один раз, вытащить из него битмапдату и из неё создавать нужное количество битмапов.

Akopalipsis 11.02.2014 21:20

Код AS3:

package  
{
        import flash.display.Bitmap;
        import flash.display.BitmapData;
        import flash.display.DisplayObject;
        import flash.display.Loader;
        import flash.display.LoaderInfo;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.IOErrorEvent;
        import flash.events.MouseEvent;
        import flash.net.URLRequest;
        public class TestClass extends Sprite
        {
                /*свойство показывающее сколько заряжать за один раз*/
                private const NUMBER_CANNONBALLS:int = 5;
                /*массив ядер которые находятся в списке отображения ( СО )*/
                private var _cannonballs:Array;
                /*массив в котором хранятся ядра*/
                private var _pool:Array;
                /*свойство хранящее длину массива ядер находящихся в СО*/
                private var _cannonballsCount:Number;
                /*свойство времени*/
                private var _time:Number;
                public function TestClass()
                {
                        //создаем массивы
                        _cannonballs = [];
                        _pool = [];
                        //задаем норму времени, во флеш оно вроде в милисекундах..
                        //тут  не понимаю и даже объяснять не буду
                        _time = 1 * 0.001 * stage.frameRate;
 
                        var loader:Loader = new Loader();
                        loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, loader_ioError);
                        loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_complete);
                        loader.load(new URLRequest('../lib/cannonball.png'));
 
                        stage.addEventListener(MouseEvent.CLICK, stage_click);
                }
                /*это если при загрузке будут ошибки*/
                private function loader_ioError(event:IOErrorEvent):void
                {
                        trace(event.errorID);
                }
                /*завершение загрузки*/
                private function loader_complete(event:Event):void
                {
                        //удаляем слушатели
                        var loader:Loader = (event.target as LoaderInfo).loader;
                        loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, loader_ioError);
                        loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loader_complete);
 
                        //сохраняем BitmapData загруженной картинки ядра
                        var bitmapData:BitmapData = event.target.content.bitmapData as BitmapData;
                        const cannonballCount:int = 10;//число указывающее сколько ядер нужно создать
                        var cannonball:Bitmap;
                        while (cannonballCount--)
                        {
                                cannonball = new Bitmap(bitmapData);//создаем объект cannonball
                                //и помещаем его в массив, а в сам класс ядра передаём созданный объект
                                //ядра и ссылку на метод, который быдет вызываться их класса ядра
                                _pool[cannonballCount] = new Cannonball(cannonball, this.prepareForPpool);
                        }
                }
                /*этот метод вызывается из класса ядра по завершению полета ядра*/
                public function prepareForPpool(target:Cannonball):void
                {
                        //так как ядро уже отлеталось, мы получаем его индекс в массиве
                        //ядер находящихся в СО
                        var index:int = _cannonballs.indexOf(target);
                        this._cannonballs.splice(index, 1);//удаляем его и массива
                        super.removeChild(target.target);//из СО
                        this._pool.push(target);//помещаем на хранение в пул
                        this._cannonballsCount = _cannonballs.length;//переназначаем значение свойству
                        //которое показывает, сколько сейчас ядер в массиве объектов находящихся в СО
                }
                /*клик по сцене*/
                private function stage_click(event:MouseEvent):void
                {
                        if (!hasEventListener(Event.ENTER_FRAME))//если события нет
                        {
                                addEventListener(Event.ENTER_FRAME, enterFrame);//то подписываемся
                        }
                        this.shoot();//и стреляем
                }
                /**/
                private function shoot():void
                {
                        var count:int = NUMBER_CANNONBALLS;//число заряжаемых за раз ядер
                        var cannonballs:Cannonball;
                        var n:int = 0;//свойство просто для примера, чтоб менять координаты
                        if (_pool.length)//если есть свободные ядра
                        {
                                while (count--)
                                {
                                        cannonballs = _pool[0];//присваеваем объект
                                        _pool.splice(0, 1);//удаляем из пула
                                        cannonballs.setCoords(10, 100, n += 50, n);//задаем координаты
                                        _cannonballs.push(cannonballs);//помещаем в массив объектов в СО
                                        super.addChild(cannonballs.target);//добавляем в СО
                                        this._cannonballsCount = _cannonballs.length;//обнавляем значение свойства указывающего
                                        //сколько ядер в массиве
                                }
                        }
                }
                /**/
                private function enterFrame(event:Event):void
                {
                        var cannonballObject:Cannonball;
                        const cannonballCount:int = this._cannonballsCount;
                        while (cannonballCount--)
                        {
                                cannonballObject = _cannonballs[cannonballCount];
                                cannonballObject.move(_time);
 
                                if (!_cannonballs.length) removeEventListener(Event.ENTER_FRAME, enterFrame);
                        }
                }
 
 
        }
 
}

Код AS3:

package  
{
        import flash.display.Bitmap;
 
        public class Cannonball extends Object
        {
 
                public var target:Bitmap;//ядро
                private var _prepareForPpool:Function;//метод по завершению
                // координаты
                private var _finishX:Number;
                private var _finishY:Number;
                private var _startX:Number;
                private var _startY:Number;
                //задержка
                private const DURATION:Number = 1;
                //растояние которое должно пролететь ядро перед удалением
                private var _distance:Number;
 
                public function Cannonball(target:Bitmap,prepareForPpool:Function)
                {
                        this.target = target;
                        _prepareForPpool = prepareForPpool;
                }
                public function setCoords(startX:Number,finishX:Number,startY:Number,finishY:Number):void
                {
                        _startX = startX;
                        _startY = startY;
                        _finishX = finishX - startX;
                        _finishY = finishY - startY;
                        _distance = 0;
                }
                public function move(time:Number):void
                {
                        _distance +=  time;
                        var ratio:Number = _distance  / DURATION;
                        if (ratio >= 1)//если мы тут то ядро достигла финиша и мы удаляемся
                        {
                                target.x = _finishX * 1 + _startX;
                                target.y = _finishY * 1 + _startY;
                                _prepareForPpool(this);
                        }
                        target.x = _finishX *ratio + _startX;
                        target.y = _finishY * ratio + _startY;
                }
 
        }
 
}


caseyryan 11.02.2014 21:27

Все это конечно не правильно. Создавать ядро каждый раз для выстрела.. это слишком ресурсозатратно. Но раз уже есть задача использовать одну и ту же картинку, то, сразу скажу, что у BitmapData есть метод clone()
Чтобы создать Bitmap, который будет копией другого, можно использовать его
Код AS3:

var bitmap:Bitmap = e.target.content as Bitmap; // допустим она загрузилась лодером
// создаем копию
var cloneBitmap:Bitmap = new Bitmap(bitmap.bitmapData.clone());


Akopalipsis 11.02.2014 21:33

Цитата:

BitmapData есть метод clone()
А клон это ссылка на bitmapData?

samana 11.02.2014 21:37

А зачем же клонировать битмарДату? Ведь это лишнее, одной будет вполне достаточно)

Akopalipsis 11.02.2014 21:40

Цитата:

А зачем же клонировать битмарДату? Ведь это лишнее, одной будет вполне достаточно)
Так надо или нет?)

samana 11.02.2014 22:06

А какой смысл создавать одинаковые данные? Клонировать не нужно, ведь старая битмапДата никуда не делась, а новая будет точно такая же как и старая. Просто достаточно создавать много битмап, и передавать им эту одну единственную битпамДату, как ещё намного выше сказал illuzor.

Akopalipsis 11.02.2014 22:13

samana Спасибо!


Часовой пояс GMT +4, время: 14:19.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.