一種選擇是,敷個面膜,並渲染到圖像和更新SKSpriteNode's
質感。然後使用該紋理來確定物理體。但是這個過程不會很高效。
例如在touchesBegan
你可以這樣說:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
guard let touch = touches.first else { return }
if let node = self.nodeAtPoint(touch.locationInNode(self.scene!)) as? SKSpriteNode{
let layer = self.layerFor(touch, node: node) // We'll use a helper function to create the layer
let image = self.snapShotLayer(layer) // Helper function to snapshot the layer
let texture = SKTexture(image:image)
node.texture = texture
// This will map the physical bounds of the body to alpha channel of texture. Hit in performance
node.physicsBody = SKPhysicsBody(texture: node.texture!, size: node.size)
}
}
在這裏,我們剛剛得到的節點,並期待在第一次觸摸,可以推廣到允許多點觸控,但我們再創建一個圖層帶有透明度的新圖像,然後創建一個紋理,然後更新節點的物理體。
對於創建層,你可以這樣說:
func layerFor(touch: UITouch, node: SKSpriteNode) -> CALayer
{
let touchDiameter:CGFloat = 20.0
let layer = CALayer()
layer.frame = CGRect(origin: CGPointZero, size: node.size)
layer.contents = node.texture?.CGImage()
let locationInNode = touch.locationInNode(node)
// Convert touch to layer coordinate system from node coordinates
let touchInLayerX = locationInNode.x + node.size.width * 0.5 - touchDiameter * 0.5
let touchInLayerY = node.size.height - (locationInNode.y + node.size.height * 0.5) - touchDiameter * 0.5
let circleRect = CGRect(x: touchInLayerX, y: touchInLayerY, width: touchDiameter, height: touchDiameter)
let circle = UIBezierPath(ovalInRect: circleRect)
let shapeLayer = CAShapeLayer()
shapeLayer.frame = CGRect(x: 0.0, y: 0.0, width: node.size.width, height: node.size.height)
let path = UIBezierPath(rect: shapeLayer.frame)
path.appendPath(circle)
shapeLayer.path = path.CGPath
shapeLayer.fillRule = kCAFillRuleEvenOdd
layer.mask = shapeLayer
return layer
}
在這裏,我們只設置當前紋理的CALayer
的內容,那麼我們創造,我們要創建蒙一個CAShapeLayer
。我們希望遮罩對於大部分圖層都是不透明的,但我們需要一個透明圓,所以我們創建一個矩形的路徑,然後向它添加一個圓。我們將fillRule
設置爲kCAFillRuleEvenOdd
以填充除我們圈子以外的所有內容。
最後,我們將該圖層渲染到可用於更新紋理的UIImage。
func snapShotLayer(layer: CALayer) -> UIImage
{
UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, 0.0)
let context = UIGraphicsGetCurrentContext()
layer.renderInContext(context!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
也許有人會提供實現這個更高性能的方式,但我認爲這會爲很多的情況下工作。
物理體對節點的視覺外觀沒有影響。你是否試圖削減節點中的視覺洞,物理體中的物理洞或兩者? – andyvn22
我試圖削減 –