0

Проблема: Когда монета появляется, это физическое тело появляется прямо под spriteNode. Кроме того, когда игрок вступает в контакт с физикой физики монеты, игрок отскакивает от физики и заканчивает игру.Swift SpriteKit basic Контакт/Столкновение

Каким должен быть выход: Физ-логика монеты должна быть правильно выровнена с помощью спрайта. Когда игрок входит в контакт с монетой, монета должна исчезнуть, а +1 на соответствующую метку.

Текущий код:

struct ColliderType { 

static let playerCategory: UInt32 = 0x1 << 0 

static let boundary: UInt32 = 0x1 << 1 
​ 
​static let coinCategory: UInt32 = 0x1 << 2 
​ 
​static let bodyA: UInt32 = 0x1 << 4 
​ 
​static let bodyB: UInt32 = 0x1 << 8 

} 

override func didMoveToView(view: SKView) { 

var coinInt = 0 
​ 
​ 
​ 
​self.physicsWorld.gravity = CGVectorMake(0.0, -7.0) 
physicsWorld.contactDelegate = self 

player = SKSpriteNode(imageNamed: "player") 
player.zPosition = 1 
player.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame)) 
player.physicsBody = SKPhysicsBody(circleOfRadius: player.size.width/5.12) 
player.physicsBody?.dynamic = true 
player.physicsBody?.allowsRotation = false 

self.addChild(player) 

generateCoins() 

​ 
​ 
coin = SKSpriteNode(imageNamed: "coin") 
coin.physicsBody? = SKPhysicsBody(circleOfRadius: coin.size.height/10) 
coin.physicsBody?.dynamic = false 
coin.physicsBody?.allowsRotation = false 
coin.zPosition = 1 
​self.addChild(coin) 
​ 
player.physicsBody?.categoryBitMask = ColliderType.playerCategory 
​player.physicsBody?.contactTestBitMask = ColliderType.boundary 
player.physicsBody?.collisionBitMask = ColliderType.coinCategory | ColliderType.boundary 

coin.physicsBody?.categoryBitMask = ColliderType.coinCategory 
coin.physicsBody?.contactTestBitMask = ColliderType.playerCategory 
coin.physicsBody?.collisionBitMask = ColliderType.playerCategory 

func didPlayerCollideWithCoin(player: SKSpriteNode, coin: SKSpriteNode) { 



self.coin.removeFromParent() 

self.coin += 1 

coinLabel.text = "\(coinInt)" 

} 

​ 
​  
​ 
​func generateCoins() { 

if(self.actionForKey("spawning") != nil){return} 

let coinTimer = SKAction.waitForDuration(7, withRange: 2) 

let spawnCoin = SKAction.runBlock { 

self.coin = SKSpriteNode(imageNamed: "coin") 

self.coin.physicsBody = SKPhysicsBody(circleOfRadius: self.coin.size.height/10) 

self.coin.name = "coin" 

self.coin.physicsBody?.dynamic = false 

self.coin.physicsBody?.allowsRotation = false 

var coinPosition = Array<CGPoint>() 

coinPosition.append((CGPoint(x:340, y:103))) 

coinPosition.append((CGPoint(x:340, y:148))) 

coinPosition.append((CGPoint(x:340, y:218))) 

coinPosition.append((CGPoint(x: 340, y:343))) 

let spawnLocation = coinPosition[Int(arc4random_uniform(UInt32(coinPosition.count)))] 

let action = SKAction.repeatActionForever(SKAction.moveToX(+self.xScale, duration: 4.4)) 

self.coin.runAction(action) 

self.coin.position = spawnLocation 

self.addChild(self.coin) 

print(spawnLocation) 

} 

let sequence = SKAction.sequence([coinTimer, spawnCoin]) 

self.runAction(SKAction.repeatActionForever(sequence), withKey: "spawning") 

} 
​​ 
func didBeginContact(contact:SKPhysicsContact) { 

let bodyA: SKPhysicsBody = contact.bodyA 

let bodyB: SKPhysicsBody = contact.bodyB 

if ((bodyA.categoryBitMask == ColliderType.playerCategory) &&  (bodyB.categoryBitMask == ColliderType.coinCategory)){ 

didPlayerCollideWithCoin(bodyA.node as! SKSpriteNode, coin: bodyB.node as! SKSpriteNode) 

} 

} 
+0

Вы уже спрашивали об этом, нет? (HTTP: // StackOverflow.com/questions/37580673/basic-swift-spritekit-collisions-using-physicalbodys) – rebusB

+0

Любая конкретная причина, по которой вы используете сдвиги бит 0, 1, 2, 4 и 8 вместо 0, 1, 2, 3, 4 и т.д? Продолжайте так, и у вас будет только 16 и 32, а потом вы закончите. –

ответ

4

Я рекомендую вам прочитать эти документы первым!

contactTestBitMask - Маска, определяющая, какие категории тел вызывают уведомления о пересечении с текущим физическим телом.

Когда два тела один и то же место, категория маска каждого тела является проверяется на контактной маску другого тела, выполняя логическую операцию И . Если любое сравнение приводит к ненулевому значению, создается объект SKPhysicsContact и передается делегату физика. Для лучшей производительности, только установленные биты в контактах маски для взаимодействий вы заинтересованы в

collisionBitmask -. Маска, которая определяет, какие категории физических тел могут столкнуться с этой физикой телом.

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

Удалить этот код, чтобы решить вопрос сталкивающихся

coin.physicsBody?.collisionBitMask = ColliderType.playerCategory 

Try, чтобы увидеть, если это решает ваш SpriteNode вопрос выравнивания

var coinTexture = SKTexture(imageNamed: "coin") 
coin = SKSpriteNode(texture:coinTexture) 
+0

Привет, спасибо за информацию! Я удалил карту collisionbitmask и ничего не изменилось. Выравнивание монеты по-прежнему такое же, как и я, я буду возиться с вещами тем временем. –

1

Кроме того, я бы рекомендовал изменения, как вы 'Определение вашей категории битмаски. Поскольку вы уже выполняете бит-сдвиг с <<, вам не нужно сдвигаться по степеням двух. Это то, что делает смещение бит для вас. Попробуйте изменить свой код на это:

static let playerCategory: UInt32 = 0x1 << 0  
static let boundary: UInt32 = 0x1 << 1 ​ 
​static let coinCategory: UInt32 = 0x1 << 2 ​ 
​static let bodyA: UInt32 = 0x1 << 3 ​ 
​static let bodyB: UInt32 = 0x1 << 4 

Это не поможет с вашей проблемой, но это полезно знать.

+0

Благодарим за информацию! –