Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Статьи (http://www.flasher.ru/forum/forumdisplay.php?f=101)
-   -   Знакомство с Flash 9 и ActionScript 3.0 на примере создания аркадной игры (http://www.flasher.ru/forum/showthread.php?t=83431)

N1ka 18.06.2008 16:51

Здравствуйте.
До сих пор пока справлялся со всякими непонятками в CS3 вместе со Strict mode, статья хорошая, конечно мне нюбу еще многое непонятно, но на то и создаются такие статьи, что вскорее надеюсь нюбом называтся не буду.

Так вот, застрял я на 3й странице ХТМЛ, где идет речь о столкновениях. Делал как написано, но тут:
Код:

TypeError: Error #1010: A term is undefined and has no properties.
        at main::sky/Update()

Долго игрался, не мог понять в чем проблема, эксперементировал и по частях новый код добавлял чтоб увидеть на каком этапе ошибка. Оказалось что на
Код:

delete all_sectors[s][obj.name];
Сравнивал с оригиналом, все будто нормально. Пробовал через дебаг, и мне деюаг тоже указал 62 строку. Вот весь код в моем sky:
Код:

package main {
        import flash.display.MovieClip;
        import flash.events.*;
        import main.*;
        dynamic public class sky extends MovieClip {
                var MIN_DROP:Number, MAX_DROP:Number;        // пределы количества вбрасываемых астероидов
                var all_moving:Array; // здесь все движущиеся объекты
                // Объявляем переменную для хранения секторов
                var all_sectors:Object;        // сектора со ссылками на объекты в них
                public function sky() {
                        all_moving = new Array();
                        // в конструкторе инициализируем
                        all_sectors = new Object();
                        // сколько астероидов вбрасывается
                        // это не константы, т.к. со временем количество астероидов должно увеличиваться
                        MIN_DROP=5; MAX_DROP=10;
                        addEventListener(Event.ENTER_FRAME, Update);
                        // тестовый вброс
                        DropSeveralAsteroids();
                }
                public function DropSeveralAsteroids():void {
                        var x1:Number, y1:Number; // точка вброса
                        var x2:Number, y2:Number; // куда двигаться
                        var cnt:Number;        // количество вбрасываемых встероидов
                        var new_asteroid:moving_object;        // объект астероида
                        var s:String;
                        x1=0; y1=0; // пока так, для теста, из левого верхнего угла
                        x2=this.earth.x; y2=this.earth.y; // двигаться к земле
                        // выбираем рандомное количество
                        cnt = MIN_DROP + Math.floor((MAX_DROP-MIN_DROP)*Math.random());
                        while (cnt--){
                                new_asteroid = new moving_object();        // создаем новый астероид
                                addChild(new_asteroid);                // добавляем его на наш мувиклип
                                all_moving.push(new_asteroid);        // запоминаем в массиве
                                new_asteroid.drop(x1,y1,x2,y2);        // бросаем
                                // В функции вброса новых астероидов
                                // Просим пересчитать в какие сектора попал объект
                                new_asteroid.CalcSectors();
                                // добавим в эти сектора ссылку на объект
                                for each (s in new_asteroid.sectors){
                                        if (!all_sectors[s]){ // такого сектора еще не было, создадим
                                                all_sectors[s] = new Object();
                                        }
                                        all_sectors[s][new_asteroid.name] = new_asteroid;
                                }
                        }
                }
                public function Update(e : Event):void {
                        var s:String, obj2:basic_object;
                        // Проходим по всему массиву созданных объектов
                        // и заставляем каждого сдвинуться в своем направлении
                        for each (var obj:basic_object in all_moving){
                                // перед тем, как сдвинуться удалим запись об этом объекте из секторов
                                for (s in obj.sectors){
                                        delete all_sectors[s][obj.name];
                                }
                                // смещаемся
                                obj.move();
                                // Просим пересчитать в какие сектора попал объект
                                obj.CalcSectors();
                                // Проверяем столкновения со всеми объектами, которые есть в новых секторах
                                for (s in obj.sectors){
                                        if (all_sectors[s]){  // такой сектор есть
                                                for each (obj2 in all_sectors[s]) { // проверяем на столкновение
                                                        if (obj.CheckCollision(obj2)){ // столкнулись
                                                                // делаем отскок
                                                                resolve(obj, obj2);
                                                        }
                                                }
                                        } else { // нет такого сектора
                                                all_sectors[s] = new Object(); // теперь будет
                                        }
                                        // регистрируемся в этом секторе
                                        all_sectors[s][obj.name]=obj;
                                }
                        }
                }
                function resolve(ball1:basic_object, ball2:basic_object):void {
                        var b1Velocity:Vector = ball1.Velocity;
                        var b2Velocity:Vector = ball2.Velocity;
                        var b1Mass:Number = ball1.getMassa();
                        var b2Mass:Number = ball2.getMassa();
                        var lineOfSight:Vector = new Vector(ball1.x-ball2.x, ball1.y-ball2.y);
                        var v1Prime:Vector = b1Velocity.vectorProjectionOnto(lineOfSight);
                        var v2Prime:Vector = b2Velocity.vectorProjectionOnto(lineOfSight);
                        var v1Prime2:Vector = new Vector();
                        v1Prime2.copyVector(v2Prime);
                        v1Prime2.mulScalar(2*b2Mass);
                        v1Prime2.addVector(v1Prime.getMulScalar(b1Mass - b2Mass));
                        v1Prime2.mulScalar(1.0/(b1Mass + b2Mass));
                        var v2Prime2:Vector = new Vector();
                        v2Prime2.copyVector(v1Prime);
                        v2Prime2.mulScalar(2*b1Mass);
                        v2Prime2.subVector(v2Prime.getMulScalar(b1Mass - b2Mass));
                        v2Prime2.mulScalar(1.0/(b1Mass + b2Mass));
                        v1Prime2.subVector(v1Prime);
                        v2Prime2.subVector(v2Prime);
                        b1Velocity.addVector(v1Prime2);
                        b2Velocity.addVector(v2Prime2);
                }
                // Отодвигает объект 1 от объекта 2, чтобы они не пересекались
                function PullBalls(ball1:basic_object, ball2:basic_object, add_random:Number=0):void {
                        var v:Vector = new Vector(ball1.x-ball2.x, ball1.y-ball2.y);
                        var distance:Number = Math.max(0.1, v.magnitude());
                        var min_distance:Number = ball1.radius + ball2.radius;
                        if (distance > min_distance) return; // не пересекаются
                        v.mulScalar((0.1+add_random+min_distance-distance)/distance);
                        ball1.x += v.x;
                        ball1.y += v.y;
                        if (add_random>0){ // добавить небольшой рандом в положение ball1
                                ball1.Velocity.addVector(v.getUnitVector());
                                ball1.x += (Math.random()-0.5)*add_random;
                                ball1.y += (Math.random()-0.5)*add_random;
                        }
                }
        }
}

Вобщем старался сам как мог найти ответ на свой вопрос, но в итоге оказалось что без сторонней помощи не обойдусь. Если не трудно, помогите пожалуйста разобраться в чем дело. Ну и просьба более доходчиво обьяснить, ибо я еще нюб. Спасибо.

MerlinTwi 19.06.2008 10:58

У вас проблема в 40-ой строке:
Код:

        // добавим в эти сектора ссылку на объект
        for each (s in new_asteroid.sectors){
                if (!all_sectors[s]){ // такого сектора еще не было, создадим
                        all_sectors[s] = new Object();
                }
                all_sectors[s][new_asteroid.name] = new_asteroid;
        }

asteroid.sectors - это Object вида:
[0_0] = true
[0_1] = true
...
Т.е. в качестве имени номер сектора, а в качестве значения всегда true.
Если перебирать циклом
Код:

for (s in new_asteroid.sectors) ...
то переменная "s" будет принимать значения: "0_0", "0_1" ...
Если же циклом for each, то вы пройдетесь по значениям, а не по именам:
Код:

for each (s in new_asteroid.sectors) ...
переменная "s" будет принимать значения: "true", "true" ...

В итоге, при создании все астероиды попали в сектор "true", и когда пытаетесь его корректно удалить (цикл for) из сектора "0_0", его нет, там null, о чем и сообщает Flash.
Ошибка довольно хитрая, понять в чем дело можно лишь, запустив в debug mode и внимательно посмотрев на значения переменных участвующих в строке с ошибкой: "s", "obj.sectors", "all_sectors", "all_sectors[s]"

Faster_ 24.06.2008 16:39

Привет всем!
А дайте пожалуйсто ссылочку на эту статейку и если возможно то уже исправленую и дополненую? :)
Заранее благодарен! ;)

etc 24.06.2008 18:32

Статью никто не переписывал.

Faster_ 24.06.2008 20:01

А исходники?

etc 24.06.2008 20:08

Аналогично. Может кто-то и делал, но не видел.

Faster_ 24.06.2008 20:10

Ладно, спасибо за ответ, буду ковырять, что есть :)

Faster_ 25.06.2008 01:06

Охх... вот и я дошёл до ошибок :(

Вот весь код пока:
Код:

package main {
        import flash.display.MovieClip;
        import flash.events.*;
               
        dynamic public class preloader extends MovieClip {
                public function preloader() {
                        addEventListener(Event.ENTER_FRAME, Update);
                }
                public function Update(e : Event):void {
                        this.txt.text = "Please wait...";
                }
        }
}

Ошибка
Код:

TypeError: Error #1010: A term is undefined and has no properties.
        at main::preloader/Update()

Дебагер тыкает на 11 строку :(
Не пойму в чем дело...

Вот исходник, если что http://narod.ru/disk/1101705000/game.rar.html

etc 25.06.2008 01:16

А давайте вы как-нибудь прочитаете всю эту тему и исправите ошибки сами, вы же сами хотите учить AS3, так ведь?

Faster_ 25.06.2008 01:23

Хм )) я первым делом её и прочитал )) На пост выше вроде такая же ошибка, но в другом случае :(


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

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