#ipad #ios7 #sprite-kit #collision-detection #pixel-perfect
#iPad #ios7 #спрайт-набор #обнаружение столкновений #pixel-perfect
Вопрос:
Мне нужно создать 8 случайных объектов sprite в игре sprite для iPad. Объекты довольно большие и разных размеров. Они не должны накладываться друг на друга. Если тот, который появляется на сцене, накладывается, он будет удален (необязательно, он удаляет нижележащий). Я искал систему обнаружения столкновений pixel perfect или вспомогательный класс для Sprite Kit. До сих пор я не нашел учебника или чего-то подобного. Большинство людей используют обычное обнаружение столкновений, которое не принесет никакой помощи, поскольку мои объекты большие. Я протестировал стандартный подход, но он создает прямоугольники, которые делают область спрайта в моем случае еще больше. Это мой проект тестирования шаблонов sprite kit:
#import "WBMMyScene.h"
static const uint32_t randomObjectCategory = 0x1 << 0;
@interface WBMMyScene () <SKPhysicsContactDelegate>
@end
@implementation WBMMyScene
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
/* Setup your scene here */
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
self.physicsWorld.gravity = CGVectorMake(0, 0);
self.physicsWorld.contactDelegate = self;
}
return self;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
/* Called when a touch begins */
for (UITouch *touch in touches)
{
CGPoint location = [touch locationInNode:self];
SKSpriteNode *spaceship = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
//SKSpriteNode *spaceship = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:CGSizeMake(50, 50)];
spaceship.position = location;
[spaceship setSize:CGSizeMake(50, 50)];
[spaceship.texture setFilteringMode:SKTextureFilteringNearest];
//spaceship.texture setFilteringMode
spaceship.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:spaceship.size];
spaceship.physicsBody.dynamic = YES;
spaceship.physicsBody.categoryBitMask = randomObjectCategory;
spaceship.physicsBody.contactTestBitMask = randomObjectCategory;
spaceship.physicsBody.collisionBitMask = 0;
[self addChild:spaceship];
}
}
- (void)didBeginContact:(SKPhysicsContact *)contact
{
// 1
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
// 2
if (firstBody.categoryBitMask == secondBody.categoryBitMask)
{
[self projectile:(SKSpriteNode *) firstBody.node didColliteWithEachOther:(SKSpriteNode *) secondBody.node];
}
}
- (void)projectile:(SKSpriteNode *)object1 didColliteWithEachOther:(SKSpriteNode *)object2
{
NSLog(@"Hit");
[object1 removeFromParent];
[object2 removeFromParent];
}
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
}
@end
Спасибо за ваше время 🙂
Ответ №1:
Насколько мне известно, в iOS7 нет физики для каждого пикселя, это должно быть в XCode 6, который находится на стадии бета-тестирования и доступен для разработчиков сейчас. Помните, что это бета-версия, и в ней есть несколько ошибок, полный релиз, скорее всего, будет в сентябре с iOS8 и новым iPhone.
В то же время у вас есть два варианта: вы можете загрузить бета-версию XCode 6 и поработать с ней для физики каждого пикселя. Лично мне, однако, немного надоело использовать бета-версию для полной разработки, и вместо этого я вернулся к XCode 5. В iOS7 и XCode 5 у вас есть возможность определить a physicsBody
с помощью пути, что дает точное описание физической формы спрайта.
Инструмент, который я использую, находится здесь и позволяет перетаскивать изображение, а затем графически определять точки пути и возвращает код, это действительно удобно.
Надеюсь, это поможет!
Комментарии:
1. Gj @Andy, я попробую инструмент, который вы используете. Я нахожусь в конце разработки и не хочу, чтобы ошибки IDE мешали заключительным этапам разработки / распространения. Я столкнулся с ошибками в Xcode 5.1, и мне не нужны новые :). Приятно знать, что в iOS8 / Xcode6 эта проблема будет исправлена.
Ответ №2:
Это решение не обеспечивает идеального распознавания пикселей, поэтому может быть не совсем тем, что вам (или другим, задающим этот вопрос) нужно, но это действительно хорошая альтернатива, которая будет идеальной для некоторых.
Он автоматически вычисляет физическое тело на основе полигонов, анализируя текстуру вашего спрайта. Он в основном рисует контур вокруг непрозрачных пикселей и использует его для столкновения.
Вместо этого:
spaceship.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:spaceship.size];
Используйте это:
spaceship.physicaBody = [SKPhysicsBody bodyWithTexture:spaceship.texture alphaThreshold:0.5f size:spaceship.size];
Комментарии:
1. Привет, джабботт, я тоже испытываю трудности, и я также пробовал использовать тело на основе текстур и полигонов, и они отлично работают при столкновении, но не для touchesMoved и didBeginContact, что на самом деле более важно, если вы хотите работать со спрайтами своими руками, а не полагаться на PhysicsWorld. Смотрите мой вопрос о touchesMoved.
2. На самом деле это также отлично работает для didBeginContact, но не для touchesMoved.