PDA

Просмотр полной версии : Можно ли переместить клип от одного родителя к другому?


Alex626
20.12.2011, 20:38
У меня возникла необходимость в определённый момент вырвать клип-наследник из клипа-родителя на более высокий уровень. Не знаю, можно ли так сделать через скрипт, но в редакторе Flash эта операия была бы эквивалентна действию "Break Apart".

Просто мне нужно сделать скролл на контейнер с объектами. Каждый объект из клипа-контейнера скролла можно перемещать в определённую зону, после чего он там и должен остаться. Но вот как сделать, чтобы после перемещения, он больше не принадлёжал бы клипу-контейнеру, т.е. уходил бы в _root?

mooncar
20.12.2011, 21:18
Нет, так сделать нельзя.
Доставайте (приаттачивайте) мувики из библиотеки.

Alex626
20.12.2011, 21:32
То есть каждый раз работать с новым клипом?

Ну хорошо, а можно ли сделать подобие скрола, но который работал бы без клипа-контейнера, и все перемещаемые объекты были бы в _root. При этом объекты, которые следует прокручивать, были бы указаны в массиве.

mooncar
20.12.2011, 21:41
Можно написать собственный скроллинг.

PS. Вы, случайно, не что-то типа инвентаря делаете?

Alex626
20.12.2011, 22:01
Да, инвентарь и делаю.

mooncar
21.12.2011, 16:13
Возможно такое решение:

Итемы находятся в инвентаре как обычно и скроллируются.

При нажатии (onPress), итем в инвентаре делается невидимым (_visible = false), а в специальный мувике поверх сцены (предназначенном для итемов перемещения по сцене) приаттачивается из библиотеки тот же итем в тех же координатах, визуально подменяя итем инвентаря.

Для точности позиционирования, чтобы не было видно подмены, можно использовать методы localToGlobal (определяем текущее положение итема инвентаря относительно _root), lobalToLocal (переводим эти координаты в нужные координаты контейнера, где будут происходить перемещения итемов на сцене).

Для перемещения итема по сцене использовать onMouseMove.
Для укладки итема в инвентарь то же делать в обратной последовательности.

Alex626
21.12.2011, 16:47
Как-то слишком негуманно. Может лучше заставить определённые объекты не перемещаться вместе со скролом?

mooncar
21.12.2011, 16:59
Вполне гуманно и логично. Я бы так сделал.
К тому же часто видим в играх, что итем в инвентаре и итем на сцене выгляд по разному.
Не нужно привязываться к объекту, как к конкретному предмету.

Alex626
21.12.2011, 17:54
Удобнее всего, когда информация о предметах хранится в самих итемах. Я реализовал перетаскивание и масштабирование. А теперь придётся работать по другому принципу?

mooncar
21.12.2011, 18:02
Хранить инфу в самих итемах - это не дело.
Конечно, база данных для итемов должна быть независима от самих итемов на сцене. Так далеко не уедешь.
Используйте массив.ы

Alex626
21.12.2011, 18:05
Мне придётся использовать массивы 80*10. Многомерные. А в объектах можно хранить десятки свойств.

mooncar
21.12.2011, 18:33
80 x 10 - это всего лишь двумерный массив.
А в дву- и более -мерных массивах тоже можно хранить массу свойств. Я, кстати, так и делаю.
Нужно правильно организовать структуру.

PS. В AS, по сути, массив - это тоже объект, только без визуального представления.
Так зачем превращать объект, имеющий визуальное представление, в хранилище данных?
Если проект куцый, то так можно сделать. если что-то посложнее - извольте структуру продумать более оптимально.

Добавлено через 5 минут
var allitems:Array = new Array();

for (id = 0; id <= 80; id++)
{
allitems[id] = new Array();
}

allitems[0]['prop1'] = 'some property1';
allitems[0]['prop2'] = 'some property2';

allitems[1]['prop1'] = 'some property1';
allitems[1]['prop2'] = 'some property2';

//и т.д.

Alex626
21.12.2011, 18:40
Можете показать примрер добавления многомерных массивов. Предположим, у меня есть функция :

function addClip(id,name,description,mass,usable,show)
{
//....
}


В ней в массив ary должна добавиться эта запись.

mooncar
21.12.2011, 18:43
var ary:Array = new Array();

for (id = 0; id < 80; id++)
{
ary[id] = new Array();
}

function addClip(id, name, description, mass, usable, show)
{
ary[id]['name'] = name;
ary[id]['description'] = description;
ary[id]['mass'] = mass;
ary[id]['usable'] = usable;
ary[id]['show'] = show;
}

Обращение очень простое:
trace(ary[20]['name'])

Добавлено через 3 минуты
Если заранее неизвестно, сколько id, не создаем заренее структуру 2-го уровня, то вариант просто создавать вложенный массив второго уровня по ходу, на лету:

var ary:Array = new Array();

function addClip(id, name, description, mass, usable, show)
{
if (ary[id] == undefined) ary[id] = new Array();//если слот под данный итем еще не создавали
ary[id]['name'] = name;
ary[id]['description'] = description;
ary[id]['mass'] = mass;
ary[id]['usable'] = usable;
ary[id]['show'] = show;
}

Таким образом, имеем БД, никак не связанную с происходящим на сцене, пока явно не изменим в ней данные, вследствие каких-то событий.

Alex626
21.12.2011, 20:15
А если ID каждый раз разные, посылаются из игры? Как можно присваивать порядковые номера каждому новому айтему?

mooncar
21.12.2011, 20:17
А если ID каждый раз разные, посылаются из игры? Как можно присваивать порядковые номера каждому новому айтему?
Не очень понял вопрос. Возможно для этого - второй вариант, когда id заранее неизвестен:
var ary:Array = new Array();

function addClip(id, name, description, mass, usable, show)
{
if (ary[id] == undefined) ary[id] = new Array();//если слот под данный итем еще не создавали
ary[id]['name'] = name;
ary[id]['description'] = description;
ary[id]['mass'] = mass;
ary[id]['usable'] = usable;
ary[id]['show'] = show;
}

Или речь о том, что могут быть разные экземпляры одного и того же итема?

Alex626
21.12.2011, 20:35
Нет, ID это идентификатор сущности оружия, первый может быть 105, а второй - 5883. Т.е. сделать запись не по ID, а по порядковому номеру, запоминая номер последнего добавленного элемента, и наращивая его при добавлении.

mooncar
21.12.2011, 20:43
Вариант 1.

Тогда нужно иметь два основных массива - один - в котором описаны дефолтные и неизменяемые свойства - типа description, mass.
Второй - массив "активных" итемов, разных экземпляров разных итемов, у которых могут меняться нужные свойства, которые могут быть в игре разными. Как я понял по названию, это типа show?
Также у итема на сцене будет еще одно свойство, которое определяет, что это, собственно, за итем, то есть соответствие id из первого массива, сущность.

А при добавлении итема на сцену нужно производить определенные действия.

var items:Array = new Array(); //БД видов итемов

for (id = 0; id < 80; id++)
{
items[id] = new Array();
}

function addDefault(id, name, description, mass)
{
items[id]['name'] = name;
items[id]['description'] = description;
items[id]['mass'] = mass;
}

addDefault(105, 'Палка', 'Палка для тыкания', 10);
addDefault(106, 'Ножик', 'Ножик для резания', 30);
//.... и .т.д.

var itemsInPlay:Array = new Array(); //БД экземпляров итемов в игре
var id_inPlay:Number = 0;

function addClip(id_itemType, show, usable):Number //возвращает, если надо id итема в игре (id_inPlay)
{
id_inPlay++;

if (itemsInPlay[id_inPlay] == undefined) itemsInPlay[id_inPlay] = new Array();//если слот под данный итем еще не создавал

itemsInPlay[id_inPlay]['id_itemType'] = id_itemType;
itemsInPlay[id_inPlay]['usable'] = usable;
itemsInPlay[id_inPlay]['show'] = show;

return id_inPlay; //если надо
}

В какой-то момент времени добавляем в игру итем с id = 2 - Ножик, его id в игре будет = 1.
Его show и usable = false
addClip(105, false, false);
Вернет id = 1, то есть идентификатор итема в игре

В другой момент можно будет узнать другие свойства данного итема (т.е. типовые):
Сперва узнаем id (сущность в вашей терминологии)
var id:Number = itemsInPlay[1]['id_itemType'];
затем по id уже неизменные свойства
trace(items[id]['name']);
trace(items[id]['mass']);
trace(items[id]['description']);

На самом деле, это первое, что в голову пришло, могут быть другие реализации.

Вариант 2.

Можно иметь одну общую базу типовых итемов, и просто в неком свойстве типового итема указывать в виде некого свойства набор (вложенный массив) соответственных итемов на сцене, это еще одна или даже две вложенности, если с учетом индивидуальных свойств в игре.

Alex626
21.12.2011, 23:51
Я имел в виду просто запись по порядку. То есть у каждого айтема есть идентификатор в игре, и идентификатор порядкового номера элемента в инвентаре на Flash. Это ведь не самостоятельная игра на Flash, а просто файл интерфейса.

Например, есть предметы:


номер id name

1 34 MyWeapon1
2 766 Gun22
3 45675 Cannon1
4 22 Grenade45

итд.

При добавлении предмета в инвентарь функцией addClip, каждый объект получает свой порядковый номер, к которому можно обращаться. Например, есть массив ary, обращаемся к объекту номер 3, для свойства name:
trace(ary[3]['name'])
//Cannon1

mooncar
22.12.2011, 12:16
Я именно это и имел ввиду в последнем посте.
Фразу "А при добавлении итема на сцену" можно считать за "А при добавлении итема в инвентарь".
И весь принцип тот же самый.
id_inPlay++; - это например отражает "каждый объект получает свой порядковый номер, "
и т.д.

Alex626
22.12.2011, 15:09
А как удалять целую строку в массиве, уплотнять, и если нужно, полностью стирать все строки?

mooncar
22.12.2011, 16:01
var itemsInventory:Array = new Array(); //итемы в инвентаре
var id_inventory:Number;

function addClip(id_itemType, show, usable):Number //возвращает id итема в инвентаре

//для задания текущего
id_inventory == undefined ? id_inventory = 0 : id_inventory++;

//если слот под данный итем еще не создан
if (itemsInventory[id_inventory] == undefined) itemsInventory[id_inventory] = new Array();

itemsInventory[id_inventory]['id_itemType'] = id_itemType;
itemsInventory[id_inventory]['usable'] = usable;
itemsInventory[id_inventory]['show'] = show;

trace('Знесли в массив, его id ' + id_inventory);
return id_inventory;
}

//заполняем итемами
addClip(100, false, false);
addClip(101, false, false);
addClip(102, false, false);
addClip(103, false, false);

trace(itemsInventory + ' Длина массива: ' + itemsInventory.length);

//удаляем итем с id = 2
itemsInventory.splice(2, 1); //удаляем начиная с 2 индекса 1 элемент

trace(itemsInventory + ' Длина массива: ' + itemsInventory.length);

Alex626
22.12.2011, 16:30
Спасибо!