p5.js递归树迭代渲染问题:移除noLoop并保留固定树结构
问题解答
1. 重构代码移除noLoop(),实现固定树结构的每帧渲染
核心思路是把树的结构数据预先生成并存储,每帧仅渲染已有数据,不再重复生成树。具体实现步骤如下:
- 定义全局变量存储树的分支数据(比如节点坐标、粗细等渲染所需信息)
- 用一个标志位判断树是否已经生成,仅在首次执行
draw时生成树结构 - 后续每帧
draw只遍历预存的树数据,完成渲染
示例重构代码:
let treeData = []; let isTreeGenerated = false; function setup() { createCanvas(800, 600); // 这里可以初始化其他游戏对象 } function draw() { background(220); // 仅首次执行时生成树结构 if (!isTreeGenerated) { generateIterativeTree(0, height, 100, radians(90), 12); isTreeGenerated = true; } // 渲染预先生成的树 renderTree(); // 这里可以正常渲染其他游戏元素(比如跟随鼠标的圆) fill(255, 0, 0); noStroke(); circle(mouseX, mouseY, 25); } // 迭代式递归生成树结构,将分支数据存入treeData function generateIterativeTree(x, y, length, angle, thickness) { const branchStack = [{x, y, length, angle, thickness}]; while (branchStack.length > 0) { const currentBranch = branchStack.pop(); const endX = currentBranch.x + cos(currentBranch.angle) * currentBranch.length; const endY = currentBranch.y - sin(currentBranch.angle) * currentBranch.length; // 保存当前分支的渲染信息 treeData.push({ start: {x: currentBranch.x, y: currentBranch.y}, end: {x: endX, y: endY}, thickness: currentBranch.thickness }); // 生成子分支(长度和粗细衰减,角度偏移) if (currentBranch.length > 8) { const newLength = currentBranch.length * 0.75; const newThickness = currentBranch.thickness * 0.65; branchStack.push({ x: endX, y: endY, length: newLength, angle: currentBranch.angle + radians(25), thickness: newThickness }); branchStack.push({ x: endX, y: endY, length: newLength, angle: currentBranch.angle - radians(25), thickness: newThickness }); } } } // 渲染存储好的树结构 function renderTree() { stroke(80, 40, 10); treeData.forEach(branch => { strokeWeight(branch.thickness); line(branch.start.x, branch.start.y, branch.end.x, branch.end.y); }); }
这样修改后,树结构仅在页面加载后生成一次,每帧重复渲染相同的树,同时draw函数可以正常处理其他游戏对象的渲染,不会被noLoop()阻塞。
2. draw与setup中console.log输出次数差异的原因
这是由p5.js的核心执行机制决定的:
setup函数是程序初始化函数,仅在页面加载完成后执行一次,所以其中的console.log只会输出一条日志。draw函数是主循环函数,默认以约60帧/秒的频率持续重复执行(直到调用noLoop()),所以每执行一次draw就会输出一条日志,因此会看到大量重复输出。
内容的提问来源于stack exchange,提问作者Josef Alkhuzanie
相关产品推荐
相关产品推荐

