You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

复刻《荒野乱斗》背景滚动效果的技术问题求助

复刻《荒野乱斗》背景效果的优化建议

我正尝试复刻《荒野乱斗》中的背景效果,实现图标铺满背景并按指定方向、速度移出屏幕。目前已实现视图加载时初始背景图标的显示,但在新图标的生成时机、速度匹配上存在问题,不确定当前方案是否最优,以下是我的尝试代码,欢迎提供建议:

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) // 向左多偏移一行的位置
                + (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()
{
    // 每隔x秒生成一列垂直和水平的图标
    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) // 向左多偏移两行的位置
                + (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()
            }
        }
    }

核心问题与优化建议

现存问题

  1. 生成时机错位:Timer固定6秒触发,未与30秒的动画周期对齐,易出现背景空隙或图标重叠
  2. 速度不一致:初始生成图标与后续Timer生成图标的columnPosition取值、布局计算逻辑存在差异,导致移动速度不统一
  3. 硬编码冗余:大量魔法数值(如循环范围、动画时长)散落在代码中,适配不同屏幕或调整效果时维护成本高
  4. 性能浪费:每次生成新图标都创建新视图并在动画结束后销毁,频繁的视图创建销毁会增加内存开销

优化方向

  • 对齐生成时机与动画周期:
    计算图标移动的实际速度(总移动距离 / 动画时长30秒),再根据图标列的间距,算出需要补充新图标的时间间隔,确保无缝衔接,避免空隙或重叠
  • 统一布局与动画逻辑:
    把布局计算(如xCalc、yCalc)、动画参数(时长、目标位置)抽成单独的工具方法或常量,让初始图标和后续生成的图标使用完全一致的逻辑,保证速度统一
  • 改用AutoLayout实现动画:
    放弃直接修改frame,用NSLayoutConstraint控制图标位置,动画时修改约束的constant值,更适配屏幕旋转、尺寸变化等场景
  • 实现视图对象池:
    维护一个可复用的CustomImageView池,动画结束后不销毁视图,而是将其隐藏并放回池中,需要时重新取出配置并显示,减少视图创建销毁的性能损耗
  • 参数化配置:
    将itemsPerRow、动画时长、图标透明度等参数定义为可配置的常量,便于快速调整效果,无需修改多处代码

内容的提问来源于stack exchange,提问作者Tyler Rutt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 00:05:24