94. [game] Битовая маска в играх

Game – Серия статей посвященных разработке flash-игр на языке ActionScript. Игры для соц.сетей и мобильных платформ iOS, Android.
http://flashpress.ru/blog/category/game/

Если вы занимаетесь разработкой клиент серверных приложений, например онлайн игр, наверняка вам будет полезно знать о такой замечательной сущности как Битовая маска. Если вы знаете для чего нужны битовые маски, но не очень хорошо понимаете как их создавать и модифицировать, можете пропустить вводный абзац и переходить сразу к делу. Если же словосочетание Битовая маска у вас ассоциируется с игрой Мафия, читайте дальше… Давайте рассмотрим простой пример: вы разрабатываете по-ходовую онлайн игру, вроде Герои Меча и Магии. В игре есть различные магические артефакты, которые могут иметь различные флаги(свойства), например:

  • myStep:Boolean – Артефакт можно использовать только когда мой ход
  • targetMe:Boolean – Артефакт можно использовать только на себя
  • targetOpponent:Boolean – Артефакт можно использовать только на оппонента
  • aoe:Boolean – Артефакт наносит урон выбранной цели и всем рядом стоящим в радиусе

Конечно вы можете передавать от сервера во флешку все эти параметры(myStep, targetMe, targetOpponent, aoe…), но это не очень удобно, дак и к тому же, если передавать от сервера во флешку большое количество таких предметов, объем трафика может существенно вырасти. Что бы этого не произошло, все эти параметры(сколько угодно много) можно передавать в виде одного числа. Да да, именно одного числа. Как это сделать – читайте дальше.

Немного теории чисел в двоичном формате

Как вы знаете, любое число можно преобразовать в двоичный формат. Сделать это можно с помощью метода num.toString(2), например число 9 в двоичном формате будет выглядеть так: 1001:

Давайте разберем строку 1001: циферки 0 и 1 в данном случае называются битами. Нумерация битов начинается справа налево. Например первый(старший) бит равен 1, второй равен 0 и т.д. Для работы с битами существуют три основных оператора:

  • & : Побитовое И (AND)
  • | : Побитовое ИЛИ (OR)
  • ^ : Побитовое Исключающее ИЛИ (XOR)
  • ~ : Побитовое НЕ (NOT)

При использовании этих операторов, сравниваются каждый соответствующий бит. Если использовать оператор AND, результирующим битом будет 1 если оба сравниваемых бита равны 1. В случае OR, результат будет 1 в том случае, если хотя бы один из сравниваемых битов равен 1. При использовать оператора XOR, все немного сложнее. Попробую объяснить как работает XOR: берем все битовые единицы числа справа, а затем инвертируем (т.е. меняем 1 на 0, а 0 на 1) все соответствующие биты числа слева. Примеры действие побитовых операций можно посмотреть в таблице:


13 =

4 =

4 =

1101
AND
0100
↓↓↓↓
0100

9 =

2 =

11 =

1001
OR
0010
↓↓↓↓
1011

13 =

4 =

9 =

1101
XOR
0100
↓↓↓↓
1001

9 =

4 =

13 =

1001
XOR
0100
↓↓↓↓
1101

Оператор NOT просто заменяет все единицы на нули, и все нули на единицы. Стоит немного остановиться на операторе NOT, т.к. его результат может показаться немного не логичным. Рассмотрим пример:

Результат получается отрицательным потому что у числа 1101 впереди стоят много нулей: 0000000000000001101, и при операции NOT, все эти нули превращаются в единицы, в итоге мы получаем переполнение типа данных, и результат операции NOT дает отрицательное значение. Если присмотреться внимательно, то результат выполнения NOT для числа num можно найти по формуле -(num+1) .

Создаем битовую маску

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

В качестве флагов необходимо использовать степень двойки, т.е. числа 1, 2, 4, 8, 16, 32 и т.д. В предыдущем классе, мы записали в константы степени двойки в шестнадцатеричной форме: 0×1, 0×2, 0×4, 0×8, 0×10, 0×20, 0×40 т.д. Вы можете писать так, как вам удобно, принципиальной разницы нет, главное что бы значения флагов были степенью двойки.

Теперь для того что бы создать маску, которая будет хранить информацию о том, что артефакт можно использовать только в моем ходе(MY_STEP), только на оппонента(TARGET_OPPONENT) и он будет действовать в радиусе(AOE), можно воспользоваться следующим кодом:

Добавить флаг можно и в уже созданную маску:

Как видите у нас получилось число 13, которое в себе содержит информацию обо всех свойствах заданных в классе ArtFlags. Это число например можно сформировать на сервере и передавать во Flash-приложение. Что бы в коде ActionScript получить значения этих свойст, необходимо использовать оператор AND, следующим образом:

Если необходимо анулировать флаг, воспользуйтесь следующим кодом:

Для инвертирования значения свойства, т.е. если необходимо поменять true на false, а false на true, используйте оператор XOR:

Да прeбудет с вами Flash.
Serious Sam
Эту статью прочитали 1584 раз

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

Присоединяйтесь к нам в социальных сетях: ВКонтакте , Twitter и Facebook
Понравилась статья? Буду благодарен если вы поделитесь ссылкой с друзьями:


Комментарии ВКонтакте:




Комментарии Facebook:




Комментарии WordPress: