基于Three.js实现蛇梯棋100x100网格不同纹理加载问题求助
解决Three.js蛇梯棋100个方块纹理加载与绑定问题
一、先搞定纹理加载循环的坑
纹理加载是异步操作,直接循环调用loader.load容易因为闭包或加载顺序出问题,这两种写法能解决:
写法1:用立即执行函数捕获循环变量
const wall_texture = []; const arr = [/* 你的1-100号图片路径数组 */]; // 用LoadingManager监听所有纹理加载完成事件 const loadingManager = new THREE.LoadingManager(); loadingManager.onLoad = function() { // 所有纹理加载完再初始化场景,避免拿不到纹理 initScene(); }; const loader = new THREE.TextureLoader(loadingManager); for (let i = 0; i < arr.length; i++) { // 用IIFE把当前循环的i值固定住 (function(index) { loader.load(arr[index], function(texture) { // 给纹理加些基础设置,避免拉伸变形 texture.wrapS = THREE.ClampToEdgeWrapping; texture.wrapT = THREE.ClampToEdgeWrapping; texture.minFilter = THREE.LinearFilter; wall_texture[index] = texture; }); })(i); }
写法2:用ES6 let的块级作用域
ES6的let会在每次循环生成独立变量,不用额外处理闭包:
const wall_texture = []; const arr = [/* 图片路径数组 */]; const loadingManager = new THREE.LoadingManager(); loadingManager.onLoad = initScene; const loader = new THREE.TextureLoader(loadingManager); for (let i = 0; i < arr.length; i++) { loader.load(arr[i], (texture) => { texture.wrapS = THREE.ClampToEdgeWrapping; texture.wrapT = THREE.ClampToEdgeWrapping; texture.minFilter = THREE.LinearFilter; wall_texture[i] = texture; // 这里的i每次循环都是独立的,不会串 }); }
二、在initScene里正确绑定纹理
必须等所有纹理加载完再执行initScene(靠上面的loadingManager.onLoad触发),然后循环创建立方体绑定对应纹理:
function initScene() { const scene = new THREE.Scene(); // 这里补全相机、渲染器等基础初始化代码 // 循环生成100个带不同纹理的立方体 for (let i = 0; i < 100; i++) { // 用对应索引的纹理创建材质 const material = new THREE.MeshBasicMaterial({ map: wall_texture[i], side: THREE.DoubleSide // 可选,确保方块两面都显示纹理 }); const geometry = new THREE.BoxGeometry(1, 1, 1); // 按需调整方块尺寸 const cube = new THREE.Mesh(geometry, material); // 按蛇梯棋网格布局设置位置(示例是10x10排列,可按需改) const row = Math.floor(i / 10); const col = i % 10; cube.position.set(col * 1.1, 0, row * 1.1); // 1.1是方块之间的间距 scene.add(cube); } // 补全渲染循环代码... }
三、常见问题排查
- 如果纹理显示异常:检查图片路径是否正确,或者调整纹理的
wrap/minFilter属性,避免拉伸模糊。 - 如果出现
undefined纹理:一定是没等纹理加载完就初始化场景了,必须依赖LoadingManager的onLoad触发initScene。 - 如果所有方块用了同一张纹理:大概率是循环变量没处理好,换成上面两种循环写法就行。
内容的提问来源于stack exchange,提问作者Cian Sullivan
相关产品推荐
相关产品推荐

