xcode 从格斗明星复制背景行为

fzwojiic  于 2023-02-05  发布在  其他
关注(0)|答案(1)|浏览(93)

这是一个有趣的问题,但我一直在尝试复制这个背景效果here (brawl stars),图标填充背景,并以特定的速度在屏幕外的选定方向移动。
我已经能够初始化背景图块/图标,使其在视图加载时立即显示,但是我无法定时新的图块/图标,使其在正确的时间以正确的速度出现。我也不知道这是否是最好的方法,这只是代表了我在混乱中试图复制这种行为的微弱尝试。
欢迎提出任何建议或想法。

func initializeBackgroundTiles()
{
    let itemsPerRow = 4

    let itemHeight = self.frame.width / 7
    let widthBetween = (itemHeight * 2) / 5
    let columnHeight = widthBetween * 4
    
    for column in 0...10 {
        
        for row in 0...5 {
            
            let columnPosition = (columnHeight * CGFloat(column))
            
            let xCalc = CGFloat(
                -(itemHeight + widthBetween) // one row to the left as well
                + (itemHeight * Double(row) + (widthBetween * Double(row))))
            
            let yCalc = (((self.frame.height - itemHeight) - columnPosition * 2) +
                         ((row % 2 == 1 ? columnHeight : 0)))
                    
            let tileSubview = CustomImageView(frame: CGRect(
                x: xCalc,
                y: yCalc,
                width: itemHeight,
                height: itemHeight))
            
            tileSubview.image = UIImage(named: "lightBand")!.withTintColor(.white)
            tileSubview.alpha = 0.04
            ContentView.addSubview(tileSubview)
            
            UIView.animate(withDuration: 30, delay: 0, options: [.curveLinear]) {
                
                let newX = ((itemHeight * Double(row)) + (widthBetween * Double(row))) + widthBetween * 3
                let newY = 0 - ((itemHeight + (row % 2 == 0 ? columnHeight : 0)) + columnPosition * 2)
                
                tileSubview.frame = CGRect(
                    x: newX,
                    y: newY,
                    width: itemHeight,
                    height: itemHeight
                )
            } completion: { completed in
                tileSubview.removeFromSuperview()
            }
        }
    }
}

func addBackgroundTilesTimer()
{
    Timer.scheduledTimer(timeInterval: 6, target: self, selector: #selector(continueBackgroundTiles), userInfo: nil, repeats: true)
}

@objc func continueBackgroundTiles()
{
    // spawn a vertical and horizontal row every x seconds
    let itemHeight = self.frame.width / 7
    let widthBetween = (itemHeight * 2) / 5
    let columnHeight = widthBetween * 4

        
        for row in 0...7 {
            
            let columnPosition = (columnHeight * CGFloat(1))
            
            let xCalc = CGFloat(
                -((itemHeight + widthBetween) * 2) // two buffer rows to the left as well
                + (itemHeight * Double(row) + (widthBetween * Double(row))))
            
            let yCalc = (((self.frame.height - itemHeight) - columnPosition * 2) +
                         ((row % 2 == 1 ? columnHeight : 0)))
                    
            let tileSubview = CustomImageView(frame: CGRect(
                x: xCalc,
                y: yCalc,
                width: itemHeight,
                height: itemHeight))
            
            tileSubview.image = UIImage(named: "lightBand")!.withTintColor(.white)
            tileSubview.alpha = 0.04
            self.ContentView.addSubview(tileSubview)
             
            UIView.animate(withDuration: 30, delay: 0, options: [.curveLinear]) {
                
                let newX = ((itemHeight * Double(row)) + (widthBetween * Double(row))) + widthBetween * 3
                let newY = 0 - ((itemHeight + (row % 2 == 0 ? columnHeight : 0)) + columnPosition * 2)
                
                tileSubview.frame = CGRect(
                    x: newX,
                    y: newY,
                    width: itemHeight,
                    height: itemHeight
                )
            } completion: { completed in
                tileSubview.removeFromSuperview()
            }
        }
    }
bq9c1y66

bq9c1y661#

我不知道你是否还需要这个,但这里有答案。不要忘记用视图控制器viewrect来初始化它。如果你想像在打斗明星中那样旋转它,那么只需添加旋转TiledBackgroundView的变换。

class TiledBackgroundView: UIView {
    
    private var timer: Timer?
    
    private let vCount = 10
    private let hCount = 5
    private let timeScale = 10
    
    private var itemHeight: CGFloat {
        frame.height / CGFloat(vCount)
    }
    
    private var itemWidth: CGFloat {
        frame.width / CGFloat(hCount)
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        initializeBackgroundTiles()
        addBackgroundTilesTimer()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func initializeBackgroundTiles() {
        for column in 0..<hCount {
            for row in 0..<vCount {
                addTile(
                    column: column,
                    row: row
                )
            }
        }
    }
    
    func addBackgroundTilesTimer() {
        timer = Timer.scheduledTimer(timeInterval: Double(timeScale), target: self, selector: #selector(continueBackgroundTiles), userInfo: nil, repeats: true)
    }
    
    @objc func continueBackgroundTiles() {
        for column in 0..<hCount {
            addTile(
                column: column,
                row: vCount
            )
        }
    }
    
    func addTile(
        column: Int,
        row: Int
    ) {
        let x = itemWidth * CGFloat(column)
        let y = itemHeight * CGFloat(row)
        
        let tileSubview = UIImageView(
            frame: CGRect(
                x: x,
                y: y,
                width: itemWidth,
                height: itemHeight
            )
        )
        tileSubview.contentMode = .center
        
        tileSubview.image = UIImage(named: "<your_image>")!.withTintColor(.white)
        addSubview(tileSubview)
        
        let duration = CGFloat(timeScale) * (CGFloat(row) + 1)
        
        UIView.animate(withDuration: duration, delay: 0, options: [.curveLinear]) {
            tileSubview.frame.origin = .init(x: x, y: -self.itemHeight)
        } completion: { completed in
            tileSubview.removeFromSuperview()
        }
    }
    
}

相关问题