Это продолжает и завершает предыдущую почту Быстрого Прекрасного пикселом Обнаружения столкновений для Cocos2D с Примером кода (1/2) статья.

Тестирование на pixelMask столкновение с прямоугольником

Тестирование на отдельный пункт просто, проверяя на прямоугольник, такой как ограничивающий прямоугольник другого узла требует большего количества работы. Не только, чтобы написать кодекс, но также и управлять этим. И это ограничено узлами, которые ни не вращаются, ни измерены. And it is limited to nodes which are neither rotated nor scaled.

К сожалению, тестирование столкновений с вращаемыми прямоугольниками (ориентируемый на ограничивающие прямоугольники) не тривиально даже, не рассматривая pixelMask столкновения. Вот C ++ OBB и C # OBB выполнение для обнаружения столкновений OBB. И это только для ограничивающих прямоугольников, проверяя каждый пиксел в ориентируемой маске пиксела, вероятно, был бы предельно дорог. And that’s just for the bounding boxes, testing each pixel in an oriented pixel mask would likely be prohibitively expensive.

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

проверьте, если pixelMask пересекается с rect
Цель-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (BOOL) pixelMaskIntersectsRegularNode: (CCNode *) другой ) pixelMaskIntersectsRegularNode:(CCNode*)other
{
   CGRect intersectRect = [сам intersectRectInPixels:self otherNode:other]; = [self intersectRectInPixels:self otherNode:other];
   
   //проверьте, установлен ли какой-либо из флагов в pixelMask в пересечении
   NSUInteger maxX = intersectRect.origin.x + intersectRect.size.width; = intersectRect.origin.x + intersectRect.size.width;
   NSUInteger maxY = intersectRect.origin.y + intersectRect.size.height; = intersectRect.origin.y + intersectRect.size.height;
   для (NSUInteger y = intersectRect.origin.y; y <maxY; y ++) NSUInteger y = intersectRect.origin.y; y < maxY; y++)
   {
      для (NSUInteger x = intersectRect.origin.x; x <maxX; x ++) NSUInteger x = intersectRect.origin.x; x < maxX; x++)
      {
         Индекс NSUInteger = y * pixelMaskWidth + x; = y * pixelMaskWidth + x;
         возвратите pixelMask [индекс]; [index];
      }
   }
   
   возвратитесь НЕТ; ;
}

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

Например можно утверждать, что ближе в центр pixelMask вероятность pixelMask укусила установленные увеличения. Это означает в зависимости от местоположения intersectionRect, который повторение по pixelMask можно было щипнуть, чтобы начать ближе в центр pixelMask и проложить себе путь за пределы. Но эта оптимизация зависит в большой степени от используемых изображений, и некоторым простираются, как объекты перемещаются. But this optimization depends heavily on the images being used and to some extend how the objects move.

Худший вариант развития событий - то, что нет никакого набора сверл в pixelMask для данного intersectRect. Зная, что, можно было бы считать повторение по pixelMask не BOOL BOOL, но поиском полный 32-битовый NSUInteger (4 BOOL сразу) от pixelMask. Если та 32-битовая ценность 0, то ни один из 4 битов столкновения не может возможно быть установлен, сокращая количество тестов и повторений от 4 до 1. Только если ценность больше чем 0, Вы должны были бы проверить, что каждый отдельный pixelMask укусил. Используя BitArray Вы могли проверить до 32 битов сразу подобным способом. If that 32-Bit value is 0, then none of the 4 collision bits can possibly be set, reducing the number of tests and iterations from 4 to 1. Only if the value is greater than 0 you would have to check each individual pixelMask bit. Using a BitArray you could test up to 32 bits at once in a similar fashion.

Беглый взгляд на intersectRectInPixels метод показывает, что это создает пересекающийся прямоугольник ограничивающих прямоугольников двух сталкивающихся узлов. Важный, чтобы отметить вот то, что происхождение пересекающегося прямоугольника должно быть преобразовано в nodeSpace первого узла и затем преобразовано в пикселы, чтобы удостовериться, что это работает с изображениями HD.

получите пересечение rect двух узлов
Цель-C
1
2
3
4
5
6
7
8
9
10
- (CGRect) intersectRectInPixels: (CCNode *) узел otherNode: (CCNode *) другой ) intersectRectInPixels:(CCNode*)node otherNode:(CCNode*)other
{
   CGRect myBBox = [узел boundingBox]; = [node boundingBox];
   CGRect otherBBox = [другой boundingBox]; = [other boundingBox];
   CGRect intersectRect = CGRectIntersection (myBBox, otherBBox); = CGRectIntersection(myBBox, otherBBox);
   
   //преобразуйте rect к пространству эльфа и преобразуйте пункты в пикселы
   intersectRect.origin = [узел convertToNodeSpace:intersectRect.origin]; = [node convertToNodeSpace:intersectRect.origin];
   возвратите CC_RECT_POINTS_TO_PIXELS (intersectRect); (intersectRect);
}

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

Обнаружение столкновения двух KKPixelMaskSprites

Это - только относительно маленький шаг, идущий от pixelMask с пересечением прямоугольника к тестированию двух pixelMasks для пересечения (наложение может быть лучшим словом здесь). Снова, Вы не должны использовать грубую силу – достаточно проверить перекрывание (пересечение) прямоугольник этих двух эльфов. Снова этот тест не работает с вращаемыми или чешуйчатыми прямоугольниками, но это - недостаток, который приносит пользу исполнению теста. Again this test doesn’t work with rotated or scaled rectangles but it’s a drawback that benefits the performance of the test.

тестирование на столкновение двух pixelMasks
Цель-C
1
2
3
4
5
6
7
8
9
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
- (BOOL) pixelMaskIntersectsPixelMaskSprite: (KKPixelMaskSprite *) другой ) pixelMaskIntersectsPixelMaskSprite:(KKPixelMaskSprite*)other
{
   CGRect intersectSelf = [сам intersectRectInPixels:self otherNode:other]; = [self intersectRectInPixels:self otherNode:other];
   CGRect intersectOther = [сам intersectRectInPixels:other otherNode:self]; = [self intersectRectInPixels:other otherNode:self];
   NSUInteger originOffsetX = intersectOther.origin.x - intersectSelf.origin.x; = intersectOther.origin.x - intersectSelf.origin.x;
   NSUInteger originOffsetY = intersectOther.origin.y - intersectSelf.origin.y; = intersectOther.origin.y - intersectSelf.origin.y;
   NSUInteger otherPixelMaskWidth = other.pixelMaskWidth; = other.pixelMaskWidth;
   BOOL* otherPixelMask = other.pixelMask; otherPixelMask = other.pixelMask;
   //проверьте, установлен ли какой-либо из флагов в pixelMask в области пересечения
   NSUInteger maxX = intersectSelf.origin.x + intersectSelf.size.width; = intersectSelf.origin.x + intersectSelf.size.width;
   NSUInteger maxY = intersectSelf.origin.y + intersectSelf.size.height; = intersectSelf.origin.y + intersectSelf.size.height;
   для (NSUInteger y = intersectSelf.origin.y; y <maxY; y ++) NSUInteger y = intersectSelf.origin.y; y < maxY; y++)
   {
      для (NSUInteger x = intersectSelf.origin.x; x <maxX; x ++) NSUInteger x = intersectSelf.origin.x; x < maxX; x++)
      {
         Индекс NSUInteger = y * pixelMaskWidth + x; = y * pixelMaskWidth + x;
         
         если (pixelMask [индекс]) pixelMask[index])
         {
            //проверьте, есть ли набор пиксела в том же самом местоположении
            //в pixelMask другого эльфа
            NSUInteger otherX = x + originOffsetX; = x + originOffsetX;
            NSUInteger otherY = y + originOffsetY; = y + originOffsetY;
            NSUInteger otherIndex = otherY * otherPixelMaskWidth + otherX; = otherY * otherPixelMaskWidth + otherX;
            
            если (otherPixelMask [otherIndex]) otherPixelMask[otherIndex])
            {
               возвратите ДА; ;
            }
         }
      }
   }
   возвратитесь НЕТ; ;
}

По сравнению с предыдущим тестом прямоугольника пересекающийся прямоугольник другого сталкивающегося KKPixelMaskSprite был добавлен и ссылка на otherPixelMask наряду с другими припрятавшими про запас ценностями в линиях 4-9. Суть функции все еще выполняет тот же самый тест вплоть до линии 22. Вместо того, чтобы возвратить первый бит, который установлен в pixelMask, мы должны удостовериться, что этот бит также установлен в otherPixelMask. Instead of returning the first bit that is set in the pixelMask, we have to make sure that this bit is also set in the otherPixelMask.

Так как индекс в otherPixelMask может быть легко вычислен, возмещая это с происхождением intersectOther прямоугольника, мы только должны произвести новый индекс для того же самого x, y координаты, но относительно системы координат другого KKPixelMaskSprite. Линии 26 и 27 выполняют ту операцию, используя предрасчетный originOffset от линий 6 и 7. В основном это возмещает x, y координаты к тому же самому местоположению в пределах прямоугольника пересечения другого эльфа. То, что остается, преобразовывает координаты в индекс и проверяет, если бит otherPixelMask в том индексе также установлен. Если так, у нас есть столкновение. In essence this offsets the x,y coordinates to the same location within the other sprite’s intersection rectangle. What remains is converting the coordinates to the index and testing if the otherPixelMask bit at that index is also set. If so, we have a collision.

Соединение тестов пересечения

Есть один метод, который я до сих пор не учитывал. Это - общественный метод интерфейса, который назовут пользователи KKPixelMaskSprite. Это выступает, несколько ранние проверяют и также выбирают правильный тест, чтобы выступить основанный на классе другого узла. It performs several early out tests and also picks the right test to perform based on the class of the other node.

определите который тест пересечения выступить
Цель-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- (BOOL) pixelMaskIntersectsNode: (CCNode *) другой ) pixelMaskIntersectsNode:(CCNode*)other
{
   если (rotation_! = 0.0f || other.rotation! = 0.0f || rotation_ != 0.0f || other.rotation != 0.0f ||
        self.scale! = 1.0f || other.scale! = 1.0f) != 1.0f || other.scale != 1.0f)
   {
      CCLOG ("или или оба узла вращаются и/или измерены, возвращаясь НЕТ!"); ");
      возвратитесь НЕТ; ;
   }
   
   если ([сам intersectsNode:other]) [self intersectsNode:other])
   {
      если ([другой isKindOfClass:PixelMaskSpriteClass]) [other isKindOfClass:PixelMaskSpriteClass])
      {
         KKPixelMaskSprite* maskSprite = (KKPixelMaskSprite *) другой; = (KKPixelMaskSprite*)other;
         возвратитесь [сам pixelMaskIntersectsPixelMaskSprite:maskSprite]; self pixelMaskIntersectsPixelMaskSprite:maskSprite];
      }
      еще
      {
         возвратитесь [сам pixelMaskIntersectsRegularNode:other]; self pixelMaskIntersectsRegularNode:other];
      }
   }
   
   возвратитесь НЕТ; ;
}

Я упоминал прежде, который тесты пересечения не работают с вращаемыми или чешуйчатыми узлами. В этом случае метод немедленно возвращается НЕ и регистрирует это, чтобы избежать кого-то расстраивание, потому что тесты “не всегда работают”. Также сэкономить меня много таких вопросов. :) Also to spare me many such questions. :)

Конечно, пересечение проверяет, только имеют смысл, если ограничивающие прямоугольники пересекаются. intersectsNode метод - функция удобства, которую Вы найдете в Kobold2D, и в классе CCNodeExtensions добавленный к проекту.

pixelMask против теста pixelMask только выполнен, если другой узел - также KKPixelMaskSprite во всех других случаях, прямоугольник, пересекающийся pixelMask тест, выполнен вместо этого. Переменная PixelMaskSpriteClass - статическая переменная, калибровавшая в init методе как [сам класс] просто, потому что, посылая сообщение класса каждый раз немного расточителен по сравнению с 4 байтами дополнительной памяти для переменной PixelMaskSpriteClass.

Тестирование пересечения двух эльфов, или KKPixelMaskSprite или нет, столь же просто как письмо:

1
если ([spriteA pixelMaskIntersectsNode:spriteB])...[spriteA pixelMaskIntersectsNode:spriteB]) ...

Работа Маски пиксела: BitArray против. Множество BOOL

BOOL array

Теперь к интересному вопросу: если BitArray в состоянии уменьшить использование памяти до 1/8-ого (12.5 %), это также быстрее? Позвольте мне показывать это, поскольку графика, полученная, выполняя pixelMask против pixelMask, проверяет несколько сотен тысяч раз неоднократно, и измеряя полную продолжительность: Let me reveal this as a graphic obtained by performing the pixelMask vs pixelMask check several hundred thousand times repeatedly, and measuring the total running time:

Другими словами: это - обмен между использованием памяти и работой во время выполнения. Тесты пересечения маски пиксела на 27 % медленнее на iPod 4, и на 18 % медленнее на iPhone 3 г, используя BitArray. И на всякий случай Вы задаетесь вопросом: если Вы должны были использовать UInt16 или даже множество UInt32 вместо множества BOOL, Вы будете видеть очень незначительное уменьшение в работе (меньше чем 5 %), но удваивать соответственно четыре раза использование памяти. Pixel mask intersection tests are 27% slower on an iPod 4, and 18% slower on an iPhone 3G when using the BitArray. And just in case you’re wondering: if you were to use a UInt16 or even UInt32 array instead of the BOOL array you’ll see a very minor decrease in performance (less than 5%) but double respectively four times the memory usage.

Комната для Усовершенствования

Сочиняя класс KKPixelMaskSprite я обнаружил много комнаты для усовершенствования. Я не хочу экономить Вас список, потому что он также показывает некоторые недостатки класса, что я думаю, что Вы должны знать. Если Вы действительно осуществляете одно из этих усовершенствований, пожалуйста, разделите их, и если возможный разделите их в соответствии с разрешающей лицензией, такой как Массачусетский технологический институт. If you do implement one of these improvements please share them, and if possible share them under a permissive license such as MIT.

Возможно полезные усовершенствования, в порядке полноценности
  • тайник pixelMasks, например в единичном предмете CCPixelMaskCache, или добавляет их к CCTexture2D
  • позвольте создание маски пиксела с имен spriteframe или spriteframes
  • позвольте тесты столкновения, если эльф вращается точно к 90, 180 или 270 степеней
  • позвольте использование невласти двух изображений для pixelMasks на 1-ых/2-ых устройствах поколения
  • позвольте столкновения между SD и эльфами изображения HD
Потенциальная оптимизация в порядке ожидаемой эффективности
  • уменьшите pixelMask размер, объединяясь 2×2, 3×3, 4×4, и т.д. пикселы в единственный бит
  • ИЛИ: только используйте изображения SD для pixelMask, вызывая столкновения на устройствах Сетчатки указать границы
  • оптимизируйте повторения, проверяя UInt32 (4x BOOL) или многократные Биты сразу для ценности> 0
  • оптимизируйте повторения, начиная повторять от угла, самого близкого к центру

В особенности оптимизация, чтобы уменьшить pixelMask размер, комбинируя многократные пикселы, должно оказаться, очень эффективна, и относительно легка осуществить. Большинство прекрасных пикселом столкновений не должно действительно быть прекрасным пикселом, достаточно близкое приближение более чем достаточно для большинства заявлений. В особенности на устройствах Сетчатки никакой игрок не будет в состоянии разобрать, точны ли не так пиксел прекрасные столкновения только в пределах два, три, или возможно даже больше пикселов. Самый простой подход должен был бы только рассмотреть только изображения SD для масок пиксела, даже на устройствах Сетчатки. Добавленное преимущество, являющееся, что меньший pixelMask равняется меньшему количеству повторений и таким образом более быстрых тестов столкновения. In particular on Retina devices no player will be able to make out if the not-so-pixel-perfect collisions are accurate only within two, three, or possibly even more pixels. The simplest approach would be to just consider only the SD images for pixel masks, even on Retina devices. The added advantage being that a smaller pixelMask equals fewer iterations and thus quicker collision tests.

Загрузите проект в качестве примера KKPixelMaskSprite


Загрузите проект демонстрационного примера KKPixelMaskSprite!

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

Веселый piXmas!

Это - моя последняя должность iDevBlogADay перед Рождеством. Это является очень большим, дополнительное хрустящий, покрытый шоколадом, запахами как корица, вкусами как яблоки и грецкие орехи и соус и печенье и индейка, и запрещено в США, потому что это содержит несъедобные пикселы и является задыхающейся опасностью для всех, кто намеревается прочитать это сразу.

В этом смысле, Веселое Рождество все! :)


Помогите мне помочь Вам!

Я провожу свое все время, придумывающее новые идеи, которые помогут Вам стать лучшим разработчиком приложения. Я очень наслаждаюсь процессом обучения, подталкиванием границ (мой и Ваш и та из технологии), имея свободу преследовать то, независимо от того, что находится на моем уме или Вашем к смело программе, что никто не запрограммировал прежде, и написать о том, что я изучил. Помогите мне помочь Вам, просматривая продукты в Изучении Магазина Cocos2D. Help me help you by browsing the products in the Learn Cocos2D Store.


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

13 Ответов на “Быстрое Прекрасное пикселом Обнаружение столкновений для Cocos2D с Примером кода (2/2)”

  1. [...] LearnCocosTV – Эпизод 1: Как я maed Ваш Домовой Быстро Прекрасное пикселом Обнаружение столкновений для Cocos2D с Примером кода (2/2) [...]

  2. Росс говорит:

    Вы проверили работу относительно библиотек физики, таких как Box2d или Бурундук? Мне было бы интересно знать – я предполагаю, что много людей только использует их для их функциональности обнаружения столкновений.

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

      • Кен Карпентер говорит:

        Фактически, я думаю, что они могут быть разумно сравнены.

        Методы развития игры часто - обмен между тем, что "хорошо" и что "достаточно хорошо".

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

        Также, знание исполнения обнаружения столкновений для Box2D помогло бы разработчику сделать информированный выбор. Конечно, Вы должны попытаться сделать сравнения настолько близко насколько возможно и хотели бы использовать все те 8 вершин.

        • Вы правильны в принципе. Но в этом случае я сказал бы, что решение должно быть принято дизайном. Работа только не крайне важна для этого решения. Performance just isn’t crucial to this decision.

          Например, прекрасные пикселом столкновения очень точны, но не работают ни в одном из эльфов, вращается или измерен. Принимая во внимание, что, если Вы рассматриваете обнаружение столкновений с двигателем физики, Ваши эльфы могут вращаться или измерены. И возможности состоят в том, что, если Вы хотите или должны использовать двигатель физики так или иначе, используя физику, чтобы обнаружить все столкновения, просто требование. And chances are that if you want or have to be using a physics engine anyway, using physics to detect all collisions is simply a requirement.

  3. Эрнесто Корви говорит:

    Штеффен, я рад, что Вы полагались на мою должность много-лет. В моей защите я действительно заявлял, что отправил псевдокодекс. :)

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

    До удобства и простоты использования кодекса против говорят, двигатель физики, это действительно зависит от того, что Вы делаете. Я вспоминаю, что, когда я отправил ту идею, я не работал над Типом леммингов клона для ИОСА (никогда выпущенный), и это повлекло за собой деформацию в реальном времени ландшафта в полукруглых формах, которые закончились множестве вершин, которые заставили и Бурундука и OpenGL ES задыхаться вполне быстро (мы говорим 1-ые устройства генерала здесь).

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

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

    • Я продолжал думать, что следующий логический шаг будет деформацией ландшафта Стиля леммингов. :)

      Что касается преобразования точки ввода, я сделал это в первом примере. Тестирование, если пункт в пределах чешуйчатой и вращаемой карты столкновения, является вопросом преобразования пункта к пространству узла. Но это терпит неудачу, если Вы хотите проверить две карты столкновения друг против друга, и оба могут быть измерены или вращаться. Возможно это возможно, хотя сначала преобразовать в настоящее время проанализировавший пункт от одного узла до мирового пространства, и затем к пространству другого узла, не уверенному, если это даст правильный результат. But this fails if you want to test two collision maps against each other, and both may be scaled or rotated. Maybe it’s possible though to first transform the currently analyzed point from one node to world space, and then to the other node’s space, not sure if that will give the correct result.

      • Эрнесто Корви говорит:

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

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

  4. Сырен Крог Неигэард говорит:

    Привет Штеффен

    Что, если эти два эльфа, чтобы проверить на столкновение находится на различном CCLayers, Ваш кодекс мог бы быть обновлен, чтобы обращаться с этим также? Так, чтобы положение эльфов маски было преобразовано в мировое пространство или что-то в проверке столкновения?

    Наилучшие пожелания
    Søren

    • Вы проверили, что кодекс не в состоянии сообщить о столкновениях правильно в этом случае? Поскольку, насколько я понимаю, это, преобразовывая координаты в пространство узла (система координат) примет во внимание (или просто не имеет значения), что узел может быть ребенком одного или нескольких других узлов.

      • Сырен Крог Неигэард говорит:

        Гм, действительно терпел неудачу, но это жаловалось на вращаемые узлы, и я сначала видел это теперь.. Я вращаю своих эльфов много печально :(

  5. JARV говорит:

    Привет Штеффен

    Я использовал KKPixelMaskSprite успешно с моей игрой (это является большим!), но я изменил своих эльфов на spriteWithSpriteFrameName …, и теперь я понимаю, что он не работает со структурами эльфа :(

    Я собираюсь попытаться приспособить KKPixelMaskSprite, чтобы работать со структурами эльфа (я предполагаю, что он не был сделан). Какая-либо подсказка, чтобы начаться с?

    Спасибо!!
    JARV

    • JARV говорит:

      Наконец я получаю это работающий с маленькой работой …, который в порядке в моей цели (couse, это может быть улучшено),

      1. - Создают CCRenderTexture с размером эльфа.
      2. - Положение эльфа Изменения к 0,0, чтобы посетить CCRenderTexture и затем восстановить его оригинальное положение:
      sprite.anchorPoint = ccp (0,0);
      sprite.position = ccp (sprite.offsetPositionInPixels.x * (-1)
      , sprite.offsetPositionInPixels.y * (-1));
      3. - Создают UIImage с CCRenderTexture:
      UIImage *image = [rt getUIImageFromBuffer];

      Теперь у нас есть UIImage, и мы можем снова использовать кодекс от KKPixelMaskSprite (initWithFile).

      Только заключительное соображение, перед звонком pixelMaskContainsPoint мы должны приспособить пункт из-за погашения:
      CGPoint указывают = ccp (point.x-sprite.offsetPositionInPixels.x, point.y-sprite.offsetPositionInPixels.y);

      Это работает большое!!

Оставьте Ответ