簡體   English   中英

帶圓角的漸變進度條 SpriteKit Swift

[英]Gradient progress bar with rounded corners SpriteKit Swift

我正在嘗試在 SpriteKit 中構建一個帶有圓角的漸變進度條,但我完全卡在了這一點上。 我已經嘗試了 SKCropNode、SKShapeNodes 等的不同組合,但我似乎無法讓它工作。 任何幫助表示贊賞,親切的問候!

這是關於 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
      

  }
}

現在因為這只是一個例子,我不會 go 一路實現這個權利,但你可以制作一個 class 具有可設計和可檢查的屬性,優化代碼,使其可重用等。但總體思路顯示在這里.

您使用SKCropNode在其中添加進度條,並使用maskNode屬性在百分比增加時顯示進度條。 我還提供了一種以編程方式創建紋理的方法,但您可以只使用 .png 文件。

裁剪節點在這里僅用於梯度的原因(因為我們不想縮放圖像,而是逐部分顯示它)。 顯然,如果進度條只有一種顏色,則不需要裁剪節點。

這是最終結果:

進度條

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM