Swift SpriteKit基本接触/碰撞 [英] Swift SpriteKit basic Contact / Collision

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

问题描述

问题:当硬币生成时,其PhysicalBody出现在spriteNode的正下方。同样,当玩家接触到硬币的PhysicsBody时,玩家会从PhysicsBody弹起并结束游戏。

The problem: When the coin spawns, it's physicsBody appears right underneath the spriteNode. Also, when the player comes in contact with the coin's physicsBody, the player bounces off of the physicsBody and the game ends.

输出应为:硬币的physisBody应该与硬币spriteNode正确对齐。当玩家接触硬币时,硬币应该消失,并且+1应该添加到正确的标签上。

What the output should be: The coin's physisBody should be aligned properly with the coin spriteNode. When the player comes in contact with the coin, the coin should disappear and +1 should be added to the proper label.

当前代码:

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)

}

}


推荐答案

我建议您首先阅读这些文档!

I would recommend that you read these documentation first!

contactTestBitMask -一个掩码,用于定义哪些类别的物体导致与当前物理物体的相交通知。

contactTestBitMask - A mask that defines which categories of bodies cause intersection notifications with a current physics body.


当两个主体共享相同的空间时,通过执行逻辑
AND操作,相对于另一个主体的接触罩测试每个主体的类别掩码
。如果任一比较结果都为非零值,则会创建
SKPhysicsContact对象,并将其传递给物理世界的
委托。为了获得最佳性能,请仅在联系人掩码中设置您感兴趣的
交互的位。

When two bodies share the same space, each body’s category mask is tested against the other body’s contact mask by performing a logical AND operation. If either comparison results in a nonzero value, an SKPhysicsContact object is created and passed to the physics world’s delegate. For best performance, only set bits in the contacts mask for interactions you are interested in.

collisionBitmask -掩膜定义可以与该物理物体碰撞的类别。

collisionBitmask - A mask that defines which categories of physics bodies can collide with this physics body.


当两个物理物体相互接触时,可能会发生碰撞。
通过执行逻辑与运算,将该人体的防撞面具与其他人体的
面具进行比较。如果结果是非零的
值,则此主体受碰撞影响。每个机构
独立地选择是否要受到另一个机构的影响。对于
的示例,您可以使用它来避免碰撞计算,该碰撞计算会使
对物体的速度产生可忽略的变化。

When two physics bodies contact each other, a collision may occur. This body’s collision mask is compared to the other body’s category mask by performing a logical AND operation. If the result is a nonzero value, this body is affected by the collision. Each body independently chooses whether it wants to be affected by the other body. For example, you might use this to avoid collision calculations that would make negligible changes to a body’s velocity.

删除此代码以解决冲突问题

coin.physicsBody?.collisionBitMask = ColliderType.playerCategory

尝试看看这是否解决了您的SpriteNode对齐问题

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

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

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