Статьи

Создание редактора изометрической карты с As3isolib

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


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

SWF был слегка сдавлен, чтобы поместиться на странице; нажмите здесь, чтобы увидеть его в полном размере .


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

Предположим, вы находитесь в изометрической проекции; у вас будет трехмерный вид (например, когда камера делает вашу фотографию), где бы вы ни находились, вы будете показаны в том же масштабе, что и эта камера. Это отличается от истинной перспективы, когда вы будете уменьшены в размерах, когда будете далеко от камеры.

Шаг 1

As3isolib обрабатывает всю основную математику, связанную с созданием ваших сцен и представлений, так что не беспокойтесь о математике!


Плитка на основе — это термин, используемый для любого графического контента, который использует плитки в качестве основного элемента. Сама концепция устарела — она ​​использовалась в старых играх по техническим причинам — но это не значит, что игры на основе тайлов теперь мертвы; В наши дни 3D-рендеринг есть, но эти 3D-игры могут быть основаны на плитках (и многие из них). Именно здесь появляются изометрические игры. Плитки обычно имеют прямоугольную форму, но есть также квадратные, треугольные и даже шестиугольные (как в некоторых названиях Civilization).


С прямоугольными плитками работать проще всего, хотя в большинстве случаев при работе в прямоугольной местности вы используете квадратные плитки. Конечно, вы можете использовать и другие размеры, но квадрат кажется излюбленным. Точка зрения для игр с квадратными плитками обычно сверху вниз или сверху. Это просто означает, что вся ваша графика должна быть нарисована так, как будто вы смотрите на объект сверху вниз. Иногда вы можете дать своей игре слегка наклоненный вид, чтобы вы смотрели в основном вниз, но вы можете видеть некоторые спереди или сзади.

Другая точка зрения для квадратных плиток — это вид «боковой скроллер», где вы смотрите на мир с его стороны. Это было очень популярно среди старых боевиков, таких как Super Mario Bros и 2D Duke Nukem. На прямоугольной карте перемещение по оси X означает перемещение на восток, а перемещение по оси Y означает перемещение на юг. В изометрической карте тайлов, в зависимости от ее типа, перемещение вдоль оси X может означать перемещение на юго-восток, а перемещение вдоль оси Y может означать перемещение на юго-запад. В изометрических плитках мы по-прежнему используем прямоугольные области для хранения плиток; это не изменится. Что изменится, так это то, как вы будете их отображать.

(Примечание редактора: большое руководство по различным типам перспективы можно найти здесь .)


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

Карты слайдов. Карта слайдов, вероятно, наиболее проста для рендеринга, навигации и взаимодействия с ней. К сожалению, он имеет ограниченное использование. Он в основном используется для прокрутки экшн-игр. Обычно слайд-карта имеет горизонтальную ось X и диагональную ось Y, хотя возможно иметь вертикальную ось Y и диагональную ось X. Плитка сглаживается горизонтальными рядами сверху вниз.

Ступенчатые карты: Ступенчатые карты отлично работают в пошаговых стратегических играх. Это также очень полезно в симуляции круглого мира; это лучше всего подходит для карт, которые обертываются (перемещаются от одного края к другому). Каждый новый ряд карты поочередно сдвигается на половину плитки влево или вправо, что приводит к зигзагообразному рисунку плиток. Ось X обычно горизонтальна (увеличивается на восток), а ось Y — юго-восток и юго-запад. Постепенные карты являются самыми нерегулярными из трех. Плитка сглаживается горизонтальными рядами сверху вниз.

Алмазные карты: этот тип карт очень популярен в стратегических играх в реальном времени. Эти карты наименее оскорбительны; на слайд-картах есть «рваные» вершины и впадины, а на шахматных картах — «рваные» края, поэтому алмазные карты самые гладкие. В алмазных картах единственным требованием является то, что оси X и Y имеют диагональ, поэтому вы можете увеличивать ось X или Y по своему усмотрению, например, увеличивать ось X к юго-западу и ось Y к юго-востоку. ,

Типы изометрической карты

Этого достаточно, контекст — пора начинать развиваться!


Первым шагом является загрузка As3isolib (Изометрическая библиотека ActionScript 3), которая является библиотекой с открытым исходным кодом для создания изометрического проецируемого содержимого. Одним из примеров игры, созданной с ее помощью, являются Empires и Allies из Zynga.

Библиотека содержит некоторые ресурсы, такие как примитивные фигуры (прямоугольники, кубы и т. Д.) И некоторые утилиты, облегчающие создание изометрического контента. Это также бесплатно и может быть использовано в любой коммерческой работе (хотя вы можете пожертвовать ее, если хотите).

Давайте теперь скачать его отсюда . После загрузки распакуйте zip-файл в новую папку и назовите его Level Editor .

В любое время при использовании As3isolib вы можете обратиться к его документации по этой ссылке


Запустите Flash и создайте новый ActionScript 3.0 FLA. Теперь нам нужно импортировать PSD-файл для созданного мной интерфейса редактора уровней (он находится в исходных файлах учебника), или вы можете изменить дизайн интерфейса так, как вы считаете, выглядит хорошо. Поэтому нажмите «Файл»> «Импорт»> «Импортировать в рабочую область», выберите файл PSD и отметьте параметр «установить размер сцены равным размеру холста Photoshop».

Теперь у нас есть необработанные изображения для нашего редактора уровней. Нам нужно создать наш класс документов, в котором мы будем реализовывать наш редактор уровней: на панели «Свойства» в разделе «Публикация» вы найдете поле «Класс»; напишите CDoc и нажмите на кнопку карандаша. Теперь сохраните появившийся файл ActionScript и назовите его CDoc.

Шаг 6

Давайте сделаем наши три кнопки в нижней панели; щелкните правой кнопкой мыши на фоновом изображении кнопки и выберите «Преобразовать в символ», как показано на рисунке, затем переименуйте кнопку в btnClear , вставьте текст в кадры «Вверх», «Вверх», «Вниз» и «Хит» и введите в него « ОЧИСТИТЬ ВСЕ» . В состояния Over и Hit вставьте изображение при наведении, как на скриншоте.

Шаг 7

Затем повторите этот шаг, чтобы сделать оставшиеся две кнопки.


Теперь мы создадим три вкладки: одна для Soild Colors, другая для Bricks и последняя для Grass.

Нарисуйте черный градиентный прямоугольник, щелкните его правой кнопкой мыши и выберите «Преобразовать в символ», затем назовите его «Tab» и выберите его тип в качестве фрагмента ролика. Теперь отметьте опцию Export for ActionScript, затем в поле Class напишите CTab, которая будет именем класса для этой вкладки Movie Clip.

Дважды щелкните вкладку Movie Clip и вставьте в нее текст; внутри этого напишите ИМЯ . Этот текст будет изменен с именем вкладки; чтобы разрешить это, преобразуйте этот текст в динамический текст с именем txt , как на картинке ниже.

Шаг 8

Теперь у нас есть мувиклип для нашей вкладки, нам нужно создать три его копии и назвать их, так что давайте сделаем это в нашем классе документов.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package
{
    import flash.events.MouseEvent;
    import flash.text.TextField;
    import flash.display.MovieClip;
 
    public class CTab extends MovieClip
    {
        public var txt:TextField;
 
        public function CTab(Name:String)
        {
            txt = this.txt as TextField;
            txt.text = Name;
            addEventListener(MouseEvent.ROLL_OVER, onRollOver, false, 0, true);
            addEventListener(MouseEvent.ROLL_OUT, onRollOut, false, 0, true);
        }
 
        protected function onRollOver(e:MouseEvent):void
        {
            this.alpha = 0.9;
        }
 
        protected function onRollOut(e:MouseEvent):void
        {
            this.alpha = 1;
        }
    }
}
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package
{
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.MouseEvent;
 
    public class CDoc extends MovieClip
    {
        // Instantiating The Tabs
        private var Solid:CTab;
        private var Bricks:CTab;
        private var Grass:CTab;
 
        public function CDoc()
        {
            addEventListener(Event.ADDED_TO_STAGE, onAddedToStage, false, 0, true);
        }
 
        protected function onAddedToStage(e:Event):void
        {
            // Creating the tabs
            Solid = new CTab(«SOLID»);
            Solid.y = 469;
            Solid.addEventListener(MouseEvent.CLICK, onSolidClick, false, 0, true);
            addChild(Solid);
 
            Bricks = new CTab(«BRICKS»);
            Bricks.y = 494;
            Bricks.addEventListener(MouseEvent.CLICK, onBricksClick, false, 0, true);
            addChild(Bricks);
 
            Grass = new CTab(«GRASS»);
            Grass.y = 521;
            Grass.addEventListener(MouseEvent.CLICK, onGrassClick, false, 0, true);
            addChild(Grass);
        }
 
        protected function onSolidClick(e:MouseEvent):void
        {
            // will be implemented later
        }
 
        protected function onBricksClick(e:MouseEvent):void
        {
            // will be implemented later
        }
 
        protected function onGrassClick(e:MouseEvent):void
        {
            // will be implemented later
        }
    }
}

Теперь давайте узнаем об одной из самых важных вещей в As3isolib: изометрическом виде, который служит как камера, которая показывает изометрические объекты. Он имеет много полезных функций, таких как панорамирование и масштабирование и фокусировка на точке или любом объекте. Он также предоставляет возможность скрывать / обрезать объекты за пределами его границ, а также позволяет нам изменять его фон и содержимое переднего плана.

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

Теперь мы добавим следующий код в наш класс CDoc — обязательно проверьте нумерацию строк или просто взгляните на исходные файлы учебника.

1
2
//Add this line before the constructor
private var viewPort:IsoView;
1
2
3
4
5
6
viewPort = new IsoView();
viewPort.setSize(800, 600);
viewPort.centerOnPt(new Pt(-100, 100, 0), false);
addChildAt(viewPort, 0);
viewPort.addEventListener(MouseEvent.MOUSE_DOWN, onStartPan, false, 0, true);
viewPort.addEventListener(MouseEvent.MOUSE_WHEEL, onZoom, false, 0, true);

В первой строке мы создали наш IsoView и назвали его viewPort, затем во второй строке мы установили его размер 800x600px. Нам нужно as3isolib.geom ее на точке или на объекте, поэтому мы создали новую точку из встроенного пакета as3isolib.geom и дали ей некоторые значения x и y в трехмерном изометрическом пространстве (что мы обсудим на следующем шаге).

Теперь нам нужно показать наш viewPort, чтобы мы добавили его в список отображения документа как дочерний элемент, и чтобы он был в нижней части нашего интерфейса, чтобы убедиться, что он не будет перекрываться с любым другим элементом, который мы добавили в индекс 0. Затем мы добавили два прослушивателя событий в наш viewPort, один для панорамирования, а другой для масштабирования (что я снова объясню позже).


Система координат, используемая во Flash, называется декартовой системой координат . Декартовая система координат основана на сетке (состоящей из множества мнимых квадратов одинакового размера) с горизонтальной осью, называемой осью x, и вертикальной осью, называемой y, как в верхнем левом углу изображения ниже.

Изометрическое пространство немного отличается; каждая из трех осей имеет одинаковый размер, а углы между любыми двумя из них составляют 120 градусов. As3isolib предоставляет способ преобразования точки из декартовой в изометрические координаты (и наоборот), вызывая IsoMath.screenToIso(Point:Pt) для преобразования в одну сторону и IsoMath.isoToScreen(Point:Pt) для преобразования в другую.

Шаг 11

Создать изометрическую сцену, которая будет содержать наши объекты, очень просто. (Все эти объекты будут унаследованы от IsoDisplayObject (например, IsoBox, IsoRectangle, IsoSprite и т. Д.), Который является базовым классом, который расширяют все примитивные и сложные изометрические экранные объекты.)

Мы создадим новую IsoScene, а затем добавим нашу сцену в окно просмотра.

1
2
//Add this line before the constructor
private var scene:IsoScene;
1
2
scene = new IsoScene();
viewPort.addScene(scene);

Чтобы добавить сетку в область просмотра, нам нужно просто создать новую IsoGrid, а затем установить ее ширину и длину в 10, чтобы получить сетку 10×10. Кроме того, мы можем установить размер его ячейки так, как нам хочется (я выбрал 30). Последний и очень важный шаг — добавить сетку на сцену.

1
2
//Add this line before the constructor
private var grid:IsoGrid;
1
2
3
4
grid = new IsoGrid();
grid.setGridSize(10, 10, 1);
grid.cellSize = 30;
scene.addChild(grid);

Нам нужно добавить прослушиватель событий для визуализации сцены, и это очень просто, просто добавьте прослушиватель и в его теле вызовите функцию render() на сцене.

1
2
//Add this code in onAddedToStage listener
addEventListener(Event.ENTER_FRAME, onRender, false, 0, true);
1
2
3
4
private function onRender(e:Event):void
{
    scene.render();
}

На этом шаге мы добавим слушателей для событий click на кнопках нижней панели, но сначала нам нужно получить к ним доступ, что мы можем сделать с помощью функции getChildByName() .

В первом обработчике события для кнопки « Очистить» мы удалим все дочерние элементы сцены, а затем нам нужно снова добавить сетку. В кнопке « Подогнать к экрану» мы установим текущий масштаб окна просмотра на 1, который вернет его к panTo() по умолчанию, затем мы будем панорамировать его в положение по умолчанию с помощью функции panTo() . Последняя кнопка, где мы будем показывать / скрывать источники сетки, поэтому мы будем инвертировать ее состояние отображения; если он будет показан, мы его спрячем и наоборот.

1
2
3
this.getChildByName(«btnClear»).addEventListener(MouseEvent.CLICK, onbtnClearClick, false, 0, true);
this.getChildByName(«btnFit»).addEventListener(MouseEvent.CLICK, onbtnFitClick, false, 0, true);
this.getChildByName(«btnShow»).addEventListener(MouseEvent.CLICK, onbtnShowClick, false, 0, true);
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
protected function onbtnClearClick(e:MouseEvent):void
{
    scene.removeAllChildren();
    scene.addChild(grid);
}
protected function onbtnFitClick(e:MouseEvent):void
{
    viewPort.currentZoom = 1;
    viewPort.panTo(-100, 100);
}
protected function onbtnShowClick(e:MouseEvent):void
{
    if (grid.showOrigin)
        grid.showOrigin = false;
    else
        grid.showOrigin = true;
}

Когда мы создали наш видовой экран, мы добавили прослушиватель событий для события MOUSE_DOWN. В этом слушателе событий мы будем обрабатывать начало панорамирования: сначала мы создадим точку и назовем ее panPt в качестве глобальной точки, чтобы использовать ее в разных местах, поскольку она будет обрабатывать местоположение мыши в каждом кадре. Мы дадим ему X и Y положения мыши (я объясню почему на следующем шаге).

Затем мы удаляем обработчик событий мыши и добавляем два новых прослушивателя: один для фактической обработки панорамирования, а другой, когда мы прекращаем панорамирование.

01
02
03
04
05
06
07
08
09
10
private var panPt:Pt;
private function onStartPan(e:MouseEvent):void
{
    panPt = new Pt(stage.mouseX, stage.mouseY);
 
    viewPort.removeEventListener(MouseEvent.MOUSE_DOWN, onStartPan);
 
    viewPort.addEventListener(MouseEvent.MOUSE_MOVE, onPan, false, 0, true);
    viewPort.addEventListener(MouseEvent.MOUSE_UP, onStopPan, false, 0, true);
}

Этот прослушиватель событий вызывается, когда мышь движется, и он очень прост: он перемещает область просмотра в соответствии с позициями X и Y начального положения мыши, панорамируя минус ее текущие позиции, чтобы вычислить разницу в местоположении относительно последнего кадра. Затем мы устанавливаем X и Y на текущие позиции мыши.

1
2
3
4
5
6
7
private function onPan(e:MouseEvent):void
{
    viewPort.panBy(panPt.x — stage.mouseX, panPt.y — stage.mouseY);
 
    panPt.x = stage.mouseX;
    panPt.y = stage.mouseY;
}

Когда мы прекращаем панорамирование, нам нужно удалить прослушиватели событий onPan и onStopPan, поскольку они нам больше не нужны, затем повторно добавить прослушиватель событий onStartPan, чтобы позволить пользователю снова панорамировать область просмотра.

1
2
3
4
5
6
7
private function onStopPan(e:MouseEvent):void
{
    viewPort.removeEventListener(MouseEvent.MOUSE_MOVE, onPan);
    viewPort.removeEventListener(MouseEvent.MOUSE_UP, onStopPan);
 
    viewPort.addEventListener(MouseEvent.MOUSE_DOWN, onStartPan, false, 0, true);
}

Ранее мы добавили прослушиватель события onZoom MOUSE_WHEEL, поэтому теперь мы его реализуем.

Это действительно просто: чтобы узнать, движется ли мышь вверх или вниз, нам нужно проверить свойство события мыши ( e ), которое называется «дельта»; если это больше чем 0, тогда мы должны увеличить, иначе мы должны уменьшить. Для этого мы увеличиваем или уменьшаем значение увеличения. Последний шаг — установить для свойства currentZoom области просмотра значение масштабирования.

01
02
03
04
05
06
07
08
09
10
11
private var zoomValue:Number = 1;
private function onZoom(e:MouseEvent):void
{
    if(e.delta > 0)
        zoomValue += 0.10;
 
    if(e.delta < 0)
        zoomValue -= 0.10;
 
    viewPort.currentZoom = zoomValue;
}

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


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

Мы начнем с создания новой изометрической сцены с именем objectScene для хранения наших объектов. Затем мы создаем новый изометрический вид для визуализации объектов в сцене и устанавливаем его размер 215x468px, который соответствует панели объектов. Теперь нам нужно выровнять его, чтобы мы центрировали его на точке размером 40×80 пикселей. Наконец, мы добавляем objectScene в представление объекта с помощью функции addScene() и добавляем objectView в список отображения нашего документа.

1
2
3
4
5
6
7
8
//Add this code in onAddedToStage listener
objectScene = new IsoScene();
 
objectView = new IsoView();
objectView.setSize(215, 468);
objectView.centerOnPt(new Pt(40, 80, 0), false);
objectView.addScene(objectScene);
addChild(objectView);

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

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
protected function onSolidClick(e:MouseEvent):void
{
    objectScene.removeAllChildren();
    var p:Pt = new Pt(0, 0);
    var solidColors:Array = [0xD15415, 0xFF6600, 0xFFCC00, 0x66FF00, 0xFF6699, 0x6699FF, 0x99FF00, 0xFF0066];
    for (var i:int = 0; i < 8; i++)
    {
        if (i % 2 == 0)
        {
            px = 0;
            py += 50;
        }
            var obj:IsoRectangle = new IsoRectangle();
        obj.setSize(30, 30, 0);
        obj.fill = new SolidColorFill(solidColors[i], 1);
        IsoMath.screenToIso(p);
        obj.moveTo(px, py, 0);
        IsoMath.isoToScreen(p);
        px += 80;
        obj.addEventListener(MouseEvent.ROLL_OVER, onRollOverHandler, false, 0, true);
        obj.addEventListener(MouseEvent.ROLL_OUT, onRollOutHandler, false, 0, true);
        obj.addEventListener(MouseEvent.CLICK, onObjClick, false, 0, true);
 
        objectScene.addChild(obj);
        objectScene.render();
     }
}

Сначала мы удаляем все дочерние элементы из objectScene, чтобы удалить все объекты, если мы фактически нажали на другую вкладку. Во-вторых, нам нужно создать Point для хранения позиций X и Y объектов, затем мы создадим массив сплошных цветов и поместим в него некоторые шестнадцатеричные значения цвета. После этого мы сделаем цикл, в котором мы создадим наши восемь объектов и покажем их в виде сетки. Затем мы фактически создаем каждый изометрический прямоугольник, используя встроенную изометрическую примитивную форму As3isolib, устанавливаем размер 30×30 пикселей и заливаем его цвет сплошным цветом (также встроенным в As3isolib), используя значение из нашего массива с альфа-значением 1 ,

Теперь нам нужно изменить наши значения точек, чтобы они находились в изометрических координатах, поэтому мы используем вышеупомянутую screenToIso() , затем перемещаем наш объект в новую позицию и сбрасываем нашу точку, чтобы она находилась в экранных координатах — это облегчает нам выровняйте наши объекты в сетке с нашими знакомыми экранными (декартовыми) координатами, в то время как мы перемещаем наши объекты в соответствии с тем, что подходит им больше всего (изометрические координаты)

Затем мы просто увеличиваем значение X на 80 и добавляем три прослушивателя событий: первые два будут обрабатывать события ROLL_OVER для подсветки объекта при наведении, а третий будет обрабатывать события CLICK. Наконец мы добавляем объект на сцену и визуализируем все.


Этот шаг очень похож на предыдущий, за исключением того, что мы меняем содержимое массива на наши кирпичи, которые мы создадим и импортируем на наших следующих шагах.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
protected function onBricksClick(e:MouseEvent):void
{
    objectScene.removeAllChildren();
    var p:Pt = new Pt(-20, -10);
    var bricks:Array = [Bricks1, Bricks2, Bricks3, Bricks4, Bricks5, Bricks6, Bricks7, Bricks8];
    for (var i:int = 0; i < 7; i++)
    {
        if (i % 2 == 0)
        {
            px = -30;
            py += 50;
        }
    var sprite:IsoSprite = new IsoSprite();
    IsoMath.screenToIso(p);
    sprite.moveTo(px, py, 0);
    IsoMath.isoToScreen(p);
    px += 80;
    sprite.sprites = [bricks[i]];
    sprite.addEventListener(MouseEvent.ROLL_OVER, onRollOverHandler, false, 0, true);
    sprite.addEventListener(MouseEvent.ROLL_OUT, onRollOutHandler, false, 0, true);
    sprite.addEventListener(MouseEvent.CLICK, onObjClick, false, 0, true);
    objectScene.addChild(sprite);
    objectScene.render();
    }
}

Другое отличие от предыдущего шага состоит в том, что мы создали изометрический спрайтовый объект, внешний вид которого мы можем полностью изменить на то, что хотим; мы добавили в него наши кирпичи, передав ссылку на sprite.sprites который является массивом спрайтов.

Теперь вы можете создавать объекты травы, как мы это делали с кирпичами, вам нужно просто изменить массив bricks массив grass .


Мы собираемся сделать наши текстурные активы, поэтому запустите новый документ Flash и импортируйте наши активы из изображения или из PSD-файла. В меню «Файл» нажмите « Импорт»> «Импортировать в рабочую область» , затем выберите импорт слоев в виде растрового изображения с редактируемыми стилями слоев .

Теперь нам нужно преобразовать каждое растровое изображение в фрагмент ролика, щелкнув его правой кнопкой мыши и выбрав « Преобразовать в символ» , а затем записав его имя, как в массивах «Кирпичи» и «Трава» ( Brick1 , Brick2 и т. Д.).

Отметьте опцию Экспорт для общего доступа во время выполнения и введите textures.swf в поле URL. Наконец, перейдите в File> Publish Settings и отметьте опцию SWC в разделе PUBLISH , затем нажмите Publish. Теперь у нас есть SWC, который содержит все наши активы, которые мы можем импортировать в наш LevelEditor для использования.

Шаг 23
Шаг 23
Шаг 22

Импортировать наш SWC-файл очень просто. В меню «Файл» выберите « Параметры ActionScript» , а на вкладке « Путь к библиотеке » нажмите кнопку «Flash», которая отображается на рисунке ниже, и перейдите к нашему SWC.

Шаг 21

Это оно! Теперь наши активы загружены.


Нам нужно обрабатывать события мыши для наших объектов — помните, что в шагах 18 и 19 мы добавили три прослушивателя событий для каждого объекта. На этом простом шаге мы реализуем прослушиватели событий ROLL_OVER.

Мне бы хотелось, чтобы у наших объектов был эффект свечения при наведении на него, поэтому нам нужно получить доступ к самим объектам. Для этого в As3isolib есть встроенный тип события ProxyEvent, который мы можем использовать для доступа к объекту события, используя e.target. Мы должны привести его к IsoDisplayObject (который является базовым классом для любого изометрического экранного объекта), чтобы сделать слушатель этого события как можно более универсальным, а затем добавить фильтр свечения, используя встроенные фильтры Flash.

Первым параметром конструктора GlowFilter является его цвет; вторая — это ее альфа, которую мы просто установим на 1; мы оставим значения blurX и blurY по умолчанию, 6, поскольку нам не нужно размытие; и, наконец, мы установим качество до 64.

В обработчике сворачивания мы просто сбросим фильтры.

1
2
3
4
5
6
7
8
9
private function onRollOverHandler(e:ProxyEvent):void
{
   var glow:GlowFilter = new GlowFilter(0xC24704, 1, 6, 6, 64);
   (e.target as IsoDisplayObject).container.filters = [glow];
}
private function onRollOutHandler(e:ProxyEvent):void
{
   (e.target as IsoDisplayObject).container.filters = [];
}

Третьим слушателем событий для наших объектов является событие CLICK. Что будет, когда мы нажмем на какой-либо объект? Что ж, нам нужно сделать его копию в окне просмотра и добавить к нему средство перетаскивания, чтобы нам было легче перемещаться в любое место на сцене.

Это очень просто сделать. Сначала мы создадим объект типа IsoDisplayObject и передадим ему наш объект, который мы щелкнули, как мы делали раньше.

Теперь нам нужно клонировать выбранный объект; это легко, поскольку As3isolib имеет встроенный метод clone() , который принадлежит классу IsoDisplayObject , который возвращает копию клонированного объекта, сохраняя его свойства размеров и стилей. Это будет отлично работать для объектов изометрического прямоугольника (которые мы создали на вкладке сплошного цвета), но в случае спрайтов (кирпичи и трава) нам также необходимо скопировать массив спрайтов для каждого объекта, поэтому мы сделаем простую проверку чтобы увидеть, относится ли объект к типу IsoSprite , и если его свойство sprites не равно нулю, мы установим свойство sprites объекта в соответствии со спрайтами объекта, по которому щелкнули.

Затем мы будем двигать наши объекты вверх (вдоль оси Z) на 50, чтобы избежать перекрытия с сеткой. Наконец, мы добавим три прослушивателя событий для нашего созданного объекта: два из них для пролистывания / разворачивания и последний для обработки перетаскивания (который мы рассмотрим на следующем шаге), затем добавим наш объект в нашу сцену и отрендерим его ,

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
protected function onObjClick(e:ProxyEvent):void
{
            var obj:IsoDisplayObject = e.target as IsoDisplayObject;
            obj = obj.clone();
            if(obj is IsoSprite && (obj as IsoSprite).sprites != null)
            {
                        (obj as IsoSprite).sprites = (e.target as IsoSprite).sprites;
            }
            obj.moveTo(0, 0, 50);
            obj.addEventListener(MouseEvent.ROLL_OVER, onRollOverHandler, false, 0, true);
            obj.addEventListener(MouseEvent.ROLL_OUT, onRollOutHandler, false, 0, true);
            obj.addEventListener(MouseEvent.MOUSE_DOWN, onPickup, false, 0, true);
 
            scene.addChild(obj);
            scene.render();
}

Есть оставшийся прослушиватель событий с именем onPickup, который является событием MOUSE_DOWN для обработки начала перетаскивания. Мы начнем с создания закрытой переменной с именем dragObject , которая будет иметь тип IsoDisplayObject , чтобы использовать ее в отношении нашего перетаскиваемого объекта, как он появляется из его имени. Также мы создадим точку для обработки положения перетаскиваемого объекта.

В обработчике раскладки мы назначим перетаскиваемый объект нашей переменной dragObject , затем для получения текущей изометрической точки мыши мы используем метод viewPort.localToIso() . Эта точка будет полезна при расчете расстояния между перетаскиваемым объектом и текущей позицией мыши, а также остановит перетаскиваемый объект от привязки к позиции мыши.

Наконец, мы удалим прослушиватель этого события, так как, когда наш объект забирается, мы не хотим его снова поднимать! Вместо этого мы добавим два прослушивателя событий для отбрасывания: один для перетаскиваемого объекта и другой для viewPort. Наконец, вы можете спросить, где происходит фактическое движение; Ответ заключается в том, что это происходит в обработчике onMoveObject, который мы рассмотрим на следующем и последнем шаге.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
private var dragObject:IsoDisplayObject;
private var dragPt:Pt;
private function onPickup(e:ProxyEvent):void
{
            dragObject = e.target as IsoDisplayObject;
            dragPt = viewPort.localToIso(new Pt(stage.mouseX, stage.mouseY));
            dragPt.x -= dragObject.x;
            dragPt.y -= dragObject.y;
 
            dragObject.removeEventListener(MouseEvent.MOUSE_DOWN, onPickup);
 
            dragObject.addEventListener(MouseEvent.MOUSE_UP, onDrop, false, 0, true);
            viewPort.addEventListener(MouseEvent.MOUSE_UP, onDrop, false, 0, true);
            viewPort.addEventListener(MouseEvent.MOUSE_MOVE, onMoveObject, false, 0, true);
}

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

Чтобы разрешить фактическое перемещение объекта, мы берем точку, соответствующую положению мыши в изометрическом пространстве, и перемещаем наш объект в соответствии со смещением между исходным положением мыши и ее текущим положением.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
private function onDrop(e:Event):void
{
            dragObject.removeEventListener(MouseEvent.MOUSE_UP, onDrop);
            viewPort.removeEventListener(MouseEvent.MOUSE_UP, onDrop);
            viewPort.removeEventListener(MouseEvent.MOUSE_MOVE, onMoveObject);
 
            dragObject.addEventListener(MouseEvent.MOUSE_DOWN, onPickup, false, 0, true);
}
private function onMoveObject(e:MouseEvent):void
{
            var pt:Pt = viewPort.localToIso(new Pt(stage.mouseX, stage.mouseY));
 
            dragObject.moveTo(pt.x — dragPt.x, pt.y — dragPt.y, dragObject.z);
}

В этом уроке мы рассмотрели основы библиотеки с открытым исходным кодом As3isolib и создали из нее изометрическое содержимое, например, изометрические прямоугольники и спрайты. Мы также рассмотрели, как создавать сцены, камеры и сетки, а также много полезных тем, таких как панорамирование, масштабирование, перетаскивание.

Теперь вы можете начать создавать свой изометрический проект Flash с As3isolib. Ищите мой следующий урок, о создании игры с As3isolib. Надеюсь, тебе весело!