2015-05-13 2 views
3

Я планирую платформерную игру для iOS с помощью SpriteKit и Swift. Я провел некоторое исследование о том, как обрабатывать столкновения с игроком спрайта и наткнуться на эту статью.Столкновение черепахи SpriteKit с изогнутыми или наклонными напольными плитами

http://www.learn-cocos2d.com/2013/08/physics-engine-platformer-terrible-idea/

В этой статье советы вы не использовать встроенный в физике двигатель SpriteKit но реализовать такие вещи, как двигаться, прыгать и обработки столкновений самостоятельно. Учебник по платформе на сайте Рэя Вендерлиша предлагает аналогичный подход.

Пока все хорошо, но давайте поговорим о напольной плитке, на которой игрок может стоять. Пользовательская реализация физики была бы простой, если плитки прямоугольные и имеют плоскую поверхность (например, в руководстве от Ray Wenderlich), так как вы использовали CGRectIntersectsRect для обнаружения столкновения. Но как вы проверите столкновение игрока с изогнутыми или наклонными плитами? Из того, что я прочитал, CGRectIntersectsRect не учитывает прозрачный пиксель внутри sprites rect.

http://i.stack.imgur.com/lRP2Q.png

Посмотрите на выше плитки, например. Белая область (верхний левый) будет прозрачной. Теперь, если игровой спрайт опустится на эту плитку, столкновение будет обнаружено на верхней границе прямоугольника плитки, хотя там нет наземных пикселей (синяя область, справа внизу). Так что в конечном счете игрок будет парить в воздухе над этой плиткой. Я мог бы нажимать кнопку спрайта на несколько пикселей, но это немного взломано и становится сложнее, если изогнутые напольные плитки имеют разные углы наклона.

Итак, вопрос в том, как я могу справиться с этими типами столкновений с одним только SpriteKit (никаких дополнительных фреймворков, таких как Cocos2D, Kobold Kit, ...)? Или этот подход совершенно неправильный, и столкновения в платформере с SpriteKit должны быть сделаны принципиально разными?

Любая помощь очень ценится!

ответ

3

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

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

Например:

enter image description here

В изображении выше я создал 45 градусов с правой стороны наклонный пол. Объект, который я добавил, называется floor45R.

Следующий шаг - проанализировать ваши объекты карты.В случае 45floorR необходимо создать физический организм, как это:

NSArray *arrayObjects = [group objectsNamed:@"floor45R"]; 
    for (NSDictionary *dicObj in arrayObjects) { 
     CGFloat x = [dicObj[@"x"] floatValue]; 
     CGFloat y = [dicObj[@"y"] floatValue]; 
     CGFloat w = [dicObj[@"width"] floatValue]; 
     CGFloat h = [dicObj[@"height"] floatValue]; 

     SKSpriteNode *myNode = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(w, h)]; 
     myNode.position = CGPointMake(x, y); 
     myNode.zPosition = 100; 
     CGMutablePathRef trianglePath = CGPathCreateMutable(); 
     CGPathMoveToPoint(trianglePath, nil, -myNode.size.width/2, myNode.size.height/2); 
     CGPathAddLineToPoint(trianglePath, nil, myNode.size.width/2, -myNode.size.height/2); 
     CGPathAddLineToPoint(trianglePath, nil, -myNode.size.width/2, -myNode.size.height/2); 
     CGPathAddLineToPoint(trianglePath, nil, -myNode.size.width/2, myNode.size.height/2); 
     myNode.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:trianglePath]; 
     myNode.physicsBody.dynamic = NO; 
     myNode.physicsBody.restitution = 0; 
     myNode.physicsBody.friction = 0.0; 
     myNode.physicsBody.categoryBitMask = CategoryFloor45; 
     myNode.physicsBody.collisionBitMask = 0x00000000; 
     CGPathRelease(trianglePath); 

     [worldNode addChild:myNode]; 
    } 

Это работает для любого склона степени пола. Не забудьте установить бит-бит вашего игрока и любого другого узла, столкнувшись с полом.

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

SKPhysicsBody *firstBody = [SKPhysicsBody bodyWithCircleOfRadius:10 center:CGPointMake(0, 0)]; 
SKPhysicsBody *secondBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(5, 50) center:CGPointMake(0, 10)]; 
self.physicsBody = [SKPhysicsBody bodyWithBodies:@[firstBody, secondBody]]; 

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

+0

Хорошо, это интересно. Думаю, я попытаюсь использовать встроенную физику. Еще одна мысль: добавляете ли вы все физические тела для всех узлов при загрузке карты или динамически назначаете тела, когда узлы собираются войти в область просмотра (если ваш уровень больше, чем область просмотра, и он прокручивается, как вы переехать)? Я полагаю, что если у вас действительно большая карта, имитация всех тел (даже тех, которые находятся за пределами области просмотра), может оказать огромное влияние на частоту кадров. Есть ли у вас опыт в отношении максимального количества тел, которые SpriteKit может обрабатывать до замедления? – snorge

+0

@snorge - Ответ на ваш вопрос - это серая область. Все зависит от того, что еще происходит в вашей сцене, сколько других узлов, физических тел, действий и т. Д. Вы можете удалить физические тела FromParent, которые находятся вне экрана, но это снова зависит от вашего игрового кода. Например, если у вас есть враг, который все еще ходит, удаление пола приведет к его забвению. Что касается максимального количества узлов, опять же это зависит от того, что еще происходит. Вам нужно будет запустить несколько тестов и посмотреть, что лучше всего подходит вашему коду. – sangony

+0

Хорошо, я попробую и посмотрю сам. Большое вам спасибо, ваш ответ дал мне некоторое представление и на самом деле мне очень помог. – snorge

1

Вы можете использовать редактор уровней Tiled для обработки изогнутых и наклонных напольных плит вместе с JSTileMap, который обрабатывает карту TMX.

Он сможет в состояние справиться контактом с изогнутой и скошенной напольной плиткой, а также для регулировки угла объектов, стоящих на вершине этих плиток, вы должны использовать некоторые математические функции, хороший пример найден here

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

+0

На самом деле, я хочу использовать Tiled для создания уровней игры. Я уже посмотрел на него, но я не понимаю, как это поможет мне справиться с столкновениями на изогнутых и наклонных полах. В конце концов, карта будет просто загружена в SpriteKit, причем каждая плитка будет прямоугольным SKSpriteNode. Спасибо за указание регулировки угла. Я мог бы добавить, что позже, но в настоящее время моя главная забота - уметь поставить игрока на землю, независимо от того, какая форма плитки пола. – snorge

+0

Вы можете использовать редактор Tiled Object и использовать «Вставить многоугольник» и нарисовать треугольник, а затем визуализировать объект в вашей игре с физикой. – Wraithseeker

+0

Я вижу. Хотя это сработает, это связано с большим количеством рисования полигонов вручную. Кроме того, изменение или добавление материала на уровень станет довольно утомительной задачей, так как мне придется перерисовывать или изменять положение полигонов каждый раз. В идеале я просто хотел бы объявить определенные плитки как «пол», установив на них какое-то свойство и позволяя игре беспокоиться о правильном позиционировании игрока внутри каждой плитки. Что-то вроде идеального столкновения с пикселями. – snorge

Смежные вопросы