likes
comments
collection
share

PixiJS 的画格子使用优化

作者站长头像
站长
· 阅读数 38

pixijs 是一个开源的 canvas 库,我们可以用这个库来做很多的事情,下面我们要做一个画格子的游戏。

Graphics简单使用

官网上对 graphics 介绍很多,这边不涉及到高级用法,graphics 就是我们用来画格子的。

下面上代码:

const baseWidth = 500
// 声明一个应用
let app = new PIXI.Application({ width: baseWidth, height: baseWidth });

// 声明 graphics,开始画一个5*5的白色矩形
const graphics = new PIXI.Graphics();
graphics.beginFill(0xffffff);
graphics.drawRect(0,0,5,5);

// 添加应用到 dom 中去
app.stage.addChild(graphics);
document.body.appendChild(app.view);

一个哪里够,我要打十个(吹牛的)但是一个格子确实不够,我要画1000个,不对,我要画1000000个

// 格子数
const gridSize = 1000
// gridCount 表示每个格子的宽度,baseWidth表示一个 500 像素大小的 dom
const gridCount = baseWidth / gridSize
for (let x = 0; x < gridSize; x++) {
       for (let y = 0; y < gridSize; y++) {
        graphics.beginFill(0xffffff);
        graphics.drawRect(x * gridCount, y * gridCount, gridCount, gridCount);
    }
 }

颜色就让随机吧

// 生成随机颜色的函数
function getRandomColor() {
   const letters = "0123456789ABCDEF";
   color = "";
   for (let i = 0; i < 6; i++) {
     color += letters[Math.floor(Math.random() * 16)];
   }
   return color;
 }

完整代码:

const baseWidth = 500;
// 格子大小
const gridSize = 1000;
// 每一个格子的大小
const gridCount = baseWidth / gridSize;

let app = new PIXI.Application({ width: baseWidth, height: baseWidth });

const graphics = new PIXI.Graphics();

app.stage.addChild(graphics);
document.body.appendChild(app.view);

draw();

// 生成随机颜色的函数
function getRandomColor() {
   const letters = "0123456789ABCDEF";
   color = "";
   for (let i = 0; i < 6; i++) {
      color += letters[Math.floor(Math.random() * 16)];
   }
   return color;
}
// 画点
function draw() {
   console.time("draw");
   // 画格子
   for (let x = 0; x < gridSize; x++) {
      for (let y = 0; y < gridSize; y++) {
          graphics.beginFill("0x" + getRandomColor());
          graphics.drawRect(x * gridCount, y * gridCount, gridCount, gridCount);
        }
      }
   console.timeEnd("draw");

   // 渲染
   console.time("render");
   app.render();
   console.timeEnd("render");
   app.stop();
}

最后画的格子大概长这个样子:

PixiJS 的画格子使用优化

书写一个按钮,每次点击就重新画一次吧

<button onclick="draw()">画画</button>

渲染卡顿

画完格子了但是卡顿的很,看了一下渲染时间

PixiJS 的画格子使用优化

渲染时间很长?

卡顿原因

研究了一下,每一次使用 graphics 画格子都是递增的,比如在坐标(5,5)画一个绿色格子,然后再在坐标上(5,5)画一个红色格子,并不是修改颜色,而是往上覆盖格子,如图

PixiJS 的画格子使用优化

解决方案

看了官网,没有修改的方法,但是可以通过修改geometry的值来实现。但是每次修改都要使用geometry.invalidate()修正一下数据。尝试了一下,这个方式还是渲染很慢,只是保证了数据不递增而已。当格子数很多的时候,还是会卡顿。

使用精灵

这个问题困扰了很久(救命

大佬出现了,他告诉我可以使用精灵,并且通过纹理来实现,并不是要一定画上去

上代码:

    const buffer = new Uint8Array(gridSize * gridSize * 4);
       for (let x = 0; x < gridSize; x++) {
         for (let y = 0; y < gridSize; y++) {
           const offset = (y + gridSize * x) * 4;
           const color = hexToRGBA(getRandomColor());
           buffer[offset + 0] = color[0]; // R value
           buffer[offset + 1] = color[1]; // G value
           buffer[offset + 2] = color[2]; // B value
           buffer[offset + 3] = 255; // A value
         }
    }
    const texture = PIXI.Texture.fromBuffer(buffer, gridSize, gridSize);
    const sprite = new PIXI.Sprite(texture);
    sprite.x = 0;
    sprite.y = 0;
    sprite.width = baseWidth;
    sprite.height = baseWidth;

    app.stage.removeChildren();
    app.stage.addChild(sprite);

补充方法,将16进制转换为rgba


    function hexToRGBA(hex, alpha = 1) {
       let r = parseInt(hex.slice(1, 3), 16),
       g = parseInt(hex.slice(3, 5), 16),
       b = parseInt(hex.slice(5, 7), 16);

       return [r, g, b, alpha];
    }

具体完整的代码:


     const baseWidth = 500;
     // 格子大小
     const gridSize = 1000;
     // 每一个格子的大小
     const gridCount = baseWidth / gridSize;

     let app = new PIXI.Application({ width: baseWidth, height: baseWidth });


     document.body.appendChild(app.view);

     draw();

     // 生成随机颜色的函数
     function getRandomColor() {
       const letters = "0123456789ABCDEF";
       color = "#";
       for (let i = 0; i < 6; i++) {
         color += letters[Math.floor(Math.random() * 16)];
        }
       return color;
     }

     function hexToRGBA(hex, alpha = 1) {
       let r = parseInt(hex.slice(1, 3), 16),
           g = parseInt(hex.slice(3, 5), 16),
           b = parseInt(hex.slice(5, 7), 16);

          return [r, g, b, alpha];
     }

     // 画点
     function draw() {
       console.time("draw");
       // 画格子
       const buffer = new Uint8Array(gridSize * gridSize * 4);
       for (let x = 0; x < gridSize; x++) {
         for (let y = 0; y < gridSize; y++) {
           const offset = (y + gridSize * x) * 4;
           const color = hexToRGBA(getRandomColor());
           buffer[offset + 0] = color[0]; // R value
           buffer[offset + 1] = color[1]; // G value
           buffer[offset + 2] = color[2]; // B value
           buffer[offset + 3] = 255; // A value
         }
       }
       const texture = PIXI.Texture.fromBuffer(buffer, gridSize, gridSize);
       const sprite = new PIXI.Sprite(texture);
       sprite.x = 0;
       sprite.y = 0;
       sprite.width = baseWidth;
       sprite.height = baseWidth;

       app.stage.removeChildren();
       app.stage.addChild(sprite);

       console.timeEnd("draw");

       // 渲染
       console.time("render");
       app.render();
       console.timeEnd("render");

       app.stop();
    }

渲染时间

PixiJS 的画格子使用优化

这样时间就短了很多了!

转载自:https://juejin.cn/post/7336750909508222988
评论
请登录