代码之家  ›  专栏  ›  技术社区  ›  Burundanga

如何检测有关精灵纹理的接触

  •  2
  • Burundanga  · 技术社区  · 9 年前

    我有一颗子弹应该向街区射击。子弹有6种不同的随机纹理来模拟不同的子弹。块有3个不同的纹理,随机选择,看起来就像有3个块。我想在代码中指定,如果子弹纹理是红色的,而方块纹理是红色,那么分数应该增加,但如果子弹是红色的而方块是绿色的,那么游戏就结束了。我真的不知道如何在didBeginContact中告诉游戏这样做。

    现在我有了这个: 在GameScene中&did移动到视图:

    struct PhysicsCategory {
    static let None      : UInt32 = 0
    static let All       : UInt32 = UInt32.max
    static let CgyBlock  : UInt32 = 0b1       
    static let Bullet    : UInt32 = 0b10
    }
    
    bullet.physicsBody = SKPhysicsBody(texture: bullet.texture, size: self.bullet.size)
    bullet.physicsBody?.categoryBitMask = PhysicsCategory.Bullet
    bullet.physicsBody?.contactTestBitMask = PhysicsCategory.CgyBlock
    bullet.physicsBody?.collisionBitMask = PhysicsCategory.None
    bullet.physicsBody?.affectedByGravity = false
    bullet.physicsBody?.usesPreciseCollisionDetection = true
    

    在didBeginContact中:

    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 & PhysicsCategory.CgyBlock != 0) &&
            (secondBody.categoryBitMask & PhysicsCategory.Bullet != 0)) 
      //and here I suppose I need to implement somehow something like
     // && (bullet.texture = "redBullet") && (CgyBlock.texture = "greenBlock" || "blackBlock")
     {
       gameOver()        
        }
    

    但我知道这行不通。我还尝试在大括号内使用switch语句,但也不起作用。如何实施?

    更新: 这是如何制作块的:

    var cgyBlock = SKSpriteNode()
    
    let cgyArray = ["cyanBox", "greenBox", "yellowBox"]
    
    func addCgyLine () {
        cgyBlock = SKSpriteNode(imageNamed: "cyanBox")
        var randomCGY = Int(arc4random_uniform(3))
        cgyBlock.texture = SKTexture(imageNamed: cgyArray[randomCGY])
    
        cgyBlock.physicsBody = SKPhysicsBody(texture: cgyBlock.texture, size: cgyBlock.size)
        cgyBlock.physicsBody?.dynamic = true
        cgyBlock.physicsBody?.categoryBitMask = PhysicsCategory.CgyBlock
        cgyBlock.physicsBody?.contactTestBitMask = PhysicsCategory.Bullet
        cgyBlock.physicsBody?.collisionBitMask = PhysicsCategory.None
    
        cgyBlock.position = CGPointMake(size.width + cgyBlock.size.width/2, CGRectGetMidY(self.frame) + 60) 
        addChild(cgyBlock)
    
        let actionMove = SKAction.moveTo(CGPoint(x: -cgyBlock.size.width/2, y: CGRectGetMidY(self.frame) + 60), duration: 3) 
        let actionDone = SKAction.removeFromParent()
        cgyBlock.runAction(SKAction.sequence([actionMove, actionDone]))
        SKActionTimingMode.EaseOut
    }
    

    然后我在didMoveToView中运行Action。

    项目符号:

    var cannon = SKSpriteNode(imageNamed: "cannon")
    var bulletInCannon = SKSpriteNode()
    var bullet = SKSpriteNode()
    
    let bulletArray = ["redBullet","magentaBullet", "blueBullet", "cyanBullet", "greenBullet", "yellowBullet"]
    
    //didMoveToView:
     var randomBullet = Int(arc4random_uniform(6))
     bulletInCannon = SKSpriteNode(imageNamed: bulletArray[randomBullet])
     bulletInCannon.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
     addChild(bulletInCannon)
    
     //touchesEnded:
    var randomBullet = Int(arc4random_uniform(6))
            bullet = SKSpriteNode(texture: bulletInCannon.texture)
            bullet.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
            bullet.name = bulletArray[randomBullet]
            bullet.physicsBody = SKPhysicsBody(texture: bullet.texture, size: self.bullet.size)
            bullet.physicsBody?.dynamic = true
            bullet.physicsBody?.categoryBitMask = PhysicsCategory.Bullet
            bullet.physicsBody?.contactTestBitMask = PhysicsCategory.CgyBlock
            bullet.physicsBody?.collisionBitMask = PhysicsCategory.None
            bullet.physicsBody?.affectedByGravity = false
            bullet.physicsBody?.usesPreciseCollisionDetection = true
    
            addChild(bullet)
     bulletInCannon.texture = SKTexture(imageNamed: bulletArray[randomBullet])
    
    2 回复  |  直到 9 年前
        1
  •  2
  •   Whirlwind    9 年前

    几条路可走:

    1. 可以使用节点的 userData 所有物

      bullet.userData = ["type" : "white"]
      

      要访问它:

      println(bullet.userData?["type"])
      
    2. 您可以创建作为SKSpriteNode子类的自定义Bullet类,并创建名为“type”的属性,然后在didBeginContact中访问该属性。

      class Bullet: SKSpriteNode {
      
          var type:String = ""
      
      
           init(type:String) {
               self.type = type //later you are accessing this with bulletNode.type
              //This is just an simple example to give you a basic idea  what you can do.
              //In real app you should probably implement some kind of security check to avoid wrong type
              let texture = SKTexture(imageNamed: type)
      
              super.init(texture: texture, color: nil, size: texture.size())
          }
      
          required init(coder aDecoder: NSCoder) {
              fatalError("init(coder:) has not been implemented")
          }
      }
      
    3. 您可以使用 bullet.name 属性,并在创建时根据项目符号/块颜色进行适当设置。稍后在didBeginContact中,您将检查 项目符号名称 找出子弹的类型。街区也是如此。

      func spawnBulletWithType(type:String) -> SKSpriteNode{
      
           //set texture based on type
           //you can pass here something like white_bullet
      
           let atlas = SKTextureAtlas(named: "myAtlas")
      
      
           //here, if passed white_bullet string, SpriteKit will search for texture called white_bullet.png
           let bullet = SKSpriteNode(texture:atlas.textureNamed(type))
      
      
           bullet.name = type // name will be white_bullet, and that is what you will search for in didBeginContact
      
           bullet.physicsBody = SKPhysicsBody(texture: bullet.texture, size: bullet.size)
           bullet.physicsBody?.categoryBitMask = PhysicsCategory.Bullet
           bullet.physicsBody?.contactTestBitMask = PhysicsCategory.CgyBlock
           bullet.physicsBody?.collisionBitMask = PhysicsCategory.None
           bullet.physicsBody?.affectedByGravity = false
           bullet.physicsBody?.usesPreciseCollisionDetection = true
      
           return bullet
      }
      

    编辑:

    根据您最近的评论,您可能会这样做:

    let bulletArray = ["redBullet","magentaBullet", "blueBullet", "cyanBullet", "greenBullet", "yellowBullet"]
    
    //didMoveToView:
     var randomBullet = Int(arc4random_uniform(6))
     let bulletType = bulletArray[randomBullet]
     bulletInCannon.name = bulletType
     bulletInCannon = SKSpriteNode(imageNamed: bulletType )
     bulletInCannon.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
     addChild(bulletInCannon)
    
    
    //touchesEnded:
    var randomBullet = Int(arc4random_uniform(6))
            bullet = SKSpriteNode(texture: bulletInCannon.texture)
            bullet.name = bulletInCannon.name
            bullet.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
    
            bullet.physicsBody = SKPhysicsBody(texture: bullet.texture, size: self.bullet.size)
            bullet.physicsBody?.dynamic = true
            bullet.physicsBody?.categoryBitMask = PhysicsCategory.Bullet
            bullet.physicsBody?.contactTestBitMask = PhysicsCategory.CgyBlock
            bullet.physicsBody?.collisionBitMask = PhysicsCategory.None
            bullet.physicsBody?.affectedByGravity = false
            bullet.physicsBody?.usesPreciseCollisionDetection = true
    
            addChild(bullet)
    let bulletType = bulletArray[randomBullet]
     bulletInCannon.texture = SKTexture(imageNamed: bulletType)
     bulletInCannon.name = bulletType
    
        2
  •  1
  •   Iman Nia    9 年前

    首先,您需要为项目符号和块定义一个类 然后,可以定义一个TextureTypes来存储纹理类型(红色、绿色),并将随机方法生成的任何属性设置为该类型的类变量。 然后,您应该管理联系人并找出BodyA和BodyB的节点。之后,可以根据节点的文本类型轻松地进行任何您喜欢的操作,

    为了澄清代码,我将纹理定义为新类型

    enum TextureTypes: String {
        case Red,Green 
        var description:String {
            switch self {
            case Red:return “Red"
            case Green:return “Green”
            case Green:return “Blue"
            }
        }
    }
    

    Blockclass和BulletClass都必须从SKNode继承,因为它们是一个节点!

    class BlockClass:SKNode {
        var NodesTexture : TextureTypes = TextureTypes.Red
    }
    
    class BulletClass:SKNode {
        var NodesTexture : TextureTypes = TextureTypes.Red
    }
    

    将以下代码写入 didBeginContact 方法检测节点的TextureType

        if (contact.bodyA.categoryBitMask == PhysicsCategory.Bullet) &&    
           (contact.bodyB.categoryBitMask == PhysicsCategory.CgyBlock)
        {
            Ablock = (BlockClass *) contact.bodyB.node;
            Abullet = (BulletClass *) contact.bodyA.node;
        }
        if (contact.bodyA.categoryBitMask == PhysicsCategory.CgyBlock) &&    
           (contact.bodyB.categoryBitMask == PhysicsCategory.Bullet)
        {
            Ablock = (BlockClass *) contact.bodyA.node;
            Abullet = (BulletClass *) contact.bodyB.node;
            if ( Ablock.NodesTexture = TextureTypes.Red )
            {
                NSLOG(“A Red Block Detected”)
    
            }
        } 
    

    不要忘记定义BlocksClass和BulletClass类型的块和项目符号