黑客帝国 - 矩阵雨

2022-11-22 16:33:56 浏览数 (2)


theme: fancy

上次编写的文章 韩式浪漫 - 落雪唯美,我们整了个雪花的效果。

咦,那么我们可不可以扩展下,整一个 黑客帝国矩阵雨的效果 呢?

答案是肯定的,下面来整活。

该效果主要完成的功能有两点:

  • 矩阵雨绘制
  • 红蓝药丸编写

矩阵雨绘制

我们同样使用 canvas 来实现。基本思路如下:

  • 初始化画布,画笔
  • 初始化矩阵雨有多少列
  • 01 的初始化绘制的字符串
  • 在画布上绘制,以随机的 01 填充,计算绘制的 xy 轴的距离,并重复绘制
  • 监听视图窗口的更改,更新画布的大小和矩阵雨多少列的数据

实现的代码不多,这里贴上 JavaScript 文件的代码。代码即文档,若难以理解,请结合代码中的注释去学习。

代码语言:javascript复制
(function() {
  let canvas = document.getElementById('canvas'); // 画布
  let ctx = canvas.getContext('2d'); // 画笔
  let width = canvas.width = window.innerWidth; // 设置 canvas 的大小,然后赋值给 width,方便后面的计算
  let height = canvas.height = window.innerHeight;
  let font = 12;
  let cols = 0;
  let dys = []; // 垂直距离的移动距离数组

  let matrix = '';
  let matrixSize = 20; // 矩阵雨的随机数量
  for(let i = 0; i < matrixSize; i  = 1) {
    matrix  = Math.floor(Math.random() * 2);
  }

  initData();
  // 初始化关键数据
  function initData() {
    // 列数据
    cols = width / font;
    // 随机生成 dy 垂直移动的距离
    for(let i = 0; i < cols; i  = 1) {
      dys[i] = Math.floor(Math.random() * cols);
    }
  }

  

  function draw(){
    // ctx.clearRect(0, 0, width, height); 
    ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
    ctx.fillRect(0, 0, width, height); // 填充画布
    ctx.fillStyle = "#00ff00";
    ctx.font = `${font}px`;
    for(let i = 0; i < cols; i  = 1) {
      let txt = matrix[Math.floor(Math.random() * matrixSize)];
      ctx.fillText(txt, i * font, dys[i] * font);
      if(dys[i] * font > height) {
        dys[i] = Math.floor(Math.random() * cols);
      }
      dys[i]  = 1; // 垂直距离的设置
    }
    requestAnimationFrame(draw); // 重新绘制
  }

  draw();
  
  // 监听窗口更改
  window.addEventListener('resize', () => {
    // 重置画布的大小
    width = canvas.width = window.innerWidth;
    height = canvas.height = window.innerHeight;
    // 重新初始化关键数据
    initData();
  });
})()

需要注意的是,draw() 函数中,不可添加 ctx.clearRect(0, 0, width, height); 代码,不然就是雪花飘落的效果了。读者可以放开该代码,自行验证。

clearRect 是清空画布的指定区域

疑问点

0 人点赞