️ 港口建设系统的核心挑战港口建设与普通建筑放置有本质区别挑战具体表现水陆边界建筑需要跨越陆地和水面两种介质岸线形态海岸线/河岸线是不规则曲线非规则网格水深因素不同水深适合不同类型码头流向/潮汐港口朝向需要考虑水流方向连续性码头、防波堤需要连续建设✅ 推荐方案混合网格系统 高度图核心架构┌─────────────────────────────────────────────────┐ │ 港口建设系统 │ ├─────────────────────────────────────────────────┤ │ 第1层高度图含水下地形 │ │ 第2层地形类型网格水域/陆地/滩涂 │ │ 第3层岸线检测层边界识别 │ │ 第4层建筑系统吸附逻辑 │ └─────────────────────────────────────────────────┘为什么选择这个方案❌ 纯规则网格方案 - 无法处理不规则岸线 - 水陆边界会出现锯齿 ❌ 纯高度图方案 - 缺乏建筑对齐参考 - 碰撞检测效率低 ✅ 混合方案推荐 - 高度图处理地形起伏和水深 - 网格处理建筑对齐和碰撞 - 岸线层处理水陆交界逻辑 详细技术实现1. 多层地形数据结构classPortTerrainSystem{constructor(width,height,cellSize){// 层1高度图包含水下this.heightMapnewFloat32Array(width*height);// 层2地形类型网格this.terrainTypeGridnewUint8Array(width*height);// 0 深水, 1 浅水, 2 滩涂, 3 陆地, 4 山地// 层3岸线数据运行时计算this.shorelineCells[];// 层4建筑占用网格this.buildingGridnewArray(width*height).fill(null);}// 根据高度自动判定地形类型classifyTerrain(x,z){constheightthis.getHeight(x,z);if(height-10)returnTerrainType.DEEP_WATER;if(height-3)returnTerrainType.SHALLOW_WATER;if(height0)returnTerrainType.INTERTIDAL;// 滩涂if(height20)returnTerrainType.LAND;returnTerrainType.MOUNTAIN;}}2. 岸线检测系统classShorelineDetector{detectShoreline(terrainSystem){constshoreline[];constgridterrainSystem.terrainTypeGrid;for(leti0;igrid.length;i){consttypegrid[i];constneighborsthis.getNeighbors(i);// 当前是水域且相邻有陆地 岸线格子if(this.isWater(type)){consthasLandNeighborneighbors.some(nthis.isLand(grid[n]));if(hasLandNeighbor){shoreline.push({index:i,position:this.indexToPosition(i),waterDepth:terrainSystem.getHeightAtIndex(i),normal:this.calculateShorelineNormal(i,terrainSystem)});}}}returnshoreline;}// 计算岸线法线方向指向水域calculateShorelineNormal(cellIndex,terrain){// 用于确定码头延伸方向// ...}}3. 港口建筑类型与放置规则constPORT_BUILDINGS{// 码头类型GRAVITY_WHARF:{name:重力式码头,size:[2,4],// 宽度沿岸线长度伸入水中minDepth:-5,// 最小水深要求maxDepth:-15,// 最大水深requiresShoreline:true,// 必须贴岸placement:perpendicular// 垂直于岸线},PILE_WHARF:{name:桩基码头,size:[2,6],minDepth:-3,maxDepth:-20,requiresShoreline:true,placement:perpendicular},// 防波堤BREAKWATER:{name:防波堤,size:[1,10],// 细长型minDepth:-25,maxDepth:0,requiresShoreline:false,placement:linear,// 线性延伸canConnect:true// 可连接成连续结构},// 浮动码头FLOATING_DOCK:{name:浮码头,size:[2,3],minDepth:-2,maxDepth:-10,requiresShoreline:false,placement:free// 自由放置},// 仓库陆地建筑WAREHOUSE:{name:仓库,size:[4,4],minDepth:2,// 必须在陆地以上maxDepth:Infinity,requiresShoreline:false,placement:grid}};4. 智能吸附系统核心classPortPlacementSystem{constructor(terrainSystem){this.terrainterrainSystem;this.shorelinenewShorelineDetector().detectShoreline(terrainSystem);}// 计算建筑放置位置和旋转calculatePlacement(buildingType,mousePos){constconfigPORT_BUILDINGS[buildingType];switch(config.placement){caseperpendicular:returnthis.placePerpendicularToShore(config,mousePos);caselinear:returnthis.placeLinear(config,mousePos);casefree:returnthis.placeFree(config,mousePos);casegrid:returnthis.placeOnGrid(config,mousePos);}}// 垂直于岸线放置码头核心逻辑placePerpendicularToShore(config,mousePos){// 1. 找到最近的岸线格子constnearestShorethis.findNearestShoreline(mousePos);if(!nearestShore)returnnull;// 2. 计算岸线法线方向码头延伸方向constshoreDirectionnearestShore.tangent;constextendDirectionnearestShore.normal;// 指向水域// 3. 计算放置位置constanchorPointnearestShore.position;constrotationMath.atan2(extendDirection.x,extendDirection.z);// 4. 检查水深是否满足要求constdepthAtEndthis.checkDepthAlongPath(anchorPoint,extendDirection,config.size[1]// 码头长度);if(depthAtEndconfig.minDepth||depthAtEndconfig.maxDepth){return{valid:false,reason:水深不符合要求};}return{valid:true,position:anchorPoint,rotation:rotation,shorePoint:anchorPoint,waterEnd:anchorPoint.clone().add(extendDirection.multiplyScalar(config.size[1]))};}// 防波堤等线性建筑placeLinear(config,mousePos){// 支持拖拽式放置// 起点 → 终点自动计算长度和角度}}5. 实时预览渲染classPortPreviewRenderer{constructor(scene,placementSystem){this.scenescene;this.placementplacementSystem;this.previewMeshnull;this.overlayMeshes[];}updatePreview(buildingType,mousePos){constresultthis.placement.calculatePlacement(buildingType,mousePos);if(!result){this.hidePreview();return;}// 更新预览模型位置和旋转this.previewMesh.position.copy(result.position);this.previewMesh.rotation.yresult.rotation;// 设置预览颜色constcolorresult.valid?0x00FF00:0xFF0000;this.setPreviewColor(color);// 显示额外的辅助信息this.showDepthIndicator(result);this.showShorelineHighlight(result.shorePoint);}// 水深指示器可视化水深范围showDepthIndicator(result){// 沿码头方向显示水深变化// 使用颜色渐变浅水(浅蓝) → 深水(深蓝)}// 高亮显示关联的岸线showShorelineHighlight(shorePoint){// 高亮显示码头连接的岸线区域}} 可视化示意陆地 ┌────────────────────┐ │ 仓库 │ │ ┌──────────┤ │ │ │ │ ═════╪════════ │ ← 重力式码头 │ │ │ (垂直于岸线) │ └──────────┤ │ ░░░░░░░░░░░░░░░░ │ ← 滩涂(浅色) │ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ │ ← 浅水 │ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │ ← 深水 │ ┌──────────┐ │ │ │ 浮码头 │ │ ← 可自由放置 │ └──────────┘ │ │ ══════════════════════ ← 防波堤 │ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓│ └────────────────────┘ 水域 完整方案总结组件技术选型说明地形基础高度图 网格高度处理水深网格处理建筑对齐岸线处理边界检测算法自动识别水陆交界建筑吸附混合吸附系统陆地建筑→网格吸附码头→岸线吸附预览系统实时渲染 深度可视化颜色指示有效性辅助线显示水深碰撞检测分区域检测水域/陆地/跨区域分别处理 额外建议用户体验优化// 1. 放置引导模式placementMode:{SMART:自动吸附到最佳位置,FREE:自由放置高级用户,MEASURE:测量模式先测量水深再规划}// 2. 批量建设// 防波堤、栈桥支持拖拽确定长度和方向// 3. 连锁建设// 码头 → 栈桥 → 系缆桩 自动连接技术选型建议开发环境推荐工具UnityTerrain NavMesh 自定义GridUnrealLandscape PCG Water SystemWeb/Three.js自定义实现我提供的代码框架可直接使用GodotGridMap HeightMap 自定义吸附