2017-08-09 63 views
1

這是我第一次在iOS上製作遊戲,所以我自然遇到了一些問題。我已經成功地解決這些問題,但現在,它來到馬里奧,我遇到了一些麻煩的管之間的碰撞部:Sprite套件中的碰撞檢測Swift

我想這樣做:

當馬里奧與管道碰撞,他將不得不跳過他們去對方。如果他不這樣做,那麼管道將繼續「推」他到遊戲結束的屏幕邊緣。

實際發生了什麼:

沒有發現任何碰撞。

這裏是下面的代碼:

import SpriteKit 
import GameplayKit 

class GameScene: SKScene, SKPhysicsContactDelegate { 

    var mario = SKSpriteNode() 

    enum ColliderType: UInt32 { 

     case Mario = 1 
     case Object = 2 
    } 

    func addPipes() { 

     let pipetexture = SKTexture(imageNamed: "pipes") 

     let pipes = SKSpriteNode(texture: pipetexture) 

     let setScale = CGFloat(arc4random_uniform(19) + 15) 

     pipes.setScale(setScale) //min 15, max 19 

     pipes.position = CGPoint(x: self.frame.maxX, y: self.frame.minY) 

     let movePipes = SKAction.move(by: CGVector(dx: -5 * self.frame.width, dy: 0), duration: TimeInterval(self.frame.width/100)) 

     let removePipes = SKAction.removeFromParent() 

     let moveAndRemovePipes = SKAction.sequence([movePipes, removePipes]) 

     pipes.zPosition = +1 

     pipes.physicsBody = SKPhysicsBody(rectangleOf: pipes.size) 

     pipes.physicsBody!.isDynamic = false 

     pipes.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue 
     pipes.physicsBody!.categoryBitMask = ColliderType.Object.rawValue 
     pipes.physicsBody!.collisionBitMask = ColliderType.Mario.rawValue 

     self.addChild(pipes) 

     pipes.run(moveAndRemovePipes) 

    } 

    func didBegin(_ contact: SKPhysicsContact) { 
     print("contact") 
    } 

    override func didMove(to view: SKView) { 

     self.physicsWorld.contactDelegate = self 

     _ = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.addPipes), userInfo: nil, repeats: true) 

     let marioTexture = SKTexture(imageNamed: "mariorun0.png") 
     let marioTexture2 = SKTexture(imageNamed: "mariorun1.png") 
     let marioTexture3 = SKTexture(imageNamed: "mariorun2.png") 

     let animation = SKAction.animate(with: [marioTexture, marioTexture2, marioTexture3], timePerFrame: 0.1) 

     let makeMarioRun = SKAction.repeatForever(animation) 

     mario = SKSpriteNode(texture: marioTexture) 

     mario.setScale(10) 

     mario.position = CGPoint(x: -(self.frame.size.width/3.5), y: -(self.frame.size.height/2.8)) 

     mario.run(makeMarioRun) 

     mario.physicsBody = SKPhysicsBody(rectangleOf: mario.size) 

     mario.physicsBody!.isDynamic = false 

     mario.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue 
     mario.physicsBody!.categoryBitMask = ColliderType.Mario.rawValue 
     mario.physicsBody!.collisionBitMask = ColliderType.Object.rawValue 

     self.addChild(mario) 


     addPipes() 

     mario.zPosition = +2 

    } 

} 

我還實施了跳躍功能完美的作品。我的問題是,我不能在管道和馬里奧之間進行碰撞檢測。

我曾嘗試將兩個精靈的z位置設置爲相同的值,但沒有任何運氣。

我最初的擔心是圖像很小,因此幾乎不可能檢測到碰撞。但是,由於我擴大了兩個節點,並使用放大圖像的物理體,所以不存在問題,但這也沒有幫助。

感謝您的幫助提前。

+0

這行代碼是不必要的:'pipes.physicsBody!.contactTestBitMask = ColliderType .Object.rawValue'。首先,這意味着管道在與自己聯繫時通知管道,但是如果您已正確設置Mario與管道接觸,則可以刪除此管道,因此沒有必要讓管道與Mario聯繫。您已正確設置了碰撞。 –

回答

0

physicsBody!.isDynamic = false表示該物體不會發生任何物理活動。其他機構可以與它互動,但它不會與任何事物互動。

這對管道來說是有意義的,因爲管道永遠不會移動,所以沒有理由是動態的。 (如果你正在做一個flappy bird-esc遊戲,你的世界應該移動,而不是管道)

現在對於馬里奧來說,這沒有任何意義。馬里奧是一個移動的實體,所以他將與周圍的物理世界進行交互。要解決你的問題,你需要讓他動態mario.physicsBody!.isDynamic = true

+0

這就是我需要的,謝謝! –