2017-01-02 5 views
6

Мне действительно нужно знать, как заблокировать ось x SKSpriteNode и его физическое устройство. Мне нужно сохранить SKSpriteNode dynamic и affectedByGravity. Узел находится на склоне, поэтому именно поэтому ось х перемещается из-за силы тяжести. Тем не менее, я не хочу, чтобы ось x этого SKSpriteNode двигалась из-за силы тяжести. Есть ли способ заблокировать ось x, чтобы достичь этого? Спасибо за любую помощь :DSwift 3 (SpriteKit): Блокировка оси x для SKSpriteNode и ее физика.

Edit: Я попытался применить ограничение к значению х, как это:

let xConstraint = SKConstraint.positionX(SKRange(constantValue: 195)) 
node.constraints?.append(xConstraint) 

Однако это не работает, и я не знаю, почему и как Исправить это. Кто-нибудь знает о решении?

Редактировать 2:SKPhysicsJointPin на самом деле выглядит более перспективным. В комментариях первого ответа/ответа на этот вопрос я пытался понять, как правильно использовать его в моей ситуации.

Пример моего кода:

let node = SKSpriteNode(imageNamed: "node") 

enum collisionType: UInt32 { 
    case node = 1 
    case ground = 2 
    case other = 4 //the other node is unrelated to the ground and node 
} 

class GameScene: SKScene, SKPhysicsContactDelegate { 

override func didMove(to view: SKView) { 
    //Setup node physicsBody 
    node.physicsBody = SKPhysicsBody(rectangleOf: node.size) 
    node.physicsBody?.categoryBitMask = collisionType.node.rawValue 
    node.physicsBody?.collisionBitMask = //[other node that isn't the ground or the node] 
    node.physicsBody?.contactTestBitMask = //[other node that isn't the ground or the node] 
    node.physicsBody?.isDynamic = true 
    node.physicsBody?.affectedByGravity = true 
    addChild(node) 

    //Physics Setup 
    physicsWorld.contactDelegate = self 
} 

узел находится на поверхности земли, а земля состоит из различных SKSpriteNode линий, которые имеют volumeBased physicsBody. Земля продолжает добавлять новые линии спереди и удалять их сзади, а также изменять значение x каждой строки отрицательным (так что земля кажется движущейся - этот процесс выполняется в SKAction). Эти линии (части земли) находятся под углом, поэтому перемещается ось x узла. Я хочу, чтобы узел всегда находился в передней части земли (например, всегда поверх вновь созданной строки). В настоящее время, устанавливая положение узла, как это блокирует ось х (решение моего вопроса):

override func didSimulatePhysics() { 
    //Manage node position 
    node.position.x = 195 
    node.position.y = CGFloat([yPosition of the first line of the ground - the yPosition keeps changing]) 
} 

Примечания:^Эта^функция внутри класса GameScene

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

+0

Вы говорите, что это ограничение не работает. Разве что это вообще не работает, как никакой эффект? – Confused

+0

Что значит, что вы не хотите, чтобы ось x двигалась из-за силы тяжести? Гравитация не влияет на спрайт на оси x, возможно, вам нужно объяснить проблему лучше – Knight0fDragon

+0

@Confused Да, вот что я имею в виду, но фонд didSimulatePhysics() работает намного лучше, но теперь у вас есть новая проблема - прочитайте мое редактирование. –

ответ

3

Я думаю, вы могли бы установить linearDamping свойство 0,0

linearDamping это свойство, которое уменьшает линейную скорость тела.

Данное свойство используется для имитации сил флюидизации или воздушного трения на корпусе . Свойство должно быть значением от 0,0 до 1,0. Значение по умолчанию равно 0,1. Если значение равно 0.0, линейное демпфирование не применяется к объекту .

Обратите внимание также на другие силы, применяемые к вашему SKSpriteNode. Гравитационная сила, применяемая в мире физики, например, где значение dx, по вашему запросу, должно быть установлено на 0.0:

CGVector(dx:0.0, dy:-4.9) 

Помните также, что при применении других сил векторов как velocity вы должны поддерживать свойство йха к 0,0 постоянных, если вы хотите, чтобы заблокировать ось х.

Вы можете найти более подробную информацию на официальный docs

Update (после ваших данных в комментарии ниже):

Вы также можете якорь своего спрайта на землю с SKPhysicsJoint (я не» знаю ваш проект, так что это только для примера):

var myJoint = SKPhysicsJointPin.joint(withBodyA: yourSprite.physicsBody!, bodyB: yourGround.physicsBody!, anchor: CGPoint(x: yourSprite.frame.minX, y: yourGround.frame.minY)) 

self.physicsWorld.add(myJoint) 

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

+0

Спасибо за это. Изменение «linearDamping» на 1.0 сделало действие силы тяжести более медленным, но оно все еще не заблокировало ось x. На узел не наложены гравитационные силы. Однако причина, по которой движется ось х, заключается в том, что она находится на склоне (диагональная прямая SKSpriteNode). Вот почему он продолжает скатываться по склону. –

+0

Как насчет 'physicalBody? .AllowsRotation'? вы пытаетесь установить его на false? –

+0

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

4

Свойство constraints узла - это по умолчанию nil. Вам нужно создать массив из одного или нескольких ограничений и присвоить его свойству. Например

let xConstraint = SKConstraint.positionX(SKRange(constantValue: 195)) 
node.constraints = [xConstraint] 

Update

Вы можете использовать узел камеры вместо перемещения земли в сцене. С узлом камеры вы перемещаете основной символ и камеру вместо земли.

enter image description here

+0

По какой-то причине это все равно не помогает, но спасибо. –

+0

Это должно вести себя очень похоже на код, добавленный в 'didSimulatePhysics'. Что происходит, когда вы добавляете это в свой метод 'didMove'? – 0x141E

+0

Положение x все еще перемещается, и оно не ограничено. –

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