使用PhysicsBodys的基本Swift SpriteKit碰撞 [英] Basic Swift SpriteKit Collisions using PhysicsBodys

查看:116
本文介绍了使用PhysicsBodys的基本Swift SpriteKit碰撞的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题:我似乎在让玩家与硬币碰撞时遇到了一些麻烦,并在碰撞时向硬币标签添加了+1。玩家接触硬币后应继续移动。

The problem: I seem to be having a little trouble getting my player to collide with a coin, and adding +1 to a coinLabel upon the collision. The player should continue moving after coming in contact with the coin.

我现在拥有的东西:有了我现在拥有的代码,玩家便可以旅行穿过硬币,但没有发生碰撞,并且+1没有添加到硬币标签中。

What I have now: With the code I have now, the player travels through the coin, but there is no collision that takes place and +1 isn't added to the coin label.

我仍在学习快速语言,因此,我感谢提供的任何帮助。

I am still learning the swift language, so I appreciate any help that is given.

代码:

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)

}
    ​        
​}


推荐答案

保持您的contactTestBitmasks不变,但删除玩家和硬币之间的冲撞位:

You could try leaving your contactTestBitmasks the same but remove the collisionBitmasks between the player and coin:

player.physicsBody?.categoryBitMask = ColliderType.playerCategory
​player.physicsBody?.contactTestBitMask = ColliderType.boundary
player.physicsBody?.collisionBitMask = ColliderType.boundary


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

这样,当玩家发生碰撞时

This way, when the player collides with a coin it will register, but it wont "bounce off" and will continue moving in the same direction.

*注:使用此硬币可能要求您使用

*Note: Using this MAY require you to use the

func didBeginContact(contact: SKPhysicsContact) {

代替方法

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

但是我建议您先使用didPlayerCollideWithCoin()方法尝试。

But I recommend trying it with the didPlayerCollideWithCoin() method first.

func didBeginContact(contact: SKPhysicsContact) {

var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody

if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
  firstBody = contact.bodyA
  secondBody = contact.bodyB
} else {
 firstBody = contact.bodyB
 secondBody = contact.bodyA
}

if firstBody.categoryBitMask == playerCategory &&   secondBody.categoryBitMask == coinCategory {
print("Your player passes through the coin")
score = score + 1
}
}

有关更多详细信息,请参见Ray Wenderlich的本教程:
https://www.raywenderlich.com/123393/how-to-create-a-breakout游戏与精灵工具包和迅捷游戏

For more details see this tutorial from Ray Wenderlich: https://www.raywenderlich.com/123393/how-to-create-a-breakout-game-with-sprite-kit-and-swift

这篇关于使用PhysicsBodys的基本Swift SpriteKit碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆