Я не понимаю, как вы представляете эту систему инвентаризации: как она выглядит? как это работает?
С упрощенной точки зрения я понимаю, что у вас есть список элементов, которые будут загружены из внешнего источника (CSV-файл, проанализированный с помощью LoadVars, XML-файл и т. Д.), И вы хотите отобразить их.
Я бы разделил это на это:
- источник данных (txt, xml и т. Д.)
- провайдер данных - в итоге у вас будут предметы для инвентаря, каждый
товар будет иметь свойства (метка, изображение, цена и т. д.)
- метод рисования / рендеринга (элементы в горизонтальном / вертикальном списке, списке листов, сетке данных и т. Д.)
Для отображения предмета динамически,
Я рекомендую взглянуть на класс MovieClipLoader . Вы можете использовать метод loadMovie () MovieClip, но MovieClipLoader более гибок (вы можете узнать, загружается ли элемент (%), получить его размеры и т. Д.), В отличие от метода loadMovie ().
Независимо от вашего источника данных, вы получите массив объектов инвентаризации, который будет иметь свойства, которые я предполагаю.
Вот основной подход к отображению предметов инвентаря:
//using dummy data, you would populate the array by parsing loaded vars or xml, whatever works best for you
var dataProvider:Array = [];
var dummyItems:Number = 20;
for(var i:Number = 0 ; i < dummyItems ; i++) dataProvider[i] = {label:'item '+i,source:'http://stackexchange.com/images/icon/stackoverflow.com'};
//make a container
var inventory:MovieClip = this.createEmptyMovieClip('inventory',1);
var inventoryMask:MovieClip = this.createEmptyMovieClip('inventoryMask',2);
inventoryMask.beginFill(0);inventoryMask.lineTo(Stage.width,0);inventoryMask.lineTo(Stage.width,50);inventoryMask.lineTo(0,50);inventoryMask.lineTo(0,0);inventoryMask.endFill();
inventory.setMask(inventoryMask);
//add items to it
for(i = 0 ; i < dummyItems ; i++) makeInventoryRenderItem(dataProvider[i],inventory,i);
//scroll on mouse over
inventory.onRollOver = function():Void{
inventory.onEnterFrame = function(){
inventory._x = -_xmouse;//this is just a stub, replace with any navigation method you wish
}
}
inventory.onRollOut = function():Void{
delete inventory.onEnterFrame;
}
//make a movie clip with a loader and a label
function makeInventoryRenderItem(data:Object,container:MovieClip,index:Number):Void {
var renderItem:MovieClip = container.createEmptyMovieClip(data.label,index);
var loader:MovieClipLoader = new MovieClipLoader();
loader.loadClip(data.source,renderItem);
var handler:Object = new Object();
handler.onLoadInit = function(target:MovieClip):Void{
target._x = (target._width + 2) * index;
var label:TextField = renderItem.createTextField(data.label+'Label',renderItem.getNextHighestDepth(),0,0,40,22);
label.text = data.label;
}
loader.addListener(handler);
}
и вот предварительный просмотр:
Обратите внимание, что это не быстрый / эффективный способ написания, а простой способ проиллюстрировать идею.
Другой подход:
В качестве другого варианта, если размер файла не является проблемой, вы можете использовать компоненты (вы можете получить около 70 КБ bload только от них). Преимущество состоит в том, что уже есть способы обработки данных, не затрагивая слишком много кода, и вы можете использовать хакерский способ отображения своих элементов или создавать собственные средства визуализации ячеек.
Вот базовый подход с использованием List и XMLConnector:
Добавить компонент списка на сцену,
назовите его ls
Добавьте XMLConnector (из компонентов данных) и назовите его xml
- Создайте XML-файл с выбранной структурой.
Я использовал такую структуру:
<data>
<item label="item 1" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 2" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 3" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 4" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 5" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 6" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 7" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 8" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 9" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 10" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 11" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 12" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 13" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 14" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 15" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 16" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 17" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 18" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 19" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
<item label="item 20" source="http://stackexchange.com/images/icon/stackoverflow.com"/>
</data>
На вкладке Параметры Инспектора компонентов необходимо установить URL для вашего xml,
и направление для получения.
Следующим шагом является импорт схемы xml в коннектор XML, чтобы он мог «понять» структуру вашего файла xml. Это можно сделать, нажав кнопку import schema на вкладке Схема Инспектора компонентов. Это крошечная кнопка в правом верхнем углу вкладки с маленькой синей стрелкой, указывающей вниз. Кроме того, убедитесь, что выбраны ваши результаты .
Вы увидите обновление результатов, и из вашего xml будет создан массив, вы также можете увидеть свойства каждого объекта.
Теперь, когда схема / структура xml импортирована, мы можем создать привязку. Мы делаем это, нажимая значок + на вкладке «Привязки» Инспектора компонентов:
Появится диалоговое окно Add Binding, где вы выбираете элемент Array и нажимаете OK.
В моем случае это называется item, в зависимости от xml это может называться как-то иначе, но идея в том, что вы выбираете элемент, содержащий повторяющиеся ([n]) элементы.
Следующий шаг - привязать входящие данные к чему-либо, в данном случае к нашему компоненту списка. Установите направление на out, затем дважды щелкните на значении:
Появится диалоговое окно Bound To . Здесь мы выберем список и его провайдера данных в качестве получателей.
Это все, что нужно сделать Инспектору компонентов. Теперь у вас есть что-то, что загружает и обрабатывает ваш xml и отправляет данные в список, когда он будет готов.
Теперь мы просто создаем пустой мувиклип с именем Icon , рисуем границу 50x50, потому что она будет содержать значок stackoverflow (48x48) внутри, а мы Export for Actionscript (Linkage)
Эти последние шаги включают в себя 7 строк ActionScript.
На основной временной шкале мы запускаем коннектор xml, устанавливаем свойство стиля defaultIcon, устанавливаем высоту строки, чтобы изображение / логотип инвентаря подходило, и отключали опрокидывание, чтобы избежать перерисовки этого события:
xml.trigger();//trigger the xml loading
ls.setStyle('defaultIcon','Icon');//use your library clip as an icon
ls.setStyle('useRollOver',false);//stop redrawing list item on rollOver
ls.rowHeight = 48;//you should know the size of the inventory item
Теперь последние 3 строки кода довольно хакерские, потому что мы используем иконку списка (которая обычно повторяет один и тот же элемент библиотеки), чтобы найти индекс элемента из самого клипа иконки, и таким образом, получая доступ к списку, поставщику данных и, следовательно, данным для каждого клипа значка.
Мы помещаем этот код в значок мувиклипа:
var index:Number = parseInt(_parent._name.substr(7))-10;//hack #1 use the rendered icon clip's name property to get it's index
var image:MovieClip = createEmptyMovieClip('image',1);
image.loadMovie(_parent._parent._parent.dataProvider.getItemAt(index).source);//hack #2 'clip' up from the icon clip to the list to find the list and source property for current item
И все, вы получаете список, который отображает ярлыки и изображения из xml-файла:
Это вариант, если вы хотите использовать компоненты и просто хотите получить хакерский способ с меньшим количеством кода. Если вы по-прежнему хотите использовать компоненты, но делаете это правильно, вам необходимо создать собственный модуль визуализации ячеек, который будет отображать данные для каждого элемента инвентаря. Для этого на сайте flash-db есть очень хорошее руководство.
НТН
UPDATE:
Я только что прочитал остальные комментарии.
@gmale прав, attachMovie - это то, что вам нужно, если вы планируете использовать элементы из библиотеки.
вы используете это так:
theContainerForYourItem.attachMovie('itemLinkageName','someOptionalName',depth);//note depth is a number
вот простой тест, вы должны изменить itemSize и либо строки связывания (либо у вас есть клипы в библиотеке с теми же именами, что и в коде, либо вы обновляете имена в коде):
var selectedItem:MovieClip;//this will keep track of the selected item
var itemSize:Number = 67;//set this to the size of a inventory item
var inventoryIds:Array = ["New","Folder","Disk","Mail","Graph"];//item linkage ids, make sure you've got some movie clips in library with these ids, or update the array
var inventory:MovieClip = this.createEmptyMovieClip("inventory",0);//container
var level:MovieClip = this.createEmptyMovieClip("level",1);
//create items
for(var i:Number = 0 ; i < inventoryIds.length ; i++){
//create container for item
var itemContainer:MovieClip = inventory.createEmptyMovieClip('item'+i,i);
//draw border, invisible bg
itemContainer.lineStyle(1);itemContainer.beginFill(0,0),itemContainer.lineTo(itemSize,0);itemContainer.lineTo(itemSize,itemSize);itemContainer.lineTo(0,itemSize);itemContainer.lineTo(0,0);itemContainer.endFill();
//position, add library item
itemContainer._x = (itemSize+2) * i;//2 is just spacing
itemContainer.attachMovie(inventoryIds[i],'icon',0);
itemContainer.onPress = itemSelected;//selec item
}
function itemSelected():Void{
//if there was previously an item removed, restore it...depends on your game's logic, u need clicks though
if(lastItem != undefined) restoreItemToInventory();
trace('selected item is: ' + inventoryIds[this.getDepth()]);//trace ths selected item
this.getInstanceAtDepth(0).removeMovieClip();//and remove the icon from the invotory
delete this.onPress;//disable clicks
lastItem = this;//update the last Item for restoring
//draw an item inside the level
var levelItem:MovieClip = level.attachMovie(inventoryIds[this.getDepth()],'icon',0);
levelItem._x = Stage.width * .5;level._y = Stage.height * .5;//position item;
levelItem.onPress = itemUsed;
}
function restoreItemToInventory():Void{
lastItem.attachMovie(inventoryIds[lastItem.getDepth()],'icon',0);//attach the icon again
lastItem.onPress = itemSelected;//make restore click
}
function itemUsed():Void{
this.removeMovieClip();//remove from stage
trace('item is: ' + inventoryIds[lastItem.getDepth()] + ' was used');//do whatever to hero/enemies
restoreItemToInventory();//restore to inventory or not
}
Примечание , что для каждого элемента библиотеки я использую контейнер. Причина этого в том, что когда я удаляю элемент, фактически я просто удаляю элемент библиотеки, который содержит контейнер, и контейнер все еще там, и поддерживает его глубины, которые совпадают с индексом элемента в массиве. , Это используется позже, чтобы удалить / прикрепить предметы инвентаря. В общем, это плохая практика, поскольку есть тесно связанные элементы, но ради простой демонстрации это подойдет.
Если в вашей игре будут добавлены новые предметы (игрок не будет иметь все возможные предметы сразу) и удалены, использованы ... возможно, также стоит научиться использовать класс Array, особенно splice () метод, который позволит вам добавлять, удалять элементы из массива по заданному индексу. на основе обновленного массива инвентаря вы будете отображать предметы и настраивать интерактивность.