webgl 迷宫项目开发总结

    技术2026-01-20  8

    项目简介: 项目分为两个部分:

    第一部分是一个迷宫Maze, 首先生成矩形cell数组,每个cell有4个side,然后一步一步地remove side(不包括迷宫边缘的side),直到全部的cell 都连通(connected)。然后在迷宫的左边缘创建一个入口,在右边缘创建一个出口。

    整体网页需要接收2个参数:N和M, 迷宫的大小为N*M。

    第二部分是交互操作Guide。在迷宫入口设置一个老鼠图片,然后可以通过左右键调整老鼠的朝向,方向键上来前进一步。

    收获

    webgl 三个js库

    webgl-utils.js

    webgl-debug.js

    cuon-utils.js

    图片加载

    var img = new Image();

    img.src = ‘./rat.png’;

    img.onload = function(){

    img_loaded = true;

    }

    图片应该最先加载。这样可以防止webgl在渲染的时候图片还没加载完而出现黑屏的问题。

    监听键盘事件

    保证事件代码只运行一次。否则会重复绑定多个事件,也就是按键一次会触发多次事件处理。

    document.addEventListener(“keyup”,function (event) {

    switch (event.keyCode)

    渲染多个物体到同一个canvas

    不能再用initShader方法了,而是需要创建多个program:

    program= createProgram(gl, VSHADER_SOURCE, FSHADER_SOURCE)

    program2= createProgram(gl, VSHADER_SOURCE_2, FSHADER_SOURCE_2)

    然后在需要渲染的时候, 主动切换不同的program:

    gl.useProgram(program);

    渲染图片时背景透明:

    应该找一个透明背景的png图片:

    // gl.enable(gl.BLEND);

    // gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

    图片尺寸:

    长宽都应该为2^N,长宽可以不同。 比如为128px, 256px, 512px

    否则无法渲染。

    cell的连通性如何判断:

    使用bfs 广度优先算法, 从任意一个cell开始,如果能遍历到全部的cell(可以弄个set来保存并判断长度),即cell全连通了。

    如何更有效地remove side:

    随机的方法虽然写起来简单,但是很难取得最优解。

    可以这样:

    随机选择一个side, 在remove 之前,记录cell 0 连通的cell总个数。

    然后remove。 再次记录cell 0连通的cell总个数。

    如果remove前后连通的cell总个数不变, 则回滚remove操作。 并进入下一次循环。

    改变图片朝向:

    Float32Array 是 4 x 4的, 每行是一个顶点, 每行里面的最后2个float表示朝向

    if (current_direction == 0) {

    // down

    a_1 = 0; a_2 = 1;

    b_1 = 0; b_2 = 0;

    c_1 = 1; c_2 = 1;

    d_1 = 1; d_2 = 0;

    } else if(current_direction ==1) {

    // right

    a_1 = 0; a_2 = 1;

    b_1 = 1; b_2 = 1;

    c_1 = 0; c_2 = 0;

    d_1 = 1; d_2 = 0;

    } else if (current_direction == 2) {

    // up

    a_1 = 1; a_2 = 0;

    b_1 = 1; b_2 = 1;

    c_1 = 0; c_2 = 0;

    d_1 = 0; d_2 = 1;

    } else if (current_direction == 3) {

    // left

    a_1 = 1; a_2 = 0;

    b_1 = 0; b_2 = 0;

    c_1 = 1; c_2 = 1;

    d_1 = 0; d_2 = 1;

    }

    移动图片:

    Float32Array 是 4 x 4的, 每行是一个顶点,每行里面的前2个float是x和y坐标,加一个delta值即可。

    其它:

    attribute 类型的变量: gl.getAttribLocation 之后如果返回值

    uniform 类型的变量: gl.getUniformLocation 之后, 如果 ! , 则为失败。

    渲染图片时浏览器无法加载本地文件,需要把网页放到webserver里面运行。

    https://shimo.im/docs/dYkqrQcyr98jPKYX/ 《android学习面试fulutter进阶资料免费获取》,可复制链接后用石墨文档 App 或小程序打开。

    Processed: 0.018, SQL: 10