Статьи

Расширенная настройка персонажей для Flash игр

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

Мы нашли этого замечательного автора благодаря FlashGameLicense.com , месту, где можно покупать и продавать флэш-игры!

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


Вот что вы построите к концу урока:

Заполните области одежды персонажа сплошными цветами, добавьте детали карандашом, затем нажмите «играть» и нажмите влево и вправо, чтобы увидеть его ходьбу!


Создайте новый документ AS3 Flash. Зайдите в панель свойств и убедитесь, что все настройки такие же, как на изображении ниже:


Затем создайте новый файл .as с именем CustomCharacter.as внутри каталога нашего проекта. Это будет наш основной класс. Введите CustomCharacter в настройках публикации как «Основной класс».
Убедитесь, что ваш класс CustomCharacter соответствует приведенному ниже.

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.display.Sprite;
    import flash.display.BitmapData
    import flash.net.FileReference
    import flash.display.Loader
    import flash.display.Bitmap
    import flash.display.MovieClip
    import fl.controls.ColorPicker
    import flash.events.Event
    import flash.events.MouseEvent
 
     
    public class CustomCharacter extends Sprite
    {
         
     
        public function CustomCharacter():void {
         
         
         
        }
         
         
    }
     
     
     
}

(Посмотрите это краткое введение в класс документа, если вы не уверены, что мы делаем на этом этапе.)


Теперь начнем с рисования нашего главного героя. В этом уроке важно убедиться, что у нас есть каждая часть тела в отдельном мувиклипе. Делая это, мы можем основывать нашу анимацию ходьбы на Tweens, что ускорит процесс анимации. Наш персонаж будет состоять из следующих объектов: голова, волосы, рубашка, две ноги и две руки. Вы можете найти главного героя, использованного в этом руководстве, в исходном FLA (ссылка на скачивание находится в верхней части руководства).

А пока, чтобы побудить игрока настроить персонажа, мы ограничим цвета частей тела персонажа серым с черными контурами. Выделите все тело, нажмите F8, чтобы превратить его в один мувиклип, и назовите его Player . Убедитесь, что вы установили точку регистрации каждой части тела в верхнем левом углу. Теперь кликните по новому мувиклипу Player на сцене и установите имя экземпляра в player .

Вот и все, мы только что создали нашего персонажа Player !


Для начала нам нужно добавить компонент ColorPicker в нашу библиотеку. Перейдите в панель компонентов, перейдя в Window> Components. Найдите класс ColorPicker и перетащите его на панель библиотеки.

Далее нам нужно выполнить всю работу ActionScript. Вот как будет выглядеть наш класс CustomCharacter после наших новых изменений.

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
package
{
    import flash.display.Sprite;
    import flash.display.BitmapData
    import flash.events.Event;
    import flash.net.FileReference
    import flash.display.Loader
    import flash.display.Bitmap
    import flash.display.MovieClip
    import fl.controls.ColorPicker
    import flash.events.MouseEvent
     
    public class CustomCharacter extends Sprite
    {
        var myColorPicker:ColorPicker = new ColorPicker();
     
        public function CustomCharacter():void {
             
        myColorPicker.editable = true;
        myColorPicker.visible = false;
        addChild(myColorPicker);
         
        player.addEventListener(MouseEvent.CLICK, showPicker)
        myColorPicker.addEventListener(Event.CHANGE, colorChanged)
         
        }
         
        private function colorChanged(e:Event):void
        {
            myColorPicker.visible = false;
        }
         
        private function showPicker(e:MouseEvent):void
        {
            myColorPicker.visible = !myColorPicker.visible
            myColorPicker.move(stage.mouseX,stage.mouseY)
             
        }
         
         
         
         
    }
     
     
     
}

Давайте пройдем этот шаг за шагом, начиная с функции конструктора. Сначала мы создаем новую переменную с именем myColorPicker . Затем мы сообщаем ему, что это экземпляр класса ColorPicker , вызывая = new ColorPicker () . Далее мы говорим, что наш ColorPicker изменяем и невидим, поэтому мы можем показать его, когда нажимаем на плеер. Затем мы добавляем класс ColorPicker на сцену, хотя он не виден.

Мы также добавили двух слушателей событий. Один для того, когда вы нажимаете на проигрыватель, который переключает видимость ColorPicker и перемещает его в положение мыши при щелчке, а второй — для проверки, когда пользователь выбрал новый цвет, чтобы мы могли сделать ColorPicker снова невидимый!


К сожалению, мы не можем просто использовать ColorPicker и заставить его изменить цвет объекта. Во-первых, нам нужно, чтобы ColorPicker определил, на какой объект вы щелкаете, чтобы он мог определить, какой объект нужно изменить. Это требует использования одной из мощных функций MouseEvent в AS3.

Внутри функции showPicker мы можем просто использовать e.target для нацеливания мувиклипа, на который действительно щелкают . Мы можем опустить альфа кликаемого объекта, чтобы подтвердить, с каким объектом мы имеем дело. Просто добавьте приведенный ниже код в функцию showPicker ().

1
e.target.alpha -= .5

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

Затем нажмите F8, чтобы создать новый мувиклип с этой серой заливкой, и назовите его «_____Color» (поэтому для мувиклипа «рука» мы назовем его « ArmColor» ). Наконец, установите имя экземпляра каждого из этих объектов ____Color на color . Теперь у каждой части тела должен быть цветной мувиклип.


Мы наконец добавляем окраску в наше приложение. Вот как должен выглядеть ваш проект в конце этого шага:

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
54
55
56
57
package
{
    import flash.display.Sprite;
    import flash.display.BitmapData
    import flash.events.Event;
    import flash.geom.ColorTransform;
    import flash.net.FileReference
    import flash.display.Loader
    import flash.display.Bitmap
    import flash.display.MovieClip
    import fl.controls.ColorPicker
    import flash.events.MouseEvent
     
    public class CustomCharacter extends Sprite
    {
        var myColorPicker:ColorPicker = new ColorPicker();
        var myChangedObject:MovieClip;
         
        public function CustomCharacter():void {
         
         
        myColorPicker.editable = true;
        myColorPicker.visible = false;
        addChild(myColorPicker);
         
        player.addEventListener(MouseEvent.CLICK, showPicker)
        myColorPicker.addEventListener(Event.CHANGE, colorChanged)
         
        }
         
        private function colorChanged(e:Event):void
        {
            myColorPicker.visible = false;
            var myChange:ColorTransform = new ColorTransform();
            myChange.color = new uint(«0x» + e.target.hexValue)
            myChangedObject.transform.colorTransform = myChange
        }
         
        private function showPicker(e:MouseEvent):void
        {
            if (e.target.name == «color») {
                myColorPicker.visible = !myColorPicker.visible
                myColorPicker.move(stage.mouseX, stage.mouseY)
                myChangedObject = MovieClip(e.target)
                myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)
            }
             
        }
         
         
         
         
    }
     
     
     
}

Скриншот приложения

Хорошо! Давайте пройдем этот шаг за шагом. Для начала мы создаем новую переменную MovieClip, myChangedObject , к которой наша программа будет обращаться. Это так, наша функция showPicker () может сообщить нашей функции colorChanged (), какой MovieClip был последний раз нажат.

Поскольку это не так, давайте посмотрим на нашу функцию showPicker () . Как вы можете видеть, мы добавили небольшую проверку, чтобы увидеть, является ли кликаемое имя объекта «цветным». Это всего лишь проверка, чтобы увидеть, действительно ли пользователь нажал на контур игрока, обувь или что-либо еще, что не должно быть изменено.

Затем мы изменяем нашу новую переменную myChangedObject, чтобы она стала равной нажатому объекту e.target , чтобы наша функция colorChanged () могла внести окончательные изменения. Наконец, мы говорим нашему ColorPicker ( myColorPicker )
предварительно выбранный ранее цвет. Если его нет, то по умолчанию он будет черным.

1
myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)

Давайте проанализируем этот маленький кусочек кода. Прежде всего, важно знать, что для того, чтобы иметь предварительно выбранный цвет, класс ColorPicker имеет переменную .selectedColor . Это число, которое может получить 6-значный int (0xRRGGBB). Во второй части мы конвертируем данные в скобках в uint для передачи в ColorPicker.

Вот ключ, мы по сути идем внутрь нашего выбранного MovieClip myChangedObject , переходим в его секцию преобразования (где хранятся наши данные), углубляемся в данные colorTransform данных преобразования и извлекаем переменную цвета, которая содержит наш код RGB (который затем мы передаем в качестве выбранного цвета палитры цветов). Думайте об этом как каталог:

myChangedObject / Данные преобразования / Данные преобразования цвета / Данные цвета (RGB)

Мы еще не закончили! Теперь давайте посмотрим на нашу функцию colorChanged () . Здесь мы создаем новый экземпляр класса ColorTransform . Затем мы устанавливаем переменную цвета внутри класса ColorTransform для цвета, выбранного пользователем с помощью палитры цветов.

Однако нам нужно добавить «0x» к выбранному цвету ColorPicker (e.target.hexValue), чтобы сформировать полную переменную, которую мы можем передать нашему ColorTransform . Это потому, что hexValue дает цвета в строковом формате «RRGGBB», а нам нужны они в целочисленном формате 0xRRGGBB. Как и раньше, мы конвертируем все добавленные данные в новый uint (), который ColorTransform может распознать.

И, наконец, мы возвращаемся к: myChangedObject.transform.colorTransform, за исключением этого времени, мы фактически изменяем переменную colorTransform на новую переменную ColorTransform, которую мы только что создали.

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


Теперь, когда у нас есть функциональное приложение для раскраски, давайте перейдем к добавлению функциональности.

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

Кроме того, это своего рода расширение из этого учебного пособия Карлоса Янеза , которое объясняет, как создать приложение для рисования.

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

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

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package
{
    import flash.display.Sprite;
    import flash.display.BitmapData
    import flash.events.Event;
    import flash.geom.ColorTransform;
    import flash.net.FileReference
    import flash.display.Loader
    import flash.display.Bitmap
    import flash.display.MovieClip
    import fl.controls.ColorPicker
    import flash.events.MouseEvent
     
    public class CustomCharacter extends Sprite
    {
        var myColorPicker:ColorPicker = new ColorPicker();
        var myChangedObject:MovieClip;
         
        public function CustomCharacter():void {
         
         
        myColorPicker.editable = true;
        myColorPicker.visible = false;
        addChild(myColorPicker);
         
         
        tools.bucket.visible = false;
        tools.pencil.visible = false;
         
        tools.bucket_btn.addEventListener(MouseEvent.CLICK,enableBucket)
        tools.pencil_btn.addEventListener(MouseEvent.CLICK, enablePencil)
         
         
        }
         
        private function enablePencil(e:MouseEvent):void
        {
             
        tools.bucket.visible = false;
        tools.pencil.visible = true;
        player.removeEventListener(MouseEvent.CLICK, showPicker)
        myColorPicker.removeEventListener(Event.CHANGE, colorChanged)
         
        }
         
        private function enableBucket(e:MouseEvent):void
        {
         
        tools.bucket.visible = true;
        tools.pencil.visible = false;
        player.addEventListener(MouseEvent.CLICK, showPicker)
        myColorPicker.addEventListener(Event.CHANGE, colorChanged)
         
         
        }
         
        private function colorChanged(e:Event):void
        {
            myColorPicker.visible = false;
            var myChange:ColorTransform = new ColorTransform();
            myChange.color = new uint(«0x» + e.target.hexValue)
            myChangedObject.transform.colorTransform = myChange
        }
         
        private function showPicker(e:MouseEvent):void
        {
            if (e.target.name == «color») {
                myColorPicker.visible = !myColorPicker.visible
                myColorPicker.move(stage.mouseX, stage.mouseY)
                myChangedObject = MovieClip(e.target)
                myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)
 
            }
             
        }
         
         
         
         
    }
     
     
     
}

Во-первых, вы можете видеть, что мы убрали слушателей событий showPicker и colorChanged , и теперь они только для
добавляется, когда мы выбираем параметры заливки. Вместо этого мы добавили два прослушивателя событий для каждой кнопки, которые ссылаются на две функции, которые активируют инструмент, на который мы нажали. Функции добавляют своих собственных слушателей событий и удаляют слушателей событий из другого инструмента. Они также делают правильные элементы интерфейса видимыми и невидимыми.

Наше новое приложение


Мы настроили интерфейс, но вопрос остается. Как мы можем выбрать, какой цвет рисовать для инструмента карандаша? Ответ прост. Мы можем просто переместить нашу палитру цветов рядом с инструментом карандаша. Это тоже довольно просто. Просто добавьте это в конец функции enablePencil () :

1
2
myColorPicker.visible = true
myColorPicker.move(515, 20);

Просто чтобы убедиться, что проигрыватель не использует ColorPicker при выборе инструмента корзины , мы можем просто добавить это в функцию enableBucket () :

1
myColorPicker.visible = false

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

В отличие от ранее, нам нужно будет дать каждой части тела имя экземпляра, поэтому вернитесь к фрагменту ролика игрока и выберите каждый объект один за другим. Дайте каждому объекту имя («arm1», «leg2», «hair» и т. Д.). Когда вы закончите, создайте массив в конструкторе CustomCharacter () следующим образом:

1
var drawableParts:Array = [player.arm1,player.arm2,player.leg1,player.leg2,player.head,player.shirt,player.hair];

К сожалению, это не работает, как планировалось.

1
2
TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at CustomCharacter()

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

По сути, мы разбиваем переменную на две части. Первая часть находится перед конструктором, когда мы создаем массив, чтобы он был доступен по всему классу. Второй — ВНУТРИ конструктора, когда мы можем присвоить ему значение.

Вот фрагмент нашего класса:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
public class CustomCharacter extends Sprite
{
    var myColorPicker:ColorPicker = new ColorPicker();
    var myChangedObject:MovieClip;
    var bucket:Boolean = false
    var drawableParts:Array
     
    public function CustomCharacter():void {
     
        drawableParts = [player.arm1,player.arm2,player.leg1,player.leg2,player.head,player.shirt,player.hair]
 
        myColorPicker.editable = true;
        myColorPicker.visible = false;
        addChild(myColorPicker);
         
         
        tools.bucket.visible = false;
        tools.pencil.visible = false;
         
        tools.bucket_btn.addEventListener(MouseEvent.CLICK,enableBucket)
        tools.pencil_btn.addEventListener(MouseEvent.CLICK, enablePencil)
    }

Чтобы рисовать в объекте, нам нужно использовать класс Shape . Сначала добавьте оператор импорта к другим
в начале нашего основного класса.

1
import flash.display.Shape;

Вот что вам нужно добавить в конец вашей функции конструктора CustomCharacter () :

1
for (var i:int = 0; i < drawableParts.length;i++ ) { var myShape:Shape = new Shape() myShape.graphics.lineStyle(1,0×330000);

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

Следующие четыре строки предназначены только для тестирования отладки, что-то вроде отладочной отрисовки Box2D. В основном это отображает фиолетовые рамки вокруг частей тела персонажа. Единственное, что нужно иметь в виду, это то, что мы умножаем ширину и высоту каждой части тела на 3, чтобы получить ширину и высоту нашего фиолетового испытательного бокса, так что мы знаем, что каждый из этих «холстов» будет достаточно большим, чтобы нарисовать на. Затем мы присваиваем имя «фигуры» каждому созданному Shape и добавляем его в текущий элемент массива drawableParts.


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

Зайди в волосы MovieClip. Щелкните правой кнопкой мыши на нашем цветном MovieClip и нажмите «Копировать». Затем щелкните правой кнопкой мыши на пустом месте внутри нашего MovieClip и нажмите «Вставить на месте». Теперь перейдите в свойства нашего нового MovieClip и установите имя экземпляра в maskclip . Теперь вернитесь к нашему игроку MovieClip и повторите это для каждого объекта.

Далее мы можем добавить этот код в конец нашего цикла for :

1
myShape.mask = drawableParts[i].maskclip

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


Теперь возникает вопрос: «Как мне получить доступ к холсту myShape каждой части тела?» К сожалению, ответ не так прост. Тем не менее, я могу провести вас через это шаг за шагом. Этот фрагмент напрямую свяжет нас с myShape, если мы вставим его в MouseEvent . Почему? Ну, просто продолжайте читать ..

1
e.target.parent.getChildByName(«shapes»)

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

  • Сначала мы идем к цели MouseEvent . Это может быть объект, который щелкнул мышью, отпустил, переместил и т. Д.
  • Далее мы идем к родителю этого объекта. Это обязательно должен быть фрагмент тела MovieClip (например, рука), потому что единственными объектами, по которым можно кликнуть, являются либо контур, либо заливка проигрывателя (позже мы обязательно убедимся, что это заливка).
  • Теперь, когда мы находимся в части тела MovieClip , мы можем использовать getChildByName («Имя объекта здесь») для доступа к объекту с заданным именем.

Поскольку ранее мы называли все наши объекты Shape как фигуры , вызов getChildByName («shape») даст нам доступ к ним.


Теперь мы можем начать рисовать игрока в черно-белом режиме.

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

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package
{
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.BitmapData
    import flash.events.Event;
    import flash.geom.ColorTransform;
    import flash.net.FileReference
    import flash.display.Loader
    import flash.display.Bitmap
    import flash.display.MovieClip
    import fl.controls.ColorPicker
    import flash.events.MouseEvent
     
    public class CustomCharacter extends Sprite
    {
        var myColorPicker:ColorPicker = new ColorPicker();
        var myChangedObject:MovieClip;
        var bucket:Boolean = false
        var drawableParts:Array
         
        //A boolean to check to see if the mouse is drawing
        var drawing:Boolean = false
         
        public function CustomCharacter():void {
            drawableParts = [player.arm1,player.arm2,player.leg1,player.leg2,player.head,player.shirt,player.hair]
            myColorPicker.editable = true;
            myColorPicker.visible = false;
            addChild(myColorPicker);
             
             
            tools.bucket.visible = false;
            tools.pencil.visible = false;
             
            tools.bucket_btn.addEventListener(MouseEvent.CLICK,enableBucket)
            tools.pencil_btn.addEventListener(MouseEvent.CLICK, enablePencil)
            for (var i:int = 0; i < drawableParts.length;i++ ) {
                var myShape:Shape = new Shape()
                 
                myShape.name = «shapes»
                 
                drawableParts[i].addChild(myShape)
                myShape.mask = drawableParts[i].maskclip
            }
        }
         
         
        private function enablePencil(e:MouseEvent):void
        {
            tools.bucket.visible = false;
            tools.pencil.visible = true;
            player.removeEventListener(MouseEvent.CLICK, showPicker)
             
            //Removing eventListener placed by our bucket tool
            myColorPicker.removeEventListener(Event.CHANGE, colorChanged)
             
            //Checks to see when our ColorPicker changes color while Pencil is selected
            myColorPicker.addEventListener(Event.CHANGE, colorChangedPencil)
             
            //Checks to see if the mouse is down, up, or moving
            player.addEventListener(MouseEvent.MOUSE_DOWN, drawOnPlayer)
            player.addEventListener(MouseEvent.MOUSE_UP, dontDrawOnPlayer)
            player.addEventListener(MouseEvent.MOUSE_MOVE, moveDrawOnPlayer)</b>
 
            myColorPicker.visible = true
            myColorPicker.move(515, 20);
        }
         
        //Function to check for movement of the mouse, while drawing
        private function moveDrawOnPlayer(e:MouseEvent):void
        {
            //If our mouse is hovering over the filling of the player and if we are indeed drawing
            if (e.target.name == «color» && drawing) {
                    //Draw a line from the graphical section of our shape movieclip to the location of the mouse
                    //We need to use ourCanvas.mouseX or mouseY because that gives us local coordinates of the mouse that our canvas can use
                    e.target.parent.getChildByName(«shapes»).graphics.lineTo(e.target.parent.getChildByName(«shapes»).mouseX,e.target.parent.getChildByName(«shapes»).mouseY);
            }
 
        }
         
        private function dontDrawOnPlayer(e:MouseEvent):void
        {
            //When you release the mouse, stop drawing
            drawing = false;
             
        }
 
        //new function
        private function drawOnPlayer(e:MouseEvent):void
        {
            //When you click, start drawing
            drawing = true;
             
            //If you are clicking on a «color» MovieClip
            if (e.target.name == «color» ) {
            //Set the size of the line to 10 and make it black (0x000000)
            e.target.parent.getChildByName(«shapes»).graphics.lineStyle(10, «0x000000»)
            //Move drawing point to where the mouse is at (see moveDrawOnPlayer() for more depth)
            e.target.parent.getChildByName(«shapes»).graphics.moveTo(e.target.parent.getChildByName(«shapes»).mouseX,e.target.parent.getChildByName(«shapes»).mouseY);
 
            }
 
        }
         
        private function enableBucket(e:MouseEvent):void
        {
            tools.bucket.visible = true;
            tools.pencil.visible = false;
            myColorPicker.visible = false
             
            //Remove bucket event listeners
            player.removeEventListener(MouseEvent.MOUSE_DOWN, drawOnPlayer)
            player.removeEventListener(MouseEvent.MOUSE_UP, dontDrawOnPlayer)
            myColorPicker.removeEventListener(Event.CHANGE, colorChangedPencil)
             
            player.addEventListener(MouseEvent.CLICK, showPicker)
 
            //See if our color has changed
            myColorPicker.addEventListener(Event.CHANGE, colorChanged)
             
            //Remove old event listeners
            player.removeEventListener(MouseEvent.MOUSE_DOWN, drawOnPlayer)
            player.removeEventListener(MouseEvent.MOUSE_UP, dontDrawOnPlayer)
            player.removeEventListener(MouseEvent.MOUSE_MOVE, moveDrawOnPlayer)
        }
         
        //Placeholder function for when our ColorPicker has chosen a new pencil color
        private function colorChangedPencil(e:Event):void
        {
             
        }
         
        private function colorChanged(e:Event):void
        {
            myColorPicker.visible = false;
            var myChange:ColorTransform = new ColorTransform();
            myChange.color = new uint(«0x» + e.target.hexValue)
            myChangedObject.transform.colorTransform = myChange
        }
         
        private function showPicker(e:MouseEvent):void
        {
            if (e.target.name == «color») {
                myColorPicker.visible = !myColorPicker.visible
                myColorPicker.move(stage.mouseX, stage.mouseY)
                myChangedObject = MovieClip(e.target)
                myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)
            }
             
        }
         
    }
     
}

Цель этого урока не в том, чтобы охватить рисование на объектах Shape. Это полностью описано в учебнике Карлоса . Прямо сейчас мы только изучаем методы рисования на правильном объекте. Если вы не понимаете, как мы получаем доступ к объекту правильной формы, перечитайте шаг 12, чтобы получить полное объяснение.


Теперь мы можем перейти к рисованию с цветом, выбранным из ColorPicker . Это очень похоже на процесс, который мы использовали в инструменте Bucket.

Давайте начнем с добавления новой переменной вне всех функций, но внутри класса. Это то, что наша программа будет использовать для хранения текущего цвета карандаша.

1
var pencilColor:String = «000000»;

Теперь давайте перейдем к нашей функции drawOnPlayer (). Сосредоточим ваше внимание на линии, которая устанавливает lineStyle () фигуры, на которой мы рисуем. Второй параметр в функции должен быть «0x000000». Измените ТОЛЬКО этот параметр на:

1
uint(«0x»+pencilColor)

По сути, это говорит о том, что для рисования используйте код RBG нашего ColorPicker , добавляя «0x», необходимый для завершения цвета.

Вот как должна выглядеть строка кода:

1
e.target.parent.getChildByName(«shapes»).graphics.lineStyle(10, uint(«0x»+pencilColor))

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

1
pencilColor = e.target.hexValue

Это просто присвоение hexValue или кода RBG нашего ColorPicker нашей переменнойcilColor.


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

Выберите все объекты внутри нашего Options MovieClip.

Удерживая клавишу Shift, нажмите левую клавишу, чтобы сдвинуть мувиклип влево.

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

Убедитесь, что изменили любые объекты на основе координат. Например, теперь нам нужно изменить местоположение ColorPicker карандаша, потому что наша кнопка Pencil Tool сместилась.

1
myColorPicker.move(440, 20);

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

Я буду использовать эту кнопку (это в FLA):

Поместите один в мувиклип инструментов и присвойте ему имя экземпляра «reset». Затем добавьте следующий слушатель события в нашу функцию конструктора:

1
tools.reset.addEventListener(MouseEvent.CLICK,resetEverything)

Теперь добавьте эту функцию обработчика событий в наш класс:

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
private function resetEverything(e:MouseEvent):void
{
    //Looping through all of the objects in our drawableParts array (all of our drawable objects)
    for (var i:int = 0; i < drawableParts.length; i++ ) {
         
        //Finding and removing our old <em>shapes</em> object
        drawableParts[i].removeChild(drawableParts[i].getChildByName(«shapes»));
         
        //Creating a new shape object
        var myShape:Shape = new Shape()
         
        //Giving our new canvas a name
        myShape.name = «shapes»
         
        //Adding our object
        drawableParts[i].addChild(myShape)
         
        //Masking our canvas to the object we are drawing on
        myShape.mask = drawableParts[i].maskclip
         
        //Finding the «color» MovieClip’s colorTransform property and resetting it to a new ColorTransform object
        drawableParts[i].getChildByName(«color»).transform.colorTransform = new ColorTransform()
     
    }
}

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


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

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

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

Здесь вы можете увидеть временную шкалу игрока MovieClip.

Теперь проверь фильм! Плеер должен быть анимированным. Вы можете попытаться нарисовать на ногах игрока, и если вы правильно следовали инструкциям, то при рисовании рисунок должен прилипать к ногам игрока и анимировать их. Я объясню, почему подробно чуть позже.


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

Для начала давайте добавим строку кода в наш конструктор, чтобы остановить анимацию игрока:

1
player.stop()

Далее нам нужно снова расширить нашу панель. Просто выполните Шаг 15 и сделайте панель немного длиннее

Теперь нам нужно добавить кнопку «Play animation». Как и другие элементы пользовательского интерфейса, моя кнопка похожа на переключатель. Когда вы нажимаете на него, он переключает видимость другого мувиклипа, чтобы придать кнопке видимость подсветки. Имя экземпляра кнопки — playgame, пока загорается название экземпляра MovieClip . Проверьте FLA или SWF предварительного просмотра, чтобы увидеть, как они сочетаются друг с другом.

Вот код, который нам нужно добавить, чтобы сделать эту работу … Сначала добавьте это в наш конструктор, чтобы отключить эффект освещения:

1
tools.playing.visible = false;

Затем добавьте этот EventListener в наш конструктор:

1
tools.playgame.addEventListener(MouseEvent.CLICK,enableGame)

Наконец, давайте создадим эту функцию в нашем классе. На данный момент этим занимаются только две вещи. Во-первых, это переключает нашу видимость MovieClip. Затем он проверяет, является ли мувиклип видимым. Если это так, запускается анимация нашего игрока . В противном случае он останавливает анимацию в первом кадре.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
private function enableGame(e:MouseEvent):void
{
    tools.playing.visible = !tools.playing.visible
     
    if (tools.playing.visible) {
         
        player.play()
    }
    else {
         
        player.gotoAndStop(1)
 
    }
}

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


Все выглядит хорошо, но что интересного в игре без взаимодействия с пользователем? На этом этапе мы собираемся добавить некоторую простую интерактивность в нашу игру. Для начала загрузите класс KeyObject от Senocular здесь . Это сделает нашу логику намного проще для написания.

Нам нужно быстро изменить класс. Откройте это. В первой строке замените:

1
package com.senocular.utils {

с:

1
package{

Теперь мы можем начать с импорта класса. Не забудьте поместить его в каталог нашего основного класса. Добавьте этот оператор импорта рядом с другими:

1
import KeyObject

Чтобы настроить класс KeyObject . Просто создайте новый ключ переменной следующим образом:

1
var key:KeyObject;

И назначьте его новому экземпляру класса KeyObject при добавлении в свойство Stage, например так:

1
key = new KeyObject(stage);

Либо вставьте эту строку кода в конструктор, либо, если это не сработает, добавьте эту строку в конструктор:

1
addEventListener(Event.ADDED_TO_STAGE, onAddToStage);

… а затем добавьте новую функцию для обработки этого события:

1
2
3
4
5
private function onAddToStage(e:Event):void
{
    removeEventListener(Event.ADDED_TO_STAGE, onAddToStage);
    key = new KeyObject(stage);
}

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

Далее нам нужно создать слушатель события ENTER_FRAME. Тем не менее, мы должны удалить его, когда мы закончим. Добавьте этот код в вашу функцию enableGame () :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
private function enableGame(e:MouseEvent):void
{
    tools.playing.visible = !tools.playing.visible
 
    if (tools.playing.visible) {
         
        player.play()
        addEventListener(Event.ENTER_FRAME, enterFrame);
         
    }
    else {
         
        player.gotoAndStop(1)
        removeEventListener(Event.ENTER_FRAME, enterFrame);
         
 
    }
}

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

Теперь вот наша функция enterFrame () :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private function enterFrame(e:Event):void
{
    //Checks with our key variable to check if the LEFT key is down
    //and that the character hasn’t gone off of the screen
    if (key.isDown(key.LEFT) && player.x > 0) {
         
        //Moves the player a bit
        player.x -= 5;
         
        //Flips the player backwards
        player.scaleX = -1
         
     
    }
    //Checks if the RIGHT key is down and the player hasn’t gone off the other side
    if (key.isDown(key.RIGHT) && player.x < 640) {
        //Moves the player a bit
        player.x += 5
         
        //Flips the player to normal
        player.scaleX = 1
    }
}

Проверьте свой SWF, нажимая левую и правую клавиши со стрелками.


Как вы, наверное, заметили, если у нас активирован инструмент карандаша и мы заставляем игрока двигаться, наш ColorPicker продолжает открываться. Вот быстрое и грязное решение для этого! Просто внесите закомментированные изменения в вашу функцию enableGame () :

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
private function enableGame(e:MouseEvent):void
{
    tools.playing.visible = !tools.playing.visible
 
    if (tools.playing.visible) {
         
        player.play()
        addEventListener(Event.ENTER_FRAME, enterFrame);
         
        //New code: Moving the ColorPicker WAAAYYYY to the right
        myColorPicker.x = 10000;
    }
    else {
         
        player.gotoAndStop(1)
        removeEventListener(Event.ENTER_FRAME, enterFrame);
         
        //New code: Checks to see if the pencil tool is active…
        if (tools.pencil.visible) {
            //Moves the ColorPicker back to where it used to be
            myColorPicker.x = 440
        }
 
    }
}

Нам не нужно ничего делать с инструментом корзины, потому что он уже перемещает ColorPicker к местоположению мыши.


Как видите, создать уникальный опыт настройки не так сложно. На самом деле, это очень хороший способ позволить игроку сделать своего аватара или персонажа «его». Поистине, мы только что просмотрели параметры настройки, доступные во Flash. Посмотрите, что еще вы можете придумать!