从SKTileMapNode中删除特定平铺

时间:2017-04-21 11:45:05

标签: ios swift swift3 sprite-kit

enter image description here

我有Tile Map Node来覆盖整个游戏场景(GameScene.sks)。屏幕顶部有一个敌人。底部还有一些小房子。只有这些房屋来自瓷砖地图节点。敌人应该射击任何一个房子。 contactBitMask设置为射击和房屋瓷砖。我想用contactBitMask删除被拍摄的房子。无论如何,我有以下行代码。

class GameScene: SKScene, SKPhysicsContactDelegate {

    var destructibleCount = Int() // destructibleCount
    func setupDestructiblePhysics() {
        guard let obstaclesTileMap = obstaclesTileMap else { return }
        for row in 0..<obstaclesTileMap.numberOfRows {
            for column in 0..<obstaclesTileMap.numberOfColumns {
                guard let tile = tile(in: obstaclesTileMap, at: (column, row)) // a function returning SKTileDefinition
                    else { continue }
                guard tile.userData?.object(forKey: "destructible") != nil // 'destructible' is set through TileSet
                    else { continue }
                let node = SKNode()
                node.physicsBody = SKPhysicsBody(rectangleOf: tile.size)
                node.physicsBody?.isDynamic = false
                node.physicsBody?.categoryBitMask = PhysicsCategory.Building
                node.position = obstaclesTileMap.centerOfTile(atColumn: column, row: row)
                node.name = "building"
                obstaclesTileMap.addChild(node)
                destructibleCount += 1
            }
        }
    }

    func didBegin(_ contact: SKPhysicsContact) {
        let enemyBeamContact = contact.bodyA.categoryBitMask == PhysicsCategory.EnemyShot ? contact.bodyB : contact.bodyA
        switch enemyBeamContact.categoryBitMask {
        case PhysicsCategory.Building:
            if let nodeA = contact.bodyA.node {
                let column = obstaclesTileMap!.tileColumnIndex(fromPosition: nodeA.position)
                let row = obstaclesTileMap!.tileRowIndex(fromPosition: nodeA.position)
                print(column, row)
                enumerateChildNodes(withName: "building", using: { node, _ in
                    if node.position == nodeA.position {
                        node.removeFromParent()
                    }
                })

                if let tile = tile(in: obstaclesTileMap!, at: (column, row)) {
                    // not being used
                }
            }
            if let nodeB = contact.bodyB.node {
                // bullet //
                if nodeB.name == "beam" {
                    nodeB.removeFromParent()
                }
            }
        default:
            break
        }
    }
}

当一个镜头击中一个房子时,didBegin物理方法会告诉我正在击中的牌。 (见打印(列,行))。我遇到的困难是如何移除被击中的瓷砖。 node.removeFromParent()不是有效的。我无法删除任何瓷砖。我有一种感觉,你不能删除一个瓷砖。或者我们可以吗?我认为使用瓷砖是开发SpriteKit游戏的有效方式。但对我来说似乎不是这样。我想我可以以编程方式将这些房屋添加到场景中。感谢。

1 个答案:

答案 0 :(得分:1)

SKTilemapNode本身就是一个整体,所以联系测试只会告诉您何时与瓷砖地图联系,而不是单个瓷砖。

您可以做的是使用tilemap来设计关卡,但在didMove(to:)函数中,您可以遍历平铺贴图并为找到的每个房屋创建单独的SKSpriteNode。您可以使用SKTilemapNode的函数来获取所需的信息(您使用的纹理,位置等):

完成行走瓷砖地图并创建所有房屋后,从场景中移除瓷砖地图并像往常一样与房屋联系。

希望它有所帮助!