我正在嘗試在 SpriteKit 中構建一個帶有圓角的漸變進度條,但我完全卡在了這一點上。我嘗試了 SKCropNode、SKShapeNodes 等的不同組合,但我似乎無法讓它作業。任何幫助表示贊賞,親切的問候!
uj5u.com熱心網友回復:
這是關于 SKCropNode 它的 maskNode 屬性。從檔案:
SKCropNode 是一個容器節點,用于裁剪場景中的其他節點。您將其他節點添加到裁剪節點并設定裁剪節點的 maskNode 屬性。例如,以下是您可以指定掩碼的一些方法:
將內容限制在場景的矩形部分的無紋理精靈。
用作精確的每像素蒙版的紋理精靈。
形成獨特形狀的子節點的集合。
您可以為遮罩的形狀或內容設定影片,以實作有趣的效果,例如隱藏或顯示。
所以,一個簡單的例子是這樣的:
class GameScene: SKScene {
override func sceneDidLoad() {
super.sceneDidLoad()
createProgressBar()
}
private func createProgressBar(){
let barFrame = CGRect(x: 0, y: 0, width: 300, height: 15)
if let cgImage = createImage(frame: barFrame) {
let texture = SKTexture(cgImage: cgImage)
let sprite = SKSpriteNode(texture: texture)
let cropNode = SKCropNode()
let mask = SKSpriteNode(color: .gray, size: barFrame.size)
cropNode.addChild(sprite)
cropNode.maskNode = mask
sprite.anchorPoint = CGPoint(x: 0.0, y: 0.5)
mask.anchorPoint = CGPoint(x: 0.0, y: 0.5)
var counter:Double = 0
let action = SKAction.run {[weak self, sprite] in
guard let `self` = self, counter < 100 else {
sprite?.removeAction(forKey: "loop")
return
}
counter = 1
let newWidth = self.getWidth(percents: counter, spriteWidth: barFrame.width)
print("Bar width \(newWidth), percentage \(counter)")
mask.size = CGSize(width: newWidth, height: barFrame.height)
}
let wait = SKAction.wait(forDuration: 0.05)
let sequence = SKAction.sequence([wait, action])
let loop = SKAction.repeatForever(sequence)
addChild(cropNode)
cropNode.position = CGPoint(x: self.frame.width / 2.0, y: self.frame.height / 2.0)
sprite.run(loop, withKey: "loop")
}
}
private func getWidth(percents:Double, spriteWidth:Double)->Double{
let onePercent = spriteWidth / 100.0
return onePercent * percents
}
private func createImage(frame barFrame:CGRect) -> CGImage?{
if let ciFilter = CIFilter(name: "CILinearGradient"){
let ciContext = CIContext()
ciFilter.setDefaults()
let startColor = CIColor(red: 0.75, green: 0.35, blue: 0.45, alpha: 1)
let endColor = CIColor(red: 0.45, green: 0.35, blue: 0.75, alpha: 1)
let startVector = CIVector(x: 0, y: 0)
let endVector = CIVector(x: barFrame.width, y: 0)
ciFilter.setValue(startColor, forKey: "inputColor0")
ciFilter.setValue(endColor, forKey: "inputColor1")
ciFilter.setValue(startVector, forKey: "inputPoint0")
ciFilter.setValue(endVector, forKey: "inputPoint1")
if let outputImage = ciFilter.outputImage {
let cgImage = ciContext.createCGImage(outputImage, from: CGRect(x: 0, y: 0, width: barFrame.width, height: barFrame.height))
return cgImage
}
}
return nil
}
}
Now cause this is just an example I won't go all the way to implement this right, but You can maybe make a class of it with designable and inspectable properties, optimize code, make it reusable etc. But the general idea is shown here.
You use SKCropNode to add progress bar in it, and use maskNode property to reveal progress bar as percentage increases. Also I gave a method to create texture programatically, but You can use just a .png file instead.
Crop node is here used only cause of a gradient (cause we don't wan't to scale image, but rather to show it part by part). Obviously, crop node is not needed if a progress bar had only one color.
Here is final result:

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/433741.html
下一篇:如何在Swift中使用UIImagePickerController旋轉cameraOverlayView上的影像
