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

marsh 16.06.2011 11:09

Массив объектов и события.
 
Привет, AS я начал изучать буквально сегодня, более-менее разбираюсь, пытаюсь писать тестовые флешки для понимания языка.

Собственно написал код, который создаёт массив объектов myrow, где myrow - это квадратный movieclip, пытался повесить события на каждый объект так, чтобы при клике он выделялся красным вокруг (через GlowFilter).

Код AS3:

import flash.filters.GlowFilter;
import flash.events.Event;
 
var len:int = 100;
var mas:Array = new Array(len);
var gf1:GlowFilter = new GlowFilter(0xff0000, 0, 0, 0, 0, 0);
var gf2:GlowFilter = new GlowFilter(0xff0000, 2, 2, 2, 2, 2);
 
function generateWorld(len:int):void {
        var i:int;
        var j:int;
        for(i = 0; i < len; i++) {
                mas[i] = new Array(len);
                for (j = 0; j < len; j++) {
                        var row:myrow = new myrow();
                        row.x = i * row.width;
                        row.y = j * row.width;
                        mas[i][j] = row;
                        addChild(mas[i][j]);
                }
        }
}
 
function oncll (e:MouseEvent) {
        this.filters = [gf3];
}
 
 
generateWorld(len);
var i:int;
var j:int;
for (i = 0; i < len; i++) {
        for (j = 0; j < len; j++) {
                mas[i][j].addEventListener(MouseEvent.CLICK, oncll);
        }
}

первое, что пришло в голову, использование this, но в итоге при клике на один из объектов массива, выделяются все объекты массива, а не только тот, на который кликнули.

Подскажите пожалуйста, как правильно реализовать выделение только одного объекта массива, на который был совершен клик мышкой?

Пробовал прослушивать событие Event.ENTER_FRAME и внутри функции проверять положение мыши относительно каждого объекта массива циклом, но уже при массиве 50х50 ощущаются тормоза, счел это плохим кодом удалил, вот теперь пытаюсь сделать все цивильно, надеюсь поможете советом.

Заранее спасибо.

carrotoff 16.06.2011 12:28

Вместо this используйте e.target

Цитата:

счел это плохим кодом удалил, вот теперь пытаюсь сделать все цивильно, надеюсь поможете советом.
Не пишите код в кадрах - первый закон программирование в AS

gloomyBrain 16.06.2011 13:00

Цитата:

Вместо this используйте e.target
Лучше уж currentTarget - мало ли, что там вложено будет в мувике...

TWETTI 16.06.2011 13:03

Можно было написать проще:
Вместо последних строк написать так:
Код AS3:

...
mas[i][j] = row;
mas[i][j].addEventListener(MouseEvent.CLICK, oncll);
addChild(mas[i][j]);
...

Можно не регистрировать слушателя события для каждого мувиклипа. Создайте один мувиклип-контейнер и поместите в него все мувиклипы-квадраты. Затем зарегистрируйте слушателя события для контейнера.

Код AS3:

import flash.filters.GlowFilter;
import flash.events.Event;
import flash.display.MovieClip;
import flash.events.MouseEvent;
 
var len:int = 100;
var mas:Array = new Array(len);
var gf1:GlowFilter = new GlowFilter(0xff0000, 0, 0, 0, 0, 0);
var gf3:GlowFilter = new GlowFilter(0xff0000, 2, 2, 2, 2, 2);
var container:MovieClip = new MovieClip();
addChild(container);
function generateWorld(len:int):void {
        ...
}
 
container.addEventListener(MouseEvent.CLICK, oncll);
function oncll (e:MouseEvent) {
        e.target.filters = [gf3];
}
 
generateWorld(len);

P.S. Объявляйте переменную-счетчик (т.е. i или j) сразу в операторе for. Так код будет компактнее.

marsh 16.06.2011 13:12

Спасибо.
А что значит "не пишите код в кадре", где его писать тогда и смогу ли я создавать объекты типов из библиотеки сцены?

marsh 16.06.2011 13:23

И еще, попробовал и e.target и e.currentTarget, ошибка одна:
TypeError: Error #1010: Термин не определен и не имеет свойств.
at Untitled_fla::MainTimeline/oncll()

(ошибка происходит при попытке клика на объекте).

TWETTI 16.06.2011 14:23

Цитата:

Сообщение от marsh (Сообщение 1004089)
Спасибо.
А что значит "не пишите код в кадре", где его писать тогда и смогу ли я создавать объекты типов из библиотеки сцены?

Код нужно писать в классах.

Цитата:

Сообщение от marsh (Сообщение 1004089)
...смогу ли я создавать объекты типов из библиотеки сцены?

Сможете.


Цитата:

Сообщение от marsh (Сообщение 1004093)
И еще, попробовал и e.target и e.currentTarget, ошибка одна:
TypeError: Error #1010: Термин не определен и не имеет свойств.
at Untitled_fla::MainTimeline/oncll()

(ошибка происходит при попытке клика на объекте).

Попробуйте так:
Код AS3:

(e.target as MovieClip).filters = [gf3];


bav 16.06.2011 14:27

Код AS3:

package 
{
    import flash.display.DisplayObject;
    import flash.filters.GlowFilter;
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.MouseEvent;
 
    /*
    * Сохраните этот файл как TestProject.as, положите рядом с флешкой
    * и пропишите TestProject как Document Class вашей флешки.
    * В библиотеке у клипа myrow должна быть поставлена галочка
    * Export for ActionScript и имя класса должно быть соответственно
    * myrow.
    */

    public class TestProject extends MovieClip
    {
        private const GF_2:GlowFilter = new GlowFilter(0xff0000, 2, 2, 2, 2, 2);
 
        private var len:int = 100;
        private var mas:Array = [];
 
        public function TestProject() {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
 
        private function init(event:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
 
            for(var i:int = 0; i < len; i++) {
                mas[i] = []; // new Array(len);
                for (var j:int = 0; j < len; j++) {
                    var row:myrow = new myrow();
                    row.x = i * row.width;
                    row.y = j * row.width;
                    mas[i][j] = row;
                    addChild(row); // addChild(mas[i][j]);
                    // Вешаем прослушку кликов на объект myrow.
                    row.addEventListener(MouseEvent.CLICK, oncll);
                }
            }
        }
 
        private function oncll (event:MouseEvent) {
            // Берем ссылку на объект инициировавший событие
            var myrow:DisplayObject = event.target as DisplayObject;
            // Берем его массив фильтров
            var fil:Array = myrow.filters;
            // Добавляем в него свой фильтр
            fil.push(GF_2);
            myrow.filters = fil;
            // Чтобы убрать фильтры делаем так:
            // myrow.filters = [];
        }
    }
}


marsh 16.06.2011 15:28

спасибо большое всем, разобрался :)

dimarik 16.06.2011 21:42

Цитата:

Сообщение от TWETTI (Сообщение 1004103)
Попробуйте так:
Код AS3:

(e.target as MovieClip).filters = [gf3];


Лучше так
Код AS3:

(e.target as DisplayObject).filters


bav 16.06.2011 23:39

dimarik, чем лучше, в данном случае, приводить к DisplayObject, а не к MovieClip?

Dukobpa3 17.06.2011 00:34

потому что таргетом может оказаться к примеру битмапа какая-то ;) Это не карентТаргет, а таргет, а тут уж во что тыкнули то и получили.

dimarik 17.06.2011 09:28

Думаю, что лучше воспользоваться приведением к суперклассу, в котором объявлен тот метод или свойство.
Если же вы решите пользоваться методами подкласса, чтобы не разводить лишние приведения, конечно, лучше привести с ожидаемому классу с обязательной проверкой на is. В данном случае target всегда будет DisplayObject и проверка не нужна.


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

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