2014-12-20 6 views
4

Обнаружение столкновений довольно просто в Swift - но в этом конкретном проекте, столкновение тела не вызывает событие didBeginContact, как обычно.Обнаружение столкновения между двумя объектами в Swift

Вот мой список для двух тел, сталкивающихся (с помощью солдат и пули):

  1. Добавить SKPhysicsContactDelegate к классу.
  2. установить физический мир соответственно, обычно: self.physicsWorld.contactDelegate = self
  3. Создайте категории для каждой группы узлов, которые у вас будут. Например. let bulletCategory = 0x1 << 0
  4. Создайте SKNodes для каждой пули и солдата.
  5. Дайте каждой пуле и солдату физическое тело с соответствующей формой.
  6. Установите каждую категорию Bullet categoryBitMask на bulletCategory (солдаты настроены на солдатскую категорию).
  7. Установите каждую контактную карту пули на soldierCategory (солдаты настроены на bulletCategory).
  8. Определить didBeginContact() обработчик.

Ниже приводится мой полный код. Это минимальная ~ 20 строк «Hello World» для столкновения.

Если вы создадите новую «Игру» и скопируйте ее в GameScene.swift, она будет запущена, только никакие события столкновения не будут запущены.

// 
// GameScene.swift 
// Thesoldier 
// 
// Created by Donald Pinkus on 12/19/14. 
// Copyright (c) 2014 Don Pinkus. All rights reserved. 
// 

import SpriteKit 

class GameScene: SKScene, SKPhysicsContactDelegate { 
    var soldier = SKShapeNode(circleOfRadius: 40) 

    let soldierCategory:UInt32 = 0x1 << 0; 
    let bulletCategory:UInt32 = 0x1 << 1; 

    override func didMoveToView(view: SKView) { 
     self.physicsWorld.contactDelegate = self 

     // THE soldier 
     soldier.fillColor = SKColor.redColor() 
     soldier.position = CGPoint(x: CGRectGetMidX(self.frame), y: 40) 
     soldier.physicsBody = SKPhysicsBody(circleOfRadius: 20) 
     soldier.physicsBody!.dynamic = false 
     soldier.physicsBody!.categoryBitMask = soldierCategory 
     soldier.physicsBody!.contactTestBitMask = bulletCategory 
     soldier.physicsBody!.collisionBitMask = 0 


     // bulletS 
     var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("makeBullet"), userInfo: nil, repeats: true) 

     self.addChild(soldier) 
    } 

    func makeBullet() { 
     var bullet = SKShapeNode(rect: CGRect(x: CGRectGetMidX(self.frame), y: self.frame.height, width: 10, height: 40), cornerRadius: CGFloat(0)) 
     bullet.fillColor = SKColor.redColor() 

     bullet.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 10, height: 40)) 
     bullet.physicsBody?.dynamic = false 
     bullet.physicsBody?.categoryBitMask = bulletCategory 
     bullet.physicsBody?.contactTestBitMask = soldierCategory 
     bullet.physicsBody?.collisionBitMask = soldierCategory 

     var movebullet = SKAction.moveByX(0, y: CGFloat(-400), duration: 1) 
     var movebulletForever = SKAction.repeatActionForever(movebullet) 
     bullet.runAction(movebulletForever) 

     self.addChild(bullet) 
    } 

    func didBeginContact(contact: SKPhysicsContact) { 
     println("CONTACT") 

    } 

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) { 
     /* Called when a touch begins */ 
    } 

    override func update(currentTime: CFTimeInterval) { 
     /* Called before each frame is rendered */ 
    } 
} 
+0

Подождите секунду. Если физическое устройство не является «динамическим», оно не может столкнуться ни с чем? –

ответ

5

Вот несколько пунктов, отсутствующих в контрольном списке:

  1. Один из физических тел должны быть динамичными
  2. Физического тела должен быть перемещен с помощью силы/импульса или установив их скорости
  3. Положения физических тел должны соответствовать их соответствующим узлам спрайта/формы

Для (2), вы перемещаете каждую пулю, меняя свое положение с течением времени на SKAction.

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

var bullet = SKShapeNode(rectOfSize: CGSizeMake(10, 40)) 
    bullet.position = CGPointMake(self.size.width/2.0, self.size.height) 

Также физическое тело солдата имеет половину радиуса его формы.

+0

Это потрясающе, спасибо. Есть ли способ, чтобы я мог отлаживать или видеть позиции физических тел? Я хочу посмотреть, как они перемещаются/устанавливаются иначе, чем объекты, но я не могу их покрасить. –

+1

Установите 'view.showsPhysics = true' в' didMoveToView' или в вашем контроллере вида. – 0x141E

+0

Должны ли оба физиологических тела быть динамичными? В другом проекте я сделал клон FlappyBirdy, и только один объект является динамическим (птица), в то время как трубы не являются динамическими и просто перемещаются с помощью 'SKAction.moveByX()', контактное событие все еще происходит –