Вы когда-нибудь были поражены разнообразием атак в файтингах, таких как Mortal Kombat, Super Smash Bros, Soul Calibur и других? Теперь вы можете узнать, как создать движок для определения комбинаций клавиш, а также создать свою собственную игру-файтинг!
Окончательный результат предварительного просмотра
Давайте посмотрим на конечный результат, к которому мы будем стремиться:
Комбинации в этой демонстрации: ASDF
, AAA
и SSS
. Введите их!
Шаг 1: Введение
Вы когда-нибудь хотели создать файтинг (или любой другой жанр) с множеством комбо? В этом уроке мы создадим простой класс для обнаружения комбинаций клавиш и сообщим нам, когда пользователь сделал комбо. Мы также создадим очень простой графический интерфейс, чтобы мы могли протестировать наш класс.
Шаг 2: Начало нового проекта
Для этого урока мы будем использовать чистый проект AS3 FlashDevelop с preloader. Мы создадим проект с предварительным загрузчиком, чтобы вам было проще, если вы хотите продолжать работать над конечным результатом игры. Начнем с открытия FlashDevelop и выбора нашего проекта:
С этим мы можем начать работать над нашими классами.
Чтобы использовать графику, которую мы создадим во Flash Pro в рамках нашего проекта AS3, нам нужно экспортировать наши изображения из файла .fla в формат .swc. Более подробную информацию об этом формате можно найти в Варианте 2 этого руководства по FlashDevelop . Создайте новый FLA AS3 во Flash Professional, затем измените настройки в нашем файле .fla, чтобы экспортировать его содержимое в формат .swc: перейдите в « Файл»> «Параметры публикации» (или нажмите Ctrl + Shift + F12) и выберите «Экспорт SWC» поле под вкладкой «Flash».
Если у вас нет Flash Professional, не беспокойтесь. Я включил окончательный файл SWC в пакет загрузки для этого урока. Загрузите его, затем перейдите к шагу 6.
Шаг 3: Основная форма кнопки
Сначала мы создадим всю графическую часть, а потом будем заботиться только о коде. Поскольку мы будем иметь дело с комбинациями клавиш, давайте создадим кнопку с буквой в ней для обозначения ключа. Наша кнопка будет очень простой: три круга разных цветов и несколько фильтров в ней. Вот как я построил свой: большой серый круг с белым кругом сверху и красный круг поверх белого. После этого я применил свечение и два фильтра тени на красном круге, чтобы получить окончательный результат, который включен в исходные файлы.
Для получения более подробной информации о том, как была создана кнопка, найдите исходные файлы для этого урока!
Шаг 4: вверх и вниз изображения
Теперь мы должны дать нашей кнопке «вверх» и «вниз» изображения. Прежде чем сделать это, нам нужно превратить его в символ. Давайте преобразуем его в символ, дадим ему имя KeyButtonImage
и экспортируем как SWCAssets.KeyButtonImage. Мы добавляем пакет SWCAssets
в имя класса для организационных целей, когда начинаем кодирование. Это будет более ясно позже.
На нашем KeyButtonImage
давайте создадим еще один ключевой кадр с таким же изображением первого, а затем изменим угол наклона фильтров, которые мы используем на красном круге. Нам также необходимо пометить наши фреймы, чтобы идентифицировать их в нашем коде, поэтому первый фрейм помечается как «Вверх», а второй — как «Вниз». Изображение внизу должно выглядеть так:
Шаг 5: Генерация .swc файла
Теперь, когда у нас есть готовое изображение кнопки, пришло время сгенерировать наш файл .swc и добавить его в наш проект FlashDevelop. Для публикации нажмите Alt + Shit + F12. Вы заметите, что файл .swc был создан в том же каталоге флэш-файла. Скопируйте этот файл и поместите его в папку «lib» нашего проекта FlashDevelop. Щелкните правой кнопкой мыши и выберите «Добавить в библиотеку», чтобы FlashDevelop распознал файл. Имя файла станет синим после его добавления в библиотеку.
FlashDevelop теперь готов начать использовать изображение нашей кнопки!
Шаг 6: Наш класс KeyButton
Наше изображение готово, поэтому нам нужно создать класс для хранения изображения и добавить к нему функциональные возможности. В FlashDevelop добавьте новый класс в папку src, назовите его KeyButton
и поместите flash.display.Sprite в качестве базового класса.
Шаг 7: Добавление изображения
Поскольку наш класс KeyButton
наследуется от класса Sprite, он может добавлять изображения в свой дочерний список отображения. На этом шаге мы добавим изображение в наш класс и поместим в него текст письма. Давайте перейдем к коду:
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
|
package
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import SWCAssets.KeyButtonImage;
public class KeyButton extends Sprite
{
private var _image:KeyButtonImage;
private var _text:TextField;
public function KeyButton(letter:String)
{
_image = new KeyButtonImage();
_image.stop();
addChild(_image);
_text = new TextField();
_text.defaultTextFormat = new TextFormat(«Verdana», 28, 0xFFFFFF, true, null, null, null, null, TextFormatAlign.CENTER);
_text.text = letter;
_text.height = 38;
_text.x = -(_text.width / 2);
_text.y = -(_text.height / 2);
_text.mouseEnabled = false;
addChild(_text);
}
}
}
|
В строках 11 и 13 мы объявляем переменные, которые будут содержать изображение нашей кнопки и текст письма соответственно. В конструкторе нашего класса (строка 15) мы запрашиваем строку, которая будет буквой нашей кнопки.
Так как наш KeyButtonImage
имеет два фрейма, в строке 18 мы вызываем метод stop()
чтобы остановить его цикл по ним. Мы определим конкретные моменты для изображения, чтобы переключать кадры позже. Строка 20 добавляет изображение в дочерний список кнопки.
От строки 22 до строки 30 мы создаем наше текстовое поле, которое будет содержать букву, позиционируем ее и отключаем от событий мыши (не обязательно, но хорошо, если предполагается, что ваше текстовое поле должно делать только отображение текста). Строка 32 добавляет текст в дочерний список кнопки.
Шаг 8: Создание объектов изображения
Наш класс KeyButton
уже может показывать изображение и представлять букву, поэтому на этом шаге мы добавим несколько кнопок на экран. Поскольку мы создаем только пример для проверки нашего класса, мы не будем добавлять все буквы в этом примере. Вместо этого мы будем работать только с 4 буквами (но наш класс сможет определять комбинации с любыми клавишами!): A, S, D и F. Теперь мы добавим их на наш экран:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
|
private var keyButtons:Array = [];
private var keys:Array = [«A», «S», «D», «F»];
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var i:int;
for (i = 0; i < 4; i++)
{
keyButtons[i] = new KeyButton(keys[i]);
KeyButton(keyButtons[i]).x = 100 + (100 * i);
KeyButton(keyButtons[i]).y = 50;
addChild(KeyButton(keyButtons[i]));
}
}
|
В строке 1 создается массив, содержащий все кнопки на нашем экране. Это будет очень полезно позже, потому что это позволит нам проходить по массиву вместо проверки кнопка за кнопкой. Строка 2 только определяет, с какими ключами мы будем работать (как сказано, A, S, D и F). Строки 12-16 находятся внутри цикла, который создаст 4 кнопки и разместит их на экране.
Теперь вы можете скомпилировать проект и увидеть кнопки на экране:
Шаг 9: Создание класса ComboHandler
Теперь мы готовы начать работу по обнаружению комбо. Для этого мы создадим класс ComboHandler
. Просто выполните те же шаги, которые вы сделали для создания класса KeyCombo
, но на этот раз наш класс ComboHandler
не будет иметь базового класса.
Какой должна быть первая часть класса ComboHandler
? Что ж, сначала нам нужно определить, когда была нажата клавиша. Чтобы сделать это, нам нужно добавить прослушиватель событий на сцену (помните: как предложено в ссылке на ActionScript 3 , чтобы глобально прослушивать прослушиватели событий KeyboardEvent
, их нужно добавить на сцену!
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
package
{
import flash.display.Stage;
import flash.events.KeyboardEvent;
public class ComboHandler
{
public static function initialize(stageReference:Stage):void
{
stageReference.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
private static function onKeyDown(e:KeyboardEvent):void
{
}
}
}
|
Этот код только строит базовую структуру класса ComboHandler
. Гораздо больше будет добавлено позже! Обратите внимание, что мы использовали только статические методы. Это потому, что в нашем примере у нас будет только один класс ComboHandler
. Некоторые предложения по улучшению этого класса доступны на заключительном этапе.
Наш класс ComboHandler
должен быть инициализирован с помощью метода initialize()
для добавления слушателя на сцену. В нашем Main
классе мы должны инициализировать класс перед работой с ним. Давайте отправимся на Main.as и сделаем это:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var i:int;
for (i = 0; i < 4; i++)
{
keyButtons[i] = new KeyButton(keys[i]);
KeyButton(keyButtons[i]).x = 100 + (100 * i);
KeyButton(keyButtons[i]).y = 50;
addChild(KeyButton(keyButtons[i]));
}
ComboHandler.initialize(stage);
}
|
Шаг 10: Регистрация комбо
У нас есть базовая структура класса ComboHandler
, поэтому теперь нам нужно добавить что-то к нему. Первым делом нужно зарегистрировать комбо в классе, чтобы он мог обнаружить комбо.
Теперь, как мы будем хранить комбо в этом классе? Возможно, вы слышали о классе словаря . Этот класс может содержать любое значение на основе ключа. В нашем классе ключи будут именами комбо, а значение будет массивом, причем каждый индекс является ключом комбо. Код для этого (поясняется ниже):
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
private static var combos:Dictionary;
public static function initialize(stageReference:Stage):void
{
combos = new Dictionary();
stageReference.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
public static function registerCombo(comboName:String, comboKeys:Array):Boolean
{
if (combos[comboName])
{
return false;
}
combos[comboName] = comboKeys;
return true;
}
|
В строке 1 мы создаем словарь, о котором мы говорили. Строка 5 инициализирует его, а функция registerCombo()
регистрирует комбо в словаре. Эта функция вернет true
если комбо было успешно зарегистрировано, или false
если в классе уже была комбо с таким именем (в этом случае вам может потребоваться удалить старую комбо — см. Шаг 19!).
Шаг 11: Регистрация нажатой клавиши и установка интервала времени
Еще одна вещь, которую должен иметь наш класс, — это максимальный интервал между нажатиями клавиш. В некоторых играх, в которых есть комбо, вы, вероятно, заметили, что когда вы нажимаете, например, клавишу A, подождите секунду и нажмете клавишу B (при условии, что есть комбинация «AB»), комбо не будет обнаружено, потому что вы тоже ждали много, чтобы нажать клавишу B. Это происходит потому, что между каждым нажатием клавиши существует максимальный интервал времени. Это именно то, что мы будем делать в нашем классе. Итак, в классе ComboHandler
:
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 static var pressedKeys:Array;
private static const MAX_INTERVAL:int = 250;
private static var interval:int;
public static function initialize(stageReference:Stage):void
{
combos = new Dictionary();
interval = 0;
stageReference.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
private static function onKeyDown(e:KeyboardEvent):void
{
if (getTimer() — interval > MAX_INTERVAL)
{
pressedKeys = [];
}
interval = getTimer();
pressedKeys.push(e.keyCode);
}
|
В строке 1 мы создаем массив с pressedKeys
. Этот массив будет содержать все клавиши, нажатыми пользователем, с интервалом времени между двумя клавишами меньше, чем максимальный интервал.
Строки 3 и 4 определяют константу MAX_INTERVAL
, которая будет нашим максимальным интервалом, и переменную interval
, которая поможет нам вычислить, каково было время интервала между двумя нажатиями клавиш.
Функция onKeyDown()
уже почти завершена: в ней мы сначала обнаруживаем, превышает ли интервал между текущим нажатием клавиши и последним нажатием клавиши максимальный интервал. Если это так, то мы сбрасываем наш массив pressedKeys
, чтобы удалить все ключи, которые были в нем. После этого мы обновляем переменную интервала до текущего времени (см. Документацию getTimer () для получения более подробной информации о том, как мы вычисляем интервал) и push()
текущую клавишу в массиве pressedKeys
.
Шаг 12: Проверка, было ли выполнено комбо или нет
В функции onKeyDown()
нашего ComboHandler
отсутствует последняя вещь: возможность проверить, был ли после нажатия клавиши комбо выполнено пользователем. Вот что мы будем делать сейчас:
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
|
private static function onKeyDown(e:KeyboardEvent):void
{
if (getTimer() — interval > MAX_INTERVAL)
{
pressedKeys = [];
}
interval = getTimer();
pressedKeys.push(e.keyCode);
checkForCombo();
}
private static function checkForCombo():void
{
var i:int;
var comboFound:String = «»;
for (var comboName:String in combos)
{
if (pressedKeys.join(» «).indexOf((combos[comboName] as Array).join(» «)) > -1)
{
comboFound = comboName;
break;
}
}
// Combo Found
if (comboFound != «»)
{
pressedKeys = [];
}
}
|
Строка 12 — единственное изменение, которое мы сделали в нашей функции onKeyDown()
: вызов функции checkForCombo()
. Это проверит, была ли выполнена комбо или нет.
Способ проверки выполнения комбо очень интересен: мы работаем со строками. Работа со строками, в этом случае, позволяет нам обнаруживать вещи, которые были бы сложнее, не работая с ними. Например, представьте, если у нас есть комбинация с ключами ASDF, но массив pressedKeys
имеет следующую последовательность ключей: ASFDASDF. Даже если пользователь нажал первые четыре клавиши («ASFD», которые не соответствуют комбо) в течение срока, это не должно изменить тот факт, что пользователь выполнил комбо, как указано последними 4 ключи («ASDF»). Без струн наша работа могла бы быть намного дольше.
Идея работы со строками заключается в следующем: мы помещаем все ключи в pressedKeys
внутри строки, разделяя каждый индекс пробелом (таким образом, pressedKeys.join(" ")
функция pressedKeys.join(" ")
), затем проверяем, есть ли в ней определенная подстрока , Эта конкретная подстрока является строкой, образованной ключами комбо, также каждый ключ отделяется пробелом. Если эта подстрока найдена, это означает, что комбо было выполнено.
Вы можете проверить это самостоятельно с помощью следующего кода:
1
2
|
pressedKeys = [«A», «S», «F», «D», «A», «S», «D», «F»];
checkForCombo();
|
… хотя вы также захотите добавить временный вызов trace(comboFound)
в checkForCombo()
чтобы увидеть результат.
Обратите внимание, однако, что этот метод не будет работать во всех случаях. Это не сработает, если вместо массива Strings у нас будет, например, массив объектов. Если бы у нас был массив Object, функция toString () по умолчанию, которая вызывается при вызове join (), выдает «[object Object]», и, следовательно, все наши объекты в массиве будут «одинаковыми» в созданной строке. , Если вы все еще хотите это сделать, просто переопределите стандартную функцию toString () и поместите туда собственный текст. На шаге 14 мы сделаем это в классе ComboEvent — посмотрите на него для справки!
Теперь мы перестанем фокусироваться на классе ComboHandler
и снова поработаем над созданными нами кнопками. (Удалите тестовый код, который вы только что добавили.)
Шаг 13: заставляем наши кнопки действовать на ключевое событие
В настоящее время наши кнопки находятся на экране, но они ничего нам не показывают. Возможно, вы помните, что мы создали два изображения кнопок: одно — когда кнопка не нажата, а другое — когда она нажата. На этом шаге мы заставим наши кнопки вести себя при нажатии клавиши. Давайте KeyButton
к нашему классу KeyButton
:
1
2
3
4
5
6
7
8
9
|
public function onUp():void
{
_image.gotoAndStop(«Up»);
}
public function onDown():void
{
_image.gotoAndStop(«Down»);
}
|
Обратите внимание, что этот код изменяет только кадры изображения кнопки. Нам по-прежнему нужно вызывать их, когда нажата соответствующая клавиша. Мы сделаем это в Main.as:
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
|
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var i:int;
for (i = 0; i < 4; i++)
{
keyButtons[i] = new KeyButton(keys[i]);
KeyButton(keyButtons[i]).x = 100 + (100 * i);
KeyButton(keyButtons[i]).y = 50;
addChild(KeyButton(keyButtons[i]));
}
ComboHandler.initialize(stage);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
}
private function onKeyDown(e:KeyboardEvent):void
{
var i:int;
for (i = 0; i < 4; i++)
{
if (String.fromCharCode(e.keyCode) == keys[i])
{
KeyButton(keyButtons[i]).onDown();
break;
}
}
}
private function onKeyUp(e:KeyboardEvent):void
{
var i:int;
for (i = 0; i < 4; i++)
{
if (String.fromCharCode(e.keyCode) == keys[i])
{
KeyButton(keyButtons[i]).onUp();
break;
}
}
}
|
Строки 18 и 19 являются единственными дополнениями к функции init()
. Они добавляют больше слушателей событий на сцене, чтобы определить, когда клавиша была нажата и когда клавиша была отпущена. Мы будем использовать этих двух слушателей, чтобы сообщить нашим кнопкам, должны ли они быть вверх или вниз.
Единственное, что вы, возможно, никогда не видели в onKeyDown()
и onKeyUp()
функция String.fromCharCode()
. Эта функция возвращает строку с кодами символов, которые вы передаете в качестве аргументов. Поскольку мы передаем только один код символа, эта функция будет возвращать строку только с одним символом, и если она соответствует строкам, которые есть в массиве ключей, это означает, что мы должны сказать соответствующей кнопке действовать.
Теперь вы можете проверить кнопки, идущие вверх и вниз!
Шаг 14: Создание пользовательского комбо-события
Прямо сейчас наш класс ComboHandler
обнаруживает нажатия клавиш, обрабатывает интервалы времени, проверяет, когда были выполнены комбо, но он все еще не действует, когда комбо было выполнено. Как это может сказать другим вещам, что комбо было сделано? Это то, что мы начнем здесь. Поскольку Flash имеет очень сильную систему событий, мы отправим событие, когда будет обнаружен комбо, и позволим другим объектам получать эти события.
Для получения дополнительной информации о пользовательских событиях, пожалуйста, перейдите по этой ссылке на 8bitrocket . Создайте класс ComboEvent
с этим кодом в нем:
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
|
package
{
import flash.events.Event;
public class ComboEvent extends Event
{
public static const COMBO_FINISHED:String = «comboFinished»;
public var params:Object;
public function ComboEvent(type:String, params:Object, bubbles:Boolean = false, cancelable:Boolean = false)
{
super(type, bubbles, cancelable);
this.params = params;
}
public override function clone():Event
{
return new ComboEvent(type, this.params, bubbles, cancelable);
}
public override function toString():String
{
return formatToString(«ComboEvent», «params», «type», «bubbles», «cancelable»);
}
}
}
|
В строке 9 мы объявляем переменную params
. Он будет содержать информацию о выполненном комбо (в этом примере мы будем указывать только имя, но вы можете указать все, что захотите). Обратите внимание на функцию clone()
в классе. Он создан для того, чтобы повторно отправленные события могли содержать ту же информацию, что и исходное событие. Для получения дополнительной информации об этом, посетите этот пост в блоге на Бит 101
Шаг 15: отправка события, когда комбо было выполнено
Теперь в нашем классе ComboHandler
пришло время действовать, когда комбо было выполнено. Для этого нам нужно отправить ComboEvent
. События могут отправляться только объектами, которые наследуются от EventDispatcher
, но ComboHandler
не наследуется от EventDispatcher
. Вместо того, чтобы наследовать его от EventDispatcher
(что заставило бы нас иметь экземпляр ComboHandler
, который нам не нужен для целей этого урока), мы создадим объект EventDispatcher
в классе и сделаем этот объект событиями отправки. Кроме того, другие классы будут прослушивать этот объект для событий. В нашем файле ComboHandler.as:
Импортируйте это:
1
|
import flash.events.EventDispatcher;
|
И добавьте этот код:
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
|
public static var dispatcher:EventDispatcher;
public static function initialize(stageReference:Stage):void
{
combos = new Dictionary();
interval = 0;
dispatcher = new EventDispatcher();
stageReference.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
}
private static function checkForCombo():void
{
var i:int;
var comboFound:String = «»;
for (var comboName:String in combos)
{
if (pressedKeys.join(» «).indexOf((combos[comboName] as Array).join(» «)) > -1)
{
comboFound = comboName;
break;
}
}
// Combo Found
if (comboFound != «»)
{
pressedKeys = [];
dispatcher.dispatchEvent(new ComboEvent(ComboEvent.COMBO_FINISHED, {comboName: comboFound} ));
}
}
|
В строке 1 мы объявляем наш диспетчерский объект. В строке 9 мы его инициализируем. В строке 34 мы отправляем ComboEvent
. И это все для класса ComboHandler
. Теперь нам нужно послушать событие, которое отправляется.
Шаг 16: Проверка на событие в Main
Проверка пользовательских событий выполняется точно так же, как вы работаете с любым другим событием в AS3: добавьте прослушиватель в диспетчер и создайте функцию, которая будет что-то делать, когда прослушиватель получает событие. Наш Main
класс должен быть тем, кто получит событие, потому что он покажет что-то на экране, когда обнаружена комбо.
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
|
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var i:int;
for (i = 0; i < 4; i++)
{
keyButtons[i] = new KeyButton(keys[i]);
KeyButton(keyButtons[i]).x = 100 + (100 * i);
KeyButton(keyButtons[i]).y = 50;
addChild(KeyButton(keyButtons[i]));
}
ComboHandler.initialize(stage);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
ComboHandler.dispatcher.addEventListener(ComboEvent.COMBO_FINISHED, onComboComplete);
}
private function onComboComplete(e:ComboEvent):void
{
}
|
ComboHandler
строка — это место, где мы добавляем слушателя в ComboHandler
.
Шаг 17: сделай что-нибудь, когда комбо было сделано
В этом уроке мы будем просто отображать текст на экране с названием комбо, которое было выполнено. Нам понадобится текстовое поле на экране, и нам нужно будет получить название комбо, которое было выполнено.
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
|
private var textField:TextField;
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var i:int;
for (i = 0; i < 4; i++)
{
keyButtons[i] = new KeyButton(keys[i]);
KeyButton(keyButtons[i]).x = 100 + (100 * i);
KeyButton(keyButtons[i]).y = 50;
addChild(KeyButton(keyButtons[i]));
}
ComboHandler.initialize(stage);
textField = new TextField();
textField.defaultTextFormat = new TextFormat(«Verdana», 20, 0x000000, true);
textField.x = 100;
textField.y = 200;
textField.width = 350;
textField.text = «No combo»;
addChild(textField);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
ComboHandler.dispatcher.addEventListener(ComboEvent.COMBO_FINISHED, onComboComplete);
}
private function onComboComplete(e:ComboEvent):void
{
textField.text = e.params.comboName;
}
|
Строка 1 содержит объявление текстового поля, которое мы будем использовать. Строки 20-27 содержат инициализацию текстового поля. В нашей функции onComboComplete()
мы помещаем только комбо-имя в текст текстового поля. Это оно! Теперь осталось только зарегистрировать несколько комбо и протестировать класс!
Шаг 18: Регистрация комбо и тестирование
В файле Main.as давайте зарегистрируем несколько комбинаций: я зарегистрирую «AAA Combo», «SSS Combo» и «ASDF Combo». Вы можете зарегистрировать столько комбо, сколько захотите!
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
|
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var i:int;
for (i = 0; i < 4; i++)
{
keyButtons[i] = new KeyButton(keys[i]);
KeyButton(keyButtons[i]).x = 100 + (100 * i);
KeyButton(keyButtons[i]).y = 50;
addChild(KeyButton(keyButtons[i]));
}
ComboHandler.initialize(stage);
ComboHandler.registerCombo(«AAA Combo», [65, 65, 65]);
ComboHandler.registerCombo(«SSS Combo», [83, 83, 83]);
ComboHandler.registerCombo(«ASDF Combo», [65, 83, 68, 70]);
textField = new TextField();
textField.defaultTextFormat = new TextFormat(«Verdana», 20, 0x000000, true);
textField.x = 100;
textField.y = 200;
textField.width = 350;
textField.text = «No combo»;
addChild(textField);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
ComboHandler.dispatcher.addEventListener(ComboEvent.COMBO_FINISHED, onComboComplete);
}
|
Скомпилируйте проект и вот что вы получите:
Шаг 19: удаление комбо из списка комбо
Что если мы хотим удалить зарегистрированное комбо? Следующая функция может быть добавлена в файл ComboHandler.as для сброса положения словаря комбо по умолчанию. Он вернет true, если комбо было удалено, и false, если это не так (не было зарегистрировано комбо с таким именем).
01
02
03
04
05
06
07
08
09
10
11
|
public static function removeCombo(comboName:String):Boolean
{
if (combos[comboName])
{
combos[comboName] = undefined;
return true;
}
return false;
}
|
Вывод
Что ж, поздравляю с окончанием этого урока! Вы готовы реализовать базовый комбо-обработчик для ваших игр!
Однако базовый комбо-обработчик подходит не для всех игр. Что, если вы хотите использовать игру, в которой есть разные персонажи, и у каждого персонажа есть свои комбинации, и вам нужен больший контроль над обработчиками? Вы можете легко это сделать, если разрешите создание экземпляров класса ComboHandler
, что останется для вас проблемой.
Вы также можете превратить этот класс в Singleton , вместо того, чтобы иметь только статические функции. Есть много других творческих применений для этого, в том числе регистрация слов в качестве комбо и проверка, набрал ли кто-то слово или нет.
У вас было творческое использование для этого класса? Поделитесь этим с нами в разделе комментариев!