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

reNiks 07.03.2011 15:51

проблемы с движком поиска пути
 
Здравствуйте!
По уроку http://www.ant-karlov.ru/TowerDefence5-poisk-puti.html делаю движок поиска пути, с некоторыми изменениями. Вот тут привожу код:
Код AS3:

package ru.reNiks
{
    import flash.geom.Point;
    import ru.RainbowAdventure.Universe;
    public class PathFinder
    {
 
        private static const WATER_KEY:int = 999;
 
 
 
        private var _mapDirs:Array = [];
        private var _mapWidth:int = 29;// Ширина карты
        private var _mapHeight:int = 19;// Высота карты
 
        private var _freeCell:int = 0;// Вид свободной ячейки
        private var _maxIterations:int = 500;// Счетчик повторов
 
 
        private var _mapMask:Array;
 
        public function PathFinder()
        {
            _mapMask = Universe.Map;
 
            trace("hahahah",_mapMask);
 
        }
        private function lox()
        {
            for (var a:int = 0; a < _mapHeight; a++)
            {
                _mapDirs[a] = [];
                for (var g:int = 0; g< _mapWidth; g++)
                {
 
                    if (_mapMask[a][g] == 1 || _mapMask[a][g] == 0)
                    {
                        _mapDirs[a][g] = 0;
                    }
                }
            }
            trace("yyy",_mapDirs);
        }
 
        private function inMap(ax:int, ay:int):Boolean
        {
            if (ax >= 0 && ay < _mapWidth && ay >= 0 && ay < _mapHeight)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
 
 
        private function goWater(ay,ax):void
        {
            trace("1AY=",ay,ax);
            // Если клеточка сверху свободна
            if (inMap(ax,ay - 1) && _mapMask[ay - 1][ax] == _freeCell)
            {
                trace("afs",_mapMask);
                _mapMask[ay - 1][ax] = WATER_KEY;// Заполняем её водой
                // Запоминаем из какой клетки вода пришла
 
                (_mapDirs[ay - 1][ax] as Point).x = ax;
                (_mapDirs[ay - 1][ax] as Point).y = ay;
 
            }
 
            // Если клеточка слева свободна
            if (inMap(ax + 1,ay) && _mapMask[ay][ax + 1] == _freeCell)
            {
                _mapMask[ay][ax + 1] = WATER_KEY;// Заполняем её водой
                // Запоминаем из какой клетки вода пришла
                trace("AY=",ay,ax);
                trace("eee",_mapDirs);
                (_mapDirs[ay][ax + 1] as Point).x = ax;
                (_mapDirs[ay][ax + 1] as Point).y = ay;
                trace("ees",_mapDirs);
            }
 
            // Если клеточка снизу свободна
            if (inMap(ax,ay + 1) && _mapMask[ay + 1][ax] == _freeCell)
            {
                _mapMask[ay + 1][ax] = WATER_KEY;// Заполняем её водой
                // Запоминаем из какой клетки вода пришла
                (_mapDirs[ay + 1][ax] as Point).x = ax;
                (_mapDirs[ay + 1][ax] as Point).y = ay;
            }
 
            // Есле клеточка справа свободна
            if (inMap(ax - 1,ay) && _mapMask[ay][ax - 1] == _freeCell)
            {
                _mapMask[ay][ax - 1] = WATER_KEY;// Заполняем её водой
                // Запоминаем из какой клетки вода пришла
                (_mapDirs[ay][ax - 1] as Point).x = ax;
                (_mapDirs[ay][ax - 1] as Point).y = ay;
            }
            trace("aaa",_mapDirs);
        }
        public function findWay(starte:Point, end:Point):Array
        {
            trace("finish",starte,end);
            // Устанавливаем точку куда льем "воду" 
            _mapMask[end.y][end.x] = WATER_KEY;
            var counter:int = 0;// Счетчик проходов по карте
 
            // Выполняем проходы по карте
            while (counter < _maxIterations)
            {
                // Ищим путь / размазываем воду по маске проходимости
                for (var a:int = 0; a < _mapHeight; a++)
                {
                    for (var d:int = 0; d < _mapWidth; d++)
                    {
                        // Если в текущей ячейке вода
                        if (_mapMask[a][d] == WATER_KEY)
                        {
                            goWater(a, d);// то распространяем её в соседние ячейки
                        }
                    }
                }
                trace("asss",_mapDirs);
                // Проверяем не попала ли вода в точку финиша
                if (_mapMask[starte.y][starte.x] == WATER_KEY)
                {
                    // Ура! Путь найден!
                    // Возвращаем путь
                    return getWay(starte, end);
                }
                counter++;
            }
 
            // Количество проходов исчерпано, путь не найден
            // Возвращаем пустой массив
            return [];
        }
        private function getWay(starte:Point, end:Point):Array
        {
 
            var way:Array = [];// Маршрут
            var p1:Point = new Point(starte.x,starte.y);
            var p2:Point = new Point();
            trace("p1",p1);
            trace("ASSS",_mapDirs);
            // Добавляем в маршрут все точки
            // пока не дойдем до конца
            while (true)
            {
                trace("xDDD",p1, p2);
                trace("Xddd",p1.x, p1.y);
                trace("mab",_mapDirs);
 
                // Получаем новую точку из направления предыдущей
                p2.x = (_mapDirs[p1.y][p1.x] as Point).x;
                p2.y = (_mapDirs[p1.y][p1.x] as Point).y;
 
                way.push(new Point(p2.x, p2.y));
                // Добавляем новую точку в маршрут;
                p1.x = p2.x;
                p1.y = p2.y;
 
                // Проверяем, не добрались ли до конца
                if (p1.x == end.x && p1.y == end.y)
                {
                    break;
                }
            }
            return way;
            trace(way);
        }
        public function set freeCell(value:int):void
        {
            _freeCell = value;
        }
 
        public function set maxIterations(value:int):void
        {
            _maxIterations = value;
        }
    }
}

при компиляции вот такая ошибка:
Код:

TypeError: Error #1010: Термин не определен и не имеет свойств.
    at ru.reNiks::PathFinder/goWater()
    at ru.reNiks::PathFinder/findWay()
    at ru.RainbowAdventure.Characters::Enemys/init()
    at ru.RainbowAdventure.Characters::Enemys/init1()
    at flash.display::DisplayObjectContainer/addChildAt()
    at flash.display::Stage/addChildAt()
    at fl.rsl::RSLPreloader/contentComplete()

в 81ой строчке "(_mapDirs[ay][ax + 1] as Point).x = ax" и, при этом в абсолютно идентичной 69ой строчке, которая между прочим выполняется раньше, вот кстати и она "(_mapDirs[ay - 1][ax] as Point).x = ax;", никакой ошибки не появляется.
Подскажите пожалуйста в чем проблема? Спасибо заранее

-De- 07.03.2011 18:38

Проблема в том, что вы не знаете, что значит "TypeError: Error #1010: Термин не определен и не имеет свойств." (или отлаживать не умеете) Это значит, что вы пытаетесь дёрнуть св-во у undefined. И ошибка вродь не при компиляции, а при выполнении.
Если правда в той строке, где говорите, то _mapDirs[ay] - undefined, оттрейстьте. Ну а _mapDirs[ay - 1] - не undefined.

reNiks 09.03.2011 20:33

хорошо я понял. Тогда объясните пожалуйста что делает и как работает команда "as Point"?

Jewelz 09.03.2011 20:41

Код AS3:

as

означает приведение типов, в массиве могут храниться разные типы данных, а этим вы показываете, что этот элемент является экземпляром класса Point, и насколько я знаю это действие еще ускоряет работу, нежели простое обращение
Код AS3:

_mapDirs[p1.y][p1.x].x


reNiks 10.03.2011 21:38

извините. возникла тут небольшая проблема. В общем дело в чем: в движке поиска пути координаты считаются по тайлам, т.е. целые числа. координаты начальной и конечной точки создаются просто-берутся координаты в пикселах и делятся на ширину тайла, при этом значения положения для расчетов имеют тип "int". в таком случае от числа просто отбрасывается дробная часть, но зачастую при этом получается что цель находится в недопустимой зоне, к примеру-в стене. кто сталкивался с подобной проблемой-помогите пожалуйста


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

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