研究一下PIXI

先把最开始的初始代码堆上来,方便以后复制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import * as PIXI from "pixi.js";
import { initDevtools } from "@pixi/devtools";

(async () => {
console.log("Hello, World!");

const app = new PIXI.Application();
initDevtools({
app,
});
await app.init({
width: screen.width,
height: screen.height,
resolution: window.devicePixelRatio || 1, // 使用设备像素比
antialias: true, // 抗锯齿
});

const graphics = new PIXI.Graphics()
.rect(0, 0, 200, 100)
.fill(0xff0000)
.rect(400, 0, 200, 100)
.fill(0x00ff00);
graphics.position.set(100, 100);
graphics.pivot.set(100, 0);

app.stage.addChild(graphics);
app.stage.eventMode = "static";
// 在舞台上绘制网格
const grid = new PIXI.Graphics();
for (let i = 0; i < 10; i++) {
grid.moveTo(0, i * 100);
grid.lineTo(1000, i * 100);
grid.moveTo(i * 100, 0);
grid.lineTo(i * 100, 1000);
grid.stroke({ width: 1, color: 0x2b2b2b });
}
app.stage.addChild(grid);

app.ticker.add(() => {
graphics.rotation += 0.1;
});

// app.start();
console.log("PIXI Version:", PIXI.VERSION);
console.log(app);
document.body.appendChild(app.canvas);
})();

当时写的时候把

1
document.body.appendChild(app.canvas);

这句给丢了,怪不得啥画面都没有。

现在专门看

1
2
3
4
5
6
7
const graphics = new PIXI.Graphics()
.rect(0, 0, 200, 100)
.fill(0xff0000)
.rect(400, 0, 200, 100)
.fill(0x00ff00);
graphics.position.set(100, 100);
graphics.pivot.set(100, 0);

这个部分,

一个图形实例 graphics ,可以看成是一个无限大的玻璃板,它最终被放在舞台上。

上面的操作其实可以这样理解:

这个巨大的玻璃板也有 右x下y 的坐标轴。前面四行代码就是根据这个玻璃板的坐标轴,在玻璃板上画了两个不同颜色的矩形。

然后就是一个移动玻璃板 position.set 、和设置玻璃板旋转中心点 pivot.set 的操作。

实际上如果没有这两步操作,巨大玻璃板的坐标轴和stage舞台的坐标轴是完全重合的。

这两部操作代码出现的时候,应该先看pivot,再看position。

pivot是设置了旋转中心点,同时也是设置了与父元素进行对齐的地方。pivot设置的点会和父元素的中心点重叠。

然后,在重叠的基础上,position就会让元素与父元素之间产生相对位移。

在玻璃板上画不同的图形

画矩形的时候,是 x, y, w, h 坐标点是先找到的左上角的点。

画圆形的时候,x, y, r 坐标点是圆心点。

记录绘制炮塔

这个完全没有用到spirit,只用了容器和图形。

容器就像非叶子节点,图形就像叶子节点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import * as PIXI from "pixi.js";
import { initDevtools } from "@pixi/devtools";

(async () => {
console.log("Hello, World!");

const app = new PIXI.Application();
initDevtools({
app,
});
await app.init({
width: screen.width,
height: screen.height,
resolution: window.devicePixelRatio || 1, // 使用设备像素比
antialias: true, // 抗锯齿
});
let tick = 0;

// const graphics = new PIXI.Graphics().circle(0, 0, 100).fill(0xff0000);
// graphics.position.set(300, 300);
// app.stage.addChild(graphics);
let b = null;
let barrels = [];
{
const cannon = new PIXI.Container();
cannon.position.set(300, 300);

const circle = new PIXI.Graphics().circle(0, 0, 100).fill(0x1e1e1e);

const barrelGroup = new PIXI.Container();
const barrelGroupRect = new PIXI.Graphics()
.rect(0, 0, 300, 100)
.stroke(0x000000);
barrelGroupRect.pivot.set(50, 50);
barrelGroup.addChild(barrelGroupRect);
b = barrelGroup;
for (let i = -2; i <= 2; i++) {
const barrel = new PIXI.Graphics().rect(0, 0, 50, 20).fill(0x3c3c3c);
barrel.pivot.set(0, 5);
barrel.position.set(0, 35 * i);
barrelGroup.addChild(barrel);
barrels.push(barrel);
}

// 这两个顺序不能乱,
cannon.addChild(circle); // 先画圆圈,炮塔墩子
cannon.addChild(barrelGroup); // 再画武器,盖在上面

app.stage.addChild(cannon);
}

{
// 在舞台上绘制网格
const grid = new PIXI.Graphics();
for (let i = 0; i < 10; i++) {
grid.moveTo(0, i * 100);
grid.lineTo(1000, i * 100);
grid.moveTo(i * 100, 0);
grid.lineTo(i * 100, 1000);
grid.stroke({ width: 1, color: 0x2b2b2b });
}
app.stage.addChild(grid);
}

app.ticker.add(() => {
tick++;
barrels.forEach((barrel, index) => {
barrel.position.x = 5 * (Math.sin(tick / 2 + index) * 2 + 2);
});
// graphics.rotation += 0.1;
b.rotation += 0.01;
});

// app.start();
console.log("PIXI Version:", PIXI.VERSION);
console.log(app);
document.body.appendChild(app.canvas);
})();

现在的问题可能是如何把数据层和渲染层拆成两部分。

最终还是太累了,暂时先不搞了