Форум 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=188410)

XMON 02.12.2012 20:40

как можно проверять столкновение объекта одного класса с объектом другого класса?
 
как можно проверять столкновение объекта одного класса с объектом другого класса?

Korchy 02.12.2012 20:57

Столкновение классов вы проверять не можете. Вы можете проверять столкновение геометрических форм, описываемых классами. По поводу столкновения геометрии: все зависит от того, что с чем сталкиваете, в статике или в движении. В общем случае погуглите "collision detection"

Tails 02.12.2012 21:23

hitTestObject

XMON 03.12.2012 08:55

а как тогда в классе проверять столкновение с разными объектами у которых нет имени. например: этим объектам присвоить какойнибуть 1 тип и смотреть, когда другой объект с другим типом столкнется сними.

про hitTestObject я знаю, я не знаю как реализовать т.к. с классами я знаком недавно.

kackbip 03.12.2012 09:56

Предположим ваши геометрические фигуры сохранены в массиве. Пробегаетесь по массиву и делаете им хтиТестОбжект с какой-нибудь другой фигурой.

XMON 03.12.2012 11:11

я бы давно так сделал, проблема в том что неизвестно сколько точно будет проверятся предметов на столкновение. их может быть 10 или 12. если делать так, то будут вылазить ошибки.

Hauts 03.12.2012 11:24

Цитата:

если делать так, то будут вылазить ошибки.
— ошибки будут "вылазить" если делать неправильно.

Проверяйте в цикле. Берете первую форму и проверяете со всеми остальными. Берете вторую и делаете то же самое.

Нет универсального встроенного волшебного метода для проверки столкновений чего-хотите, сколько-хотите и как-хотите. Все руками делается. И головой.

Tetraeon 03.12.2012 12:32

Если есть массив с объектами и вы незнаете находятся ли эти объекты в данный момент в контейнере с объектами можно заранее проверить их наличие:
Код AS3:

for(var i:int=0; i<objArray.length; i++)
{
    if((container.objArray[i])&&(objArray[i].hitTestObject(obj)))
    {
      trace('hit');
    }
}


XMON 03.12.2012 12:47

как можно заполнить массив (созданный в классе) с главной линии времени, а потом управлять элементами массива из класса?

Добавлено через 50 минут
помогите пожалуйста

kackbip 03.12.2012 16:21

Никак.
Делайте так:
1) У вас есть игровое поле. Оно владеет всеми фигурами.
2) Поле создает фигуры и сохраняет ссылки на них в массиве.
3) Поле же инициирует проверки на столкновение. Скажем, после каждого передвижения объектов.

XMON 04.12.2012 16:06

вот я создаю массив и управляю им:
Код AS3:

package {
        import flash.display.MovieClip;
        public class MyFirstClass extends MovieClip
        {
                public var ar:Array = new Array
                public function MyFirstClass ()
                {
          ar[0].x += 1000
 
                }
        }
}

вот я его заполняю:
Код AS3:

var myClass:MyFirstClass=new MyFirstClass();
myClass.ar.push(mc)

но выдает ошибку -
Код:

TypeError: Error #1010: Термин не определен и не имеет свойств.
at MyFirstClass()
at my_first_class_fla::MainTimeline/frame1()


kackbip 04.12.2012 16:29

1) Не создавайте публичный полей никогда. Массив должен быть приватным.
2) Сделайте публичный метод в MyFirstClass, скажем такой:
addFigure(figure: DisplayObject)
В этом методе добавляейте переданные объекты в массив.
3) В конструкторе MyFirstClass вы манипулируете элементом массива ar[0], но при этом массив у вас еще пустой. Чем в итоге вы манипулируете?
4) Задайте классу имя, которое характеризует его область ответственности.

XMON 04.12.2012 18:28

у меня возникла новая проблема...
вот код:
Код AS3:

package  {
  import flash.display.MovieClip;
 
  public class fuf extends MovieClip {
 
      public function fuf() {
        var hold:MyFirstClass = new MyFirstClass
        if(this.hitTestObject(hold))
        {
            trace ("столкнулся")
        }
      }
 
  }
 
}

а класс MyFirstClass расширяет MovieClip и пустой

здесь я проверяю столкновение двух классов. но не работает. почему и как исправить?

kackbip 04.12.2012 19:20

MyFirstClass у вас пустой. Соответственно объектов, которые могут столкнуться нет? Не совсем понял что не получается.

1) Заполняем поле(MyFirstClass. Переименуйте его уже) объектами.
2) Каким-то образом двигаем объекты.
3) Вызываем в MyFirstClass проверку на столкновение для каждого объекта.

Давайте по порядку. Сначала заполните поле объектами которые могут столкнуться. И покажите код.

XMON 04.12.2012 19:23

я создаю объекты не кодом и в "редакторе", а потом присваиваю классу эти обьекты.

kackbip 04.12.2012 19:28

1) Покажите как присваиваете
2) Покажите код присваивания в MyFirstClass

Мы так долго будем. Но писать за вас не хочу :)

XMON 04.12.2012 19:59

Цитата:

Мы так долго будем. Но писать за вас не хочу
я понимаю, но я наверно не не знаю и 50% языка action script, а за классы я взялся совсем недавно, поэтому я немножко пишу код как "вне классов".
я думал что если присвоить объекту класс то этот объект и объекты внутри автоматически становятся этим классом и можно просто проверять столкновение совершенно всех объектов в классе.
я не совсем понимаю как присваивать. вот мои попытки:
Код AS3:

package {
        import flash.display.MovieClip;
        public class MyFirstClass extends MovieClip
        {
                public var ar:Array = new Array
                public function MyFirstClass ()
                {
                        ar.push(aaa)
                        trace (ar)
                }
        }
}

Код AS3:

package {
        import flash.display.MovieClip;
        public class fuf extends MovieClip
        {
                public var ar:Array = new Array
                public function fuf ()
                {
                        var dod:MyFirstClass = new MyFirstClass
                        ar.push(aaa)
                        trace (ar)
                        if (this.ar[0].hitTestObject(dod.ar[0]))
                        {
                                trace ("столкнулись")
                        }
                }
        }
}

Код AS3:

var fgf:fuf = new fuf
fgf.ar.push (aaa)

Код AS3:

var myClass:MyFirstClass=new MyFirstClass();
myClass.ar.push(aaa);

но выдаёт как всегда ошибку-
Код:

TypeError: Error #2007: Параметр hitTestObject не должен быть равен нулю.
        at flash.display::DisplayObject/_hitTest()
        at flash.display::DisplayObject/hitTestObject()
        at fuf()
        at Символ11()
        at flash.display::Sprite/constructChildren()
        at flash.display::Sprite()
        at flash.display::MovieClip()


kackbip 04.12.2012 21:35

Код AS3:

package {
        import flash.display.MovieClip;
        public class Container extends MovieClip
        {
                private var figures:Array = new Array();
                public function Container(){
                        var figure:Figure;
                        for(var i:int=0;i<10;i++){
                                figure = new Figure();//создаем библиотечный символ, которому пролинковали класс Figure
                                figure.x = i*10;
                                figure.y = i*10;
                                addChild(figure);//добавляем в дисплей лист фигуру
                                figures.push(figure);//запоминаем фигуры в массиве
                        }
                }
        }
}

Figure это класс прописанный библиотечному символу.
Container в своем конструкторе создает 10 фигур, добавляет их в список отображения, добавляет их в массив.

XMON 05.12.2012 14:56

что это за строчка?

Код AS3:

Figure figure;

что она делает ?

класс Figure, его я так понял можно оставить пустым ?

kackbip 05.12.2012 16:04

Это объявление переменной. Ей пользуюсь в цикле для хранения ссылки на объекты Figure - объект, на который ссылается переменная, меняется с каждым циклом.
Вы ведь работаете во Flash CS? Если так то класс Figure можно не создавать. Просто прописать Figure в linkage библиотечного символа, а IDE сама создаст пустой класс.

Wolsh 05.12.2012 16:30

Цитата:

Это объявление переменной.
Ага. В С++ например. У нас же форум о несколько другом языке.
Код AS3:

var figure:Figure;


kackbip 05.12.2012 16:39

Действительно. Автоматизм дело наказуемое. Еще в объявлении счетчика так же накосячил. Поправил код.

XMON 05.12.2012 16:49

Вложений: 1
ничего не появляется на экране...
что я не так делаю?

kackbip 05.12.2012 16:54

У меня на работе нету flash. У вас Container на сцене стоит? Если нет - сделайте в качестве document class - Container.

XMON 05.12.2012 17:02

всё получилось, спасибо. я вот так вызывал:
Код AS3:

var hold:Container = new Container

большое спасибо вам за всё.
буду ставить вам плюсики в репутацию столько, сколько ваших сообщений в этой теме)

Добавлено через 32 секунды
щас поэкспериментирую над столкновениями

а как можно добавить в массив символ, который находится на сцене?

kackbip 05.12.2012 17:59

Цитата:

Сообщение от XMON (Сообщение 1107997)
всё получилось, спасибо. я вот так вызывал:
Код AS3:

var hold:Container = new Container


Наверное вы забыли добавить контейнер в список отображения. Так же как фигуры добавляются в список отображения контейнера. addChild
Цитата:

а как можно добавить в массив символ, который находится на сцене?
Символы в библиотеке, а на сцене это уже DisplayObject-ы.
Любому объекту, который вы в IDE выставляете на сцену, можно в IDE же назначить name.
Далее мы можем обратиться к объекту который непосредственно содержит в себе именованный объект:

getChildByName("имяОбъекта");

XMON 05.12.2012 18:34

пытался добавить так:

Код AS3:

package {
        import flash.display.Sprite;
        import flash.display.DisplayObject;
        public class Container extends MovieClip
        {
                private var figures:Array = new Array();
                private var container:Sprite = new Sprite();
                private var target:DisplayObject = container.getChildByName("sprite1");
                private var sprite1:Sprite = new Sprite();
                public function Container()
                {
                        container.addChild(sprite1);
                        trace(container.getChildIndex(target)); // 0
                        figures.push(container)
                }
        }
}

но вот что пишет в вывод:

Код:

TypeError: Error #2007: Параметр child не должен быть равен нулю.
        at flash.display::DisplayObjectContainer/getChildIndex()
        at Container()
        at _3Dgalery_fla::MainTimeline/frame1()


kackbip 05.12.2012 18:45

trace прямо выводит 0? По-хорошему именно там должно падение случиться.

Код AS3:

private var target:DisplayObject = container.getChildByName("sprite1");

Вы пытаетесь взять дочерний объек у спрайта, который был создан строчкой выше т.е. у пустого спрайта. Соответственно в target у вас сохраняется null.

Далее вы передаете null в getChildIndex:
Код AS3:

trace(container.getChildIndex(target));

Этого приложение перенести не может и падает.

Подумайте еще. Сейчас не успею написать развернутый ответ.

XMON 06.12.2012 11:30

вот код:
Код AS3:

package {
        import flash.display.MovieClip;
        import flash.display.Sprite;
    import flash.display.DisplayObject;
        public class Container extends MovieClip
        {
                private var figures:Array = new Array()
                private var container:MovieClip = new MovieClip;
                private var target:DisplayObject = container; 
                public function Container(){
                        var figure:Figure;
                        for(var i:int=0;i<10;i++){
                                figure = new Figure();
                                figure.x = i*20;
                                figure.y = i*20;
                                figure.rotation += 45
                                addChild(figure);
                                figures.push(figure);
                                figures[i].x += 100
 
                        }
                        figures.push(target)
                        container = ObjecT
                        trace (figures)
                }
        }
}

добавил дисплей обджект в массив, проверил трейсом, он есть в массиве но не передвигается строчкой figures[i].x += 100

kackbip 06.12.2012 13:03

Для каждого объекта строчка
Код AS3:

figures[i].x += 100

вызывается единожды.
Когда объект должен передвигаться.

XMON 06.12.2012 13:15

знаю, но почему объект не передвигается ?

kackbip 06.12.2012 13:21

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

XMON 06.12.2012 13:41

нет, не плавное. просто задать объекту координату например x=100 и всё. но объект не отрисовывается в новых координатах.

kackbip 06.12.2012 13:44

Прикрепите swf-ку к сообщению.

XMON 06.12.2012 13:51

зачем ? на сцене ничего не происходит. это тоже самое что белый лист кинуть.

Добавлено через 2 минуты
не могли бы вы показать код который проверяет столкновение дисплей обжектов?

kackbip 06.12.2012 14:16

Видимо я должен был догадаться, что ничего не отображается по словам "но объект не отрисовывается в новых координатах"? Значит он и в старых не отрисовывается? А что вы хотите сталкивать, если у вас еще ничего не отображается? Надо же сначала добиться отображения объектов на сцене. Будем дальше пытаться?

Вот ссылочку нашел
http://www.ilike2flash.com/2009/06/s...nscript-3.html

XMON 06.12.2012 14:20

это я умею. мне нужно точно такое же, только в классе чтобы проверять столкновение многих объектов.

Добавлено через 8 минут
возможно вы знаете (или не знаете) браузерную флэш игру - "starquake" (http://www.starquake.ru/). там чтоб поставить модули на корабль нужно зажать мышку на нужном модуле, перетащить на свободную клетку в корабле, отпустить мышку и модуль ставится в ту самую клетку, в которую его перетащили. вот именно это мне надо.

Добавлено через 35 минут
итак, вот план:
выберем предмет из списка
зажимаем его
перетаскиваем на нужную клетку
отпускаем мышку
предмет из списка всаёт на эту клетку
(например все клетки загнать в массив и проверять столкновение с этим массивом)
все обьекты - дисплей обжекты.

Добавлено через 36 минут
блин, я всё тока что осознал. пойду писать код

kackbip 06.12.2012 16:57

Результаты выкладывайте - мне интересно какое у вас понимание получилось.

XMON 06.12.2012 18:34

вот код, которым я перемещаю обьект из массива:
Код AS3:

var GUNS:Array = new Array
GUNS.push (weapons.gun.guni)
for(var f:int=0;f<GUNS.length;f++)
{
        GUNS[f].addEventListener(MouseEvent.MOUSE_DOWN, mDown);
    GUNS[f].addEventListener(MouseEvent.MOUSE_UP, mUp);
 
        function mDown(e:MouseEvent):void
        {
                GUNS[f].startDrag(false);
        }
        function mUp(e:MouseEvent):void
        {
                GUNS[f].stopDrag();
        }
}

но возникаю ошибки. я знаю что можно зделать примерно так:
Код AS3:

switch нажал кудато
какойто код
break
 
switch нажал кудато
какойто код
break
 
и т.д.

но есть ли способ более лучше?

iNils 06.12.2012 19:04

Цитата:

Код AS3:

var GUNS:Array = new Array
GUNS.push (weapons.gun.guni)
for(var f:int=0;f<GUNS.length;f++)
{
        GUNS[f].addEventListener(MouseEvent.MOUSE_DOWN, mDown);
    GUNS[f].addEventListener(MouseEvent.MOUSE_UP, mUp);
 
        function mDown(e:MouseEvent):void
        {
                GUNS[f].startDrag(false);
        }
        function mUp(e:MouseEvent):void
        {
                GUNS[f].stopDrag();
        }
}


Мама дорогая...
1. GUNS - так называют только константы. Переменная должна называться guns
2. Зачем вы засунули определение функций в цикл? С какой целью? Думаете они будут каждый раз создаваться? Нет, функция определяется один раз. Лучше всего в самом верху кода.
3. Внутри функций не надо писать GUNS[f], это все равно работать не будет. Знаете почему? Потому что когда сработает функция, от любого объекта, то переменная f будет равна своему последнему значению в цикле, то есть GUNS.length - 1.
4. Внутри функции нужно использовать e.target. И да, называть аргумент e - плохая практика. Нужно давать осмысленное название - event

Что имеем на выходе?
Код AS3:

function mDown (event:MouseEvent):void {
        event.target.startDrag (false);
}
function mUp (event:MouseEvent):void {
        event.target.stopDrag ();
}
var guns:Array = new Array
guns.push (weapons.gun.guni);
for (var i:int = 0; i < guns.length; i++) {
        guns[i].addEventListener(MouseEvent.MOUSE_DOWN, mDown);
    guns[i].addEventListener(MouseEvent.MOUSE_UP, mUp);
}



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

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