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

程序化自动布局多尺寸图片数组及推箱子游戏棋盘展示方案求助

搞定推箱子游戏的棋盘布局与图片展示方案

嘿,针对你开发推箱子(Sokoban)时遇到的棋盘展示和自适应布局问题,我整理了一套实用的解决方案,直接就能整合到你的代码里:

核心思路:动态适配不同尺寸关卡

你现有代码里的x0和y0是固定值,只能适配特定大小的关卡。咱们改成根据关卡尺寸动态计算起始位置,让棋盘始终居中显示,不管是5x5还是10x10的关卡都能完美适配。

完整优化代码示例

// 示例关卡地图(可从文件/配置加载不同尺寸的关卡)
let sampleLevelMap: [String] = [
    "##########",
    "#........#",
    "#.$..$...#",
    "#..##....#",
    "#.@......#",
    "##########"
]

func makeLevel(with levelMap: [String]) {
    // 先清理旧视图,避免重复叠加占用内存
    cellImageView.forEach { row in row.forEach { $0.removeFromSuperview() } }
    floorImageView.forEach { row in row.forEach { $0.removeFromSuperview() } }
    cellImageView.removeAll()
    floorImageView.removeAll()
    
    let cellSize = CGSize(width: 35, height: 35)
    let rows = levelMap.count
    guard rows > 0 else { return }
    let cols = levelMap[0].count
    
    // 计算棋盘总尺寸
    let totalBoardWidth = CGFloat(cols) * cellSize.width
    let totalBoardHeight = CGFloat(rows) * cellSize.height
    
    // 计算居中起始位置(基于父视图尺寸动态计算)
    guard let parentView = self.view else { return }
    let startX = (parentView.bounds.width - totalBoardWidth) / 2
    let startY = (parentView.bounds.height - totalBoardHeight) / 2
    
    // 定义元素图片映射(添加可选绑定,避免图片加载失败崩溃)
    let imageMap: [Character: UIImage?] = [
        ".": UIImage(named: "poopgoal30x30"),
        "#": UIImage(named: "wall30x30"),
        "$": UIImage(named: "box30x30"), // 补全你箱子图片的名称
        "@": UIImage(named: "player30x30"), // 玩家角色图片
        " ": UIImage(named: "floor30x30") // 空白地板背景
    ]
    
    // 遍历地图创建视图
    for rowIndex in 0..<rows {
        var cellRow: [UIImageView] = []
        var floorRow: [UIImageView] = []
        let rowStr = levelMap[rowIndex]
        
        for colIndex in 0..<cols {
            let currentChar = rowStr[rowStr.index(rowStr.startIndex, offsetBy: colIndex)]
            
            // 计算当前单元格的位置
            let x = startX + CGFloat(colIndex) * cellSize.width
            let y = startY + CGFloat(rowIndex) * cellSize.height
            let cellFrame = CGRect(x: x, y: y, width: cellSize.width, height: cellSize.height)
            
            // 创建底层地板视图(每个格子都需要)
            let floorView = UIImageView(frame: cellFrame)
            floorView.image = imageMap[" "]! ?? UIImage(named: "defaultFloor") // 兜底默认图
            parentView.addSubview(floorView)
            floorRow.append(floorView)
            
            // 创建上层元素视图(墙、箱子、目标点、玩家)
            let cellView = UIImageView(frame: cellFrame)
            cellView.image = imageMap[currentChar] ?? nil
            if cellView.image != nil {
                parentView.addSubview(cellView)
                cellRow.append(cellView)
            }
        }
        
        cellImageView.append(cellRow)
        floorImageView.append(floorRow)
    }
}

// 调用示例:加载示例关卡
makeLevel(with: sampleLevelMap)

关键优化点说明

  • 自适应居中布局:通过父视图尺寸和关卡总尺寸的差值,自动计算起始坐标,不管关卡大小都能居中显示
  • 安全的图片加载:用可选绑定处理UIImage(named:)的返回值,避免图片不存在导致崩溃,还加了兜底默认图
  • 视图清理逻辑:每次创建新关卡前移除旧视图,防止视图叠加占用内存
  • 模块化传入关卡数据:把关卡地图作为参数传入,方便快速切换不同尺寸的关卡

这样你就能轻松展示任意尺寸的推箱子棋盘啦!

内容的提问来源于stack exchange,提问作者Simon.T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:30:20