Работа с maskBits и categoryBits в box2d

Когда начинал работать с box2d, и возникла потребность фильтровать контакты, некоторое время не мог вкурить что же это за маскбиты такие, и как с ними обращаться.
В статье расскажу для новичков об этом, а так-же самый удобный способ работы с маскбитами, который смог придумать. (версия box2d 2.1a)

1) как работают maskBits и categoryBits:

чтоб это понять, надо представить эти числа в двоичном виде, нарпимер у нас есть тело1, у которого maskBits = 00000011
тогда это тело будет контактировать со всеми телами, у которых есть хоть одна единичка в categoryBits на том месте, где у тела1 в maskBits тоже единичка.

по умолчанию categoryBits = 1, а maskBits полон единичек, поэтому все тела контактируют со всеми.

2) как назначить:


        fixtureDef.filter.maskBits = 0xFF;
        fixtureDef.filter.categoryBits = 1;



3) как сделать работу с масками удобней.

сначала сделать класс, в котором прописаны константы категорий:

package {

        public class Groups {

                public static const static_category:uint = 1;  //1
                public static const player_category:uint = 2;  //10
                public static const enemy_category:uint = 4;  //100
                public static const neutral_category:uint = 8; //1000
                public static const bullet_category:uint = 16; //10000

        }
}



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

        //тело будет контактировать с телами категорий "статика" и "враги"
        fixtureDef.filter.maskBits = Groups.static_category + Groups.enemy_category
        //категория тела - игрок
        fixtureDef.filter.categoryBits = Groups.player_category;



всё, если кто расскажет как сделать еще удобней, будет здорово :))

Комментарии (7)

0
По идее так оно задумано. Ну разве что никто не мешает одно тело в несколько категорий поместить.

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

Если по быстрому надо что-то сделать, то можно не морочится с константами, есть шестнадцатеричные литералы: 0x1, 0x10, 0x100 и т.д.
0
Наск. я понимаю, это будет 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, и т.д., что не очень удобно для тех кто не работал много с ассемблером :)
0
У тебя есть целых 8 категорий вида 0x1, 0x10, 0x100 и т.д. Очень часто это хватит.
0
кому нравится задавать именно в двоичном виде, parseInt в помощь..
но мне больше все таки нравится запись вида — 0х80000000
нежели — parseInt(«10000000000000000000000000000000», 2);
0
И кстати, maskBits не совсем «полон единичек» так как по умолчанию имеет значение 0xFFFF а не 0xFFFFFFFF
соответственно вместо:
11111111111111111111111111111111
мы имеем:
00000000000000001111111111111111
0
А я как раз думал написать об этом после конвейеров :)
Кстати, у меня 1 тело может принадлежать только к 1 категории сейчас, но может сталкиваться с выбранным количеством других категорий. Спасибо за напоминание, что тело может принадлежать больше, чем к одной категории, добавил.
0
хмм… нужно подумать и написать класс, который будет сам расставлять нужные биты.
Например регистрируем в нём все категории, которые могут быть в игре. В «написанном» классе, добавляем пары, которые могут взаимодействовать друг с другом, он у себя внутри для каждой категории строит битовые последовательности. При создании обьекта, присваиваем предаем в класс категорию(категории) обьекта, а он возвращает правильные битовые последовательности.

Такое не сложно написать, нужно будет подумать на досуге :)
  • vizgl
  • vizgl
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.