我们假设我们将相同的节点添加大约1000次,如下面的代码所示。有没有办法访问每个平台?
例如,如果PlatformCategory
和PlayerCategory
之间发生碰撞,则发生碰撞的平台应将其颜色更改为绿色并运行SKAction
。
编辑:感谢Whirlwind,我可以让与玩家相撞的平台变为绿色,而其他所有人都保持红色。现在我需要正确设置碰撞,这意味着我只希望Player
在Platform
高于它时与class GameScene: SKScene, SKPhysicsContactDelegate {
let PlayerCategory : UInt32 = 0x1 << 1
let PlatformCategory : UInt32 = 0x1 << 2
var Platform: SKSpriteNode!
var Player: SKSpriteNode!
override func didMoveToView(view: SKView) {
/* Setup your scene here */
self.physicsWorld.contactDelegate = self
self.physicsBody?.velocity = CGVectorMake(0, 0)
.....
SpawnPlayer()
generatePlatforms()
}
func SpawnPlatforms(position: CGPoint)->SKSpriteNode{
Platform = SKSpriteNode(color: SKColor.redColor(), size: CGSize(width: self.frame.size.width, height: 25))
Platform.position = position
Platform.zPosition = 1
Platform.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: self.frame.size.width, height: 25))
Platform.physicsBody?.dynamic = false
Platform.physicsBody?.restitution = 0.0
Platform.physicsBody?.allowsRotation = false
Platform.physicsBody?.usesPreciseCollisionDetection = true
Platform.physicsBody?.categoryBitMask = PlatformCategory
Platform.physicsBody?.contactTestBitMask = PlayerCategory
Platform.physicsBody?.collisionBitMask = PlayerCategory
return Platform
}
func generatePlatforms(){
for i in 1...1000{
let position = CGPoint(x: self.frame.size.width / 2, y: 140 * CGFloat(i))
let platform = SpawnPlatforms(position)
self.addChild(platform)
}
}
func didBeginContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
let platform = contact.bodyB.node as! SKSpriteNode
switch(contactMask) {
case PlayerCategory | PlatformCategory:
//either the contactMask was the bro type or the ground type
print("Contact Made0")
if(Player.position.y >= platform.position.y && Player.position.y <= platform.position.y + Player.size.height){
Player.physicsBody?.collisionBitMask = PlatformCategory
platform.color = SKColor.greenColor()
}
default:
return
}
}
func didEndContact(contact: SKPhysicsContact) {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch(contactMask) {
case PlayerCategory | PlatformCategory:
//either the contactMask was the bro type or the ground type
print("Contact Made0")
default:
return
}
}
发生碰撞。
例如,播放器从1.平台跳转到2.平台。在跳跃时,它不应该在第二个平台通过之后与第二平台发生碰撞。
<Grid x:Name="SourceGrid13"
CanDrag="True"
DragStarting="SourceGrid_DragStarting"
Margin="0,20,0,0">
答案 0 :(得分:1)
正如我所说,要检测联系以改变平台的颜色,你必须做一些事情:
符合SKPhysicsDelegate协议
此任务的语法很简单:
class GameScene: SKScene,SKPhysicsContactDelegate
{//your GameScene properties and methods go here...}
符合协议意味着类必须实现该协议所需的方法。特定于SKPhysicsDelegate协议的方法是didBeginContact和didEndContact。如果你查看头文件,你会看到:
protocol SKPhysicsContactDelegate : NSObjectProtocol {
optional func didBeginContact(contact: SKPhysicsContact)
optional func didEndContact(contact: SKPhysicsContact)
}
即使这些方法是可选的,我们也需要它们来获取描述联系人的联系对象。
设置physicsWorld联系委托属性
唯一需要的代码是:
self.physicsWorld.contactDelegate = self //self is a scene (eg. GameScene)
因此,当在物理世界中发生物理接触时,我们应该以某种方式得到通知。根据文档,contactDelegate属性是在发生联系时调用的委托。通过将场景设置为联系代表,我们将联系处理的责任委托给它。这应该提到didBeginContact。
以下是如何实现它的方法(可能还有更多方法):
func didBeginContact(contact: SKPhysicsContact) {
var firstBody, 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 & CharacterCategory) != 0 &&
(secondBody.categoryBitMask & PlatformCategory != 0)) {
//secondBody would be a platform
}
}
}
在这里,您可以轻松更改一个平台的颜色,如下所示:
let platform = secondBody.node as SKSpriteNode
platform.color = UIColor.redColor()
或者您可以更改所有平台的颜色:
self.enumerateChildNodesWithName("platform", usingBlock: {
node, stop in
var platformNode = node as SKSpriteNode
platformNode.color = UIColor.redColor()
})
我也看到你正在使用这个问题的代码:
https://stackoverflow.com/a/31454044/3402095
所以我编辑了它(更改了didBeginContact),向您展示如何将精灵的颜色更改为红色。