Swift3 打开和关闭物理

Swift3 打开和关闭物理,swift3,sprite-kit,collision-detection,Swift3,Sprite Kit,Collision Detection,我试图解决一个问题,一个精灵节点可以通过一个平台向上跳,但不能向下跳。我尝试使用以下代码: override func didMove(to view: SKView) { if (thePlayer.position.y > stonePlatform1.position.y) == true { stonePlatform1.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: stonePlatform

我试图解决一个问题,一个精灵节点可以通过一个平台向上跳,但不能向下跳。我尝试使用以下代码:

override func didMove(to view: SKView) {
    if (thePlayer.position.y > stonePlatform1.position.y) ==  true {
        stonePlatform1.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: stonePlatform.size.width * 0.9, height: stonePlatform.size.height * 0.75))
        stonePlatform1.physicsBody!.isDynamic = false
        stonePlatform1.physicsBody!.affectedByGravity = false
        stonePlatform1.physicsBody!.categoryBitMask = BodyType.object.rawValue
        stonePlatform1.physicsBody!.contactTestBitMask = BodyType.object.rawValue
        stonePlatform1.physicsBody!.restitution = 0.4
    }
}
这个想法是当玩家在平台上方时打开平台的物理主体。然而,当我使用这个代码时,物理根本不起作用。事实上,我尝试使用以下代码:

override func didMove(to view: SKView) {
    if (thePlayer.position.y < stonePlatform1.position.y) ==  true {
        stonePlatform1.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: stonePlatform.size.width * 0.9, height: stonePlatform.size.height * 0.75))
        stonePlatform1.physicsBody!.isDynamic = false
        stonePlatform1.physicsBody!.affectedByGravity = false
        stonePlatform1.physicsBody!.categoryBitMask = BodyType.object.rawValue
        stonePlatform1.physicsBody!.contactTestBitMask = BodyType.object.rawValue
        stonePlatform1.physicsBody!.restitution = 0.4
    }
}
override func didMove(to view:SKView){
如果(thePlayer.position.y

物理也没有打开。如果If语句不存在,那么物理总是有效的

您可以尝试从物理体开始,将其设置为
nil
,然后在玩家位于其上方后设置物理值。同样,这种代码应该在update函数中。在didMove中使用它只会让它被调用一次

override func update(_ currentTime: TimeInterval){
 if (thePlayer.position.y < stonePlatform1.position.y) && stonePlatform1.physicsBody != nil {
       stonePlatform1.physicsBody = nil
 }else if (thePlayer.position.y > stonePlatform1.position.y) && stonePlatform1.physicsBody == nil{
    setPhysicsOnPlatform(stonePlatform1)
 }
}

func setPhysicsOnPlatform(_ platform: SKSpriteNode){
   platform.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: stonePlatform.size.width * 0.9, height: stonePlatform.size.height * 0.75))
   ...
   //the rest of your physics settings
}
覆盖函数更新(\uCurrentTime:TimeInterval){
如果(thePlayer.position.ystonePlatform1.position.y)和&stonePlatform1.physicsBody==nil{
setPhysicsOnPlatform(stonePlatform1)
}
}
func setPhysicsOnPlatform(u平台:SKSpriteNode){
platform.physicsBody=SKPhysicsBody(矩形:CGSize(宽度:stonePlatform.size.width*0.9,高度:stonePlatform.size.height*0.75))
...
//其余的物理设置
}

你还应该对球员和主播的身高做一些调整。否则,如果您的主播点为(0,0),而玩家正在通过平台的一半,则将应用物理,并会出现不希望出现的结果。

您可以尝试从物理主体开始,将其设置为
nil
,然后在玩家位于其上方后将物理值设置为该主体。同样,这种代码应该在update函数中。在didMove中使用它只会让它被调用一次

override func update(_ currentTime: TimeInterval){
 if (thePlayer.position.y < stonePlatform1.position.y) && stonePlatform1.physicsBody != nil {
       stonePlatform1.physicsBody = nil
 }else if (thePlayer.position.y > stonePlatform1.position.y) && stonePlatform1.physicsBody == nil{
    setPhysicsOnPlatform(stonePlatform1)
 }
}

func setPhysicsOnPlatform(_ platform: SKSpriteNode){
   platform.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: stonePlatform.size.width * 0.9, height: stonePlatform.size.height * 0.75))
   ...
   //the rest of your physics settings
}
覆盖函数更新(\uCurrentTime:TimeInterval){
如果(thePlayer.position.ystonePlatform1.position.y)和&stonePlatform1.physicsBody==nil{
setPhysicsOnPlatform(stonePlatform1)
}
}
func setPhysicsOnPlatform(u平台:SKSpriteNode){
platform.physicsBody=SKPhysicsBody(矩形:CGSize(宽度:stonePlatform.size.width*0.9,高度:stonePlatform.size.height*0.75))
...
//其余的物理设置
}

你还应该对球员和主播的身高做一些调整。否则,如果您的主播点为(0,0),且玩家在平台中间,则将应用物理,并会出现不希望出现的结果。

您可以使用此平台的节点速度,如下所示:

SpriteKit-Swift 3代码:

private var up1 : SKSpriteNode!
private var down1 : SKSpriteNode!
private var down2 : SKSpriteNode!
private var player : SKSpriteNode!

override func didMove(to view: SKView) {
    up1 = self.childNode(withName: "up1") as! SKSpriteNode
    down1 = self.childNode(withName: "down1") as! SKSpriteNode
    down2 = self.childNode(withName: "down2") as! SKSpriteNode
    player = self.childNode(withName: "player") as! SKSpriteNode
    up1.physicsBody?.categoryBitMask = 0b0001 // Mask for UoPlatforms
    down1.physicsBody?.categoryBitMask = 0b0010 // Mask for downPlatforms
    down2.physicsBody?.categoryBitMask = 0b0010 // Same mask
}

override func update(_ currentTime: TimeInterval) {
    player.physicsBody?.collisionBitMask = 0b0000 // Reset the mask

    // For UP only Platform
    if (player.physicsBody?.velocity.dy)! < CGFloat(0.0) {
        player.physicsBody?.collisionBitMask |= 0b0001 // The pipe | operator adds the mask by binary operations
    }

    // For Down only platforms
    if (player.physicsBody?.velocity.dy)! > CGFloat(0.0) {
        player.physicsBody?.collisionBitMask |= 0b0010  // The pipe | operator adds the mask by binary operations
    }

}
private var up1:SKSpriteNode!
一等兵:斯普林泰诺德!
二等兵:斯普林泰诺德!
私人玩家:斯普林泰诺德!
覆盖func didMove(到视图:SKView){
up1=self.childNode(名称为:“up1”)作为!SKSpriteNode
down1=self.childNode(名称为“down1”)作为!SKSpriteNode
down2=self.childNode(名称为“down2”)作为!SKSpriteNode
player=self.childNode(名称为“player”)as!SKSpriteNode
up1.physicsBody?.categoryBitMask=0b0001//UO平台的掩码
down1.physicsBody?.categoryBitMask=0b0010//下行平台的掩码
down2.physicsBody?.categoryBitMask=0b0010//相同的掩码
}
覆盖函数更新(uCurrentTime:TimeInterval){
player.physicsBody?.collisionBitMask=0b0000//重置掩码
//仅限上站台
if(player.physicsBody?.velocity.dy)!CGFloat(0.0){
player.physicsBody?.collisionBitMask |=0b0010//管道|操作符通过二进制操作添加掩码
}
}
源代码和示例如下:

该示例显示: 绿色平台->仅向下 红色平台->仅向上


您可以使用此平台的节点速度,如下所示:

SpriteKit-Swift 3代码:

private var up1 : SKSpriteNode!
private var down1 : SKSpriteNode!
private var down2 : SKSpriteNode!
private var player : SKSpriteNode!

override func didMove(to view: SKView) {
    up1 = self.childNode(withName: "up1") as! SKSpriteNode
    down1 = self.childNode(withName: "down1") as! SKSpriteNode
    down2 = self.childNode(withName: "down2") as! SKSpriteNode
    player = self.childNode(withName: "player") as! SKSpriteNode
    up1.physicsBody?.categoryBitMask = 0b0001 // Mask for UoPlatforms
    down1.physicsBody?.categoryBitMask = 0b0010 // Mask for downPlatforms
    down2.physicsBody?.categoryBitMask = 0b0010 // Same mask
}

override func update(_ currentTime: TimeInterval) {
    player.physicsBody?.collisionBitMask = 0b0000 // Reset the mask

    // For UP only Platform
    if (player.physicsBody?.velocity.dy)! < CGFloat(0.0) {
        player.physicsBody?.collisionBitMask |= 0b0001 // The pipe | operator adds the mask by binary operations
    }

    // For Down only platforms
    if (player.physicsBody?.velocity.dy)! > CGFloat(0.0) {
        player.physicsBody?.collisionBitMask |= 0b0010  // The pipe | operator adds the mask by binary operations
    }

}
private var up1:SKSpriteNode!
一等兵:斯普林泰诺德!
二等兵:斯普林泰诺德!
私人玩家:斯普林泰诺德!
覆盖func didMove(到视图:SKView){
up1=self.childNode(名称为:“up1”)作为!SKSpriteNode
down1=self.childNode(名称为“down1”)作为!SKSpriteNode
down2=self.childNode(名称为“down2”)作为!SKSpriteNode
player=self.childNode(名称为“player”)as!SKSpriteNode
up1.physicsBody?.categoryBitMask=0b0001//UO平台的掩码
down1.physicsBody?.categoryBitMask=0b0010//下行平台的掩码
down2.physicsBody?.categoryBitMask=0b0010//相同的掩码
}
覆盖函数更新(uCurrentTime:TimeInterval){
player.physicsBody?.collisionBitMask=0b0000//重置掩码
//仅限上站台
if(player.physicsBody?.velocity.dy)!CGFloat(0.0){
player.physicsBody?.collisionBitMask |=0b0010//管道|操作符通过二进制操作添加掩码
}
}
带有exa的源代码