pixiJs入门记录

224 阅读1分钟
视频:www.bilibili.com/video/BV1rG…
01、Pixi初识和搭建Pixi应用
- vue create 01-pixi
- cd 01-pixi
- npm i pixi.js
- npm run serve

- app.vue 
- canvas width100vw height100vh positionFixed

<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'
// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view)
// 创建一个矩形
const rectangle = new PIXI.Graphics();
rectangle.beginFill(0x66ccff);  // 填充颜色
rectangle.drawRect(0, 0, 64, 64);  // 绘制矩形
rectangle.endFill();  // 结束填充
// 将矩形添加到舞台
app.stage.addChild(rectangle);
</script>
02、Pixi图形Graphics具体应用
- vue create 01-pixi
- cd 01-pixi
- npm i pixi.js
- npm run serve

- app.vue 
- canvas width100vw height100vh positionFixed

<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'
// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1,
    antialias: true, // 抗锯齿
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view)
// 创建一个矩形
const rectangle = new PIXI.Graphics();
rectangle.beginFill(0x66ccff, 0.9);  // 填充颜色
rectangle.drawRect(0, 0, 64, 64);  // 绘制矩形
rectangle.endFill();  // 结束填充
// 图形的缩放
rectangle.scale.set(2, 2);
// 图形的位移
rectangle.position.set(100, 100);
// 图形的旋转
rectangle.rotation = 0.5;
// 图形的锚点
rectangle.pivot.set(82, 32);
// 设置图形的边框样式
rectangle.lineStyle(4, 0xffd900, 1); // 线宽,线颜色,透明度

// 将矩形添加到舞台
app.stage.addChild(rectangle);


// 创建一个圆形
cosnt circle = new PIXI.Graphics();
circle.beginFill(0x66ccff, 0.9);
circle.drawCircle(0, 0, 32);
circle.endFill();
circle.position.set(300, 300);
app.stage.addChild(circle);

</script>
03、Pixi绘制各种常见图形
- vue create 01-pixi
- cd 01-pixi
- npm i pixi.js
- npm run serve

- app.vue 
- canvas width100vw height100vh positionFixed

<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'
// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1,
    antialias: true, // 抗锯齿
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view)
// 创建一个矩形
const rectangle = new PIXI.Graphics();
rectangle.beginFill(0x66ccff, 0.9);  // 填充颜色
rectangle.drawRect(0, 0, 64, 64);  // 绘制矩形
rectangle.endFill();  // 结束填充
// 图形的缩放
rectangle.scale.set(2, 2);
// 图形的位移
rectangle.position.set(100, 100);
// 图形的旋转
rectangle.rotation = 0.5;
// 图形的锚点
rectangle.pivot.set(82, 32);
// 设置图形的边框样式
rectangle.lineStyle(4, 0xffd900, 1); // 线宽,线颜色,透明度

// 将矩形添加到舞台
app.stage.addChild(rectangle);


// 创建一个圆形
cosnt circle = new PIXI.Graphics();
circle.beginFill(0x66ccff, 0.9);
circle.drawCircle(0, 0, 32);
circle.endFill();
circle.position.set(300, 300);
app.stage.addChild(circle);


// 绘制圆角矩形
const roundedRectangle = new PIXI.Graphics();
roundedRectangle.beginFill(0x66ccff, 0.9);
roundedRectangle.drawRoundedRect(0, 0, 164, 64, 10); // x,y,width,height,圆角半径
roundedRectangle.endFill();
roundedRectangle.position.set(500, 500);
app.stage.addChild(roundedRectangle);


// 绘制椭圆
const ellipse = new PIXI.Graphics();
ellipse.beginFill(0x66ccff, 0.9);
ellipse.drawEllipse(0, 0, 164, 64);
ellipse.endFill();
ellipse.position.set(700, 700);
app.stage.addChild(ellipse);


// 绘制多边形
const polygon = new PIXI.Graphics();
polygon.beginFill(0x66ccff, 0.9);
polygon.drawPolygon([0, 0, 100, 0, 100, 100, 0, 100]); // [x, y, x1, y1, x2, y2]
polygon.endFill();
polygon.position.set(50, 300);
add.stage.addChild(polygon);


// 绘制圆弧
const arc = new PIXI.Graphics();
arc.beginFill(0x660000, 0.9);
arc.arc(0, 0, 32, 0, Math.PI, false);
arc.endFill();
arc.position.set(300, 50);
app.stage.addChild(arc);


// 绘制线段
const line = new PIXI.Graphics();
line.lineStyle(4, 0xff0000, 1);
line.moveTo(0, 0); // 设置线段的起始点
line.lineTo(100, 100); 
line.lineTo(200, 0); // 设置线段的结束点
line.postiion.set(500, 50);
app.stage.addChild(line);

</script>
04、Pixi纹理与动画实现
<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'
// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1,
    antialias: true, // 抗锯齿
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view);

// 创建一个纹理
const texture = PIXI.Texture.from('./where/src.png');

// 创建一个精灵
const sprite = new PIXI.Sprite(texture);
sprite.anchor.set(0.5, 0.5); // 设置精灵的锚点
sprite.x = app.screen.width / 2; // 设置精灵的位置
sprite.y = app.screen.height / 2;
sprite.rotation = Math.PI / 4; // 设置精灵的旋转
sprite.scale.set(2, 2); // 设置精灵的缩放
sprite.alpha = 0.5; // 设置精灵的透明度
app.stage.addChild(sprite);

// ticker实现动画
app.ticker.add((delta) => {
    sprite.rotation += 0.01 * delta;
}

</script>
05、Pixi事件交互
<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'
// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1,
    antialias: true, // 抗锯齿
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view);

// 创建一个纹理
const texture = PIXI.Texture.from('./where/src.png');

// 创建一个精灵
const sprite = new PIXI.Sprite(texture);
sprite.anchor.set(0.5, 0.5); // 设置精灵的锚点
sprite.x = app.screen.width / 2; // 设置精灵的位置
sprite.y = app.screen.height / 2;
sprite.rotation = Math.PI / 4; // 设置精灵的旋转
sprite.scale.set(2, 2); // 设置精灵的缩放
sprite.alpha = 0.5; // 设置精灵的透明度
app.stage.addChild(sprite);

// ticker实现动画
app.ticker.add((delta) => {
    sprite.rotation += 0.01 * delta;
}

// 为精灵添加交互事件
sprite.interactive = true;
sprite.on('click', () => {
    console.log('click');
});

// 绘制一个矩形
const rect = new PIXI.Graphics();
rect.beginFill(0xff0000);
rect.drawRect(0, 0, 100, 100);
rect.endFill();
rect.x = 100;
rect.y = 100;
app.stage.addChild(rect);

// 给矩形添加一个点击事件
rect.interactive = true;
rect.on('click', () => {
    console.log('rect click');
});

// 移入移出事件
sprite.on('pointerenter', () => {
    sprite.alpha = 1;
});
sprite.on('pointerout', () => {
    sprite.alpha = 0.5;
});

</script>
06、Pixi资源管理
<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'
// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1,
    antialias: true, // 抗锯齿
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view);

// 添加资源
PIXI.Assets.add('jian', './where/jian.png');
PIXI.Assets.add('man', './where/man.png');
PIXI.Assets.add('mujian', './where/mujian.png');

// 异步加载资源
const texturesPromise = PIXI.Assets.load(['jian', 'man', 'mujian']);

// 加载完成后创建精灵
texturesPromise.then((textures) => {
    // 创建容器
    const container = new PIXI.Container();
    // 创建精灵
    const sprite = new PIXI.Sprite(textures.jian);
    // 设置精灵位置
    sprite.x = app.screen.width / 2;
    sprite.y = app.screen.height / 2;
    // 设置精灵锚点
    sprite.anchor.set(0.5);
    // 设置精灵缩放
    sprite.scale.set(0.5);
    // 设置精灵透明度
    sprite.alpha = 0.5;
    // 设置精灵旋转
    sprite.rotation = 0.5;
    // 设置精灵混合模式
    sprite.blendMode = PIXI.BLEND_MODES.ADD;
    // 设置精灵交互
    sprite.interactive = true;
    // 设置精灵鼠标样式
    sprite.buttonMode = true;
    // 设置精灵鼠标事件
    sprite.on('pointerdown', () => {
        console.log('pointerdown');
    });
    container.addChild(sprite);
    
    // 创建精灵
    const sprite2 = new PIXI.Sprite(textures.man);
    sprite2.scale.set(0.1);
    container.addChild(sprite2);
    
    // 把容器添加到舞台
    app.stage.addChild(container);
});
</script>
06-01、Pixi场景资源管理
<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'
// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1,
    antialias: true, // 抗锯齿
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view);

// 添加场景1的资源
PIXI.Assets.addBundle('scene1', {
    'jian':  './where/jian.png',
    'man', './where/man.png',
    'mujian', './where/mujian.png'
});
const texturesPromise = PIXI.Assets.load('scene1', (progress) => {
    console.log('加载完成', progress);
});

// 加载完成后创建精灵
texturesPromise.then((textures) => {
    // 创建容器
    const container = new PIXI.Container();
    // 创建精灵
    const sprite = new PIXI.Sprite(textures.jian);
    // 设置精灵位置
    sprite.x = app.screen.width / 2;
    sprite.y = app.screen.height / 2;
    // 设置精灵锚点
    sprite.anchor.set(0.5);
    // 设置精灵缩放
    sprite.scale.set(0.5);
    // 设置精灵透明度
    sprite.alpha = 0.5;
    // 设置精灵旋转
    sprite.rotation = 0.5;
    // 设置精灵混合模式
    sprite.blendMode = PIXI.BLEND_MODES.ADD;
    // 设置精灵交互
    sprite.interactive = true;
    // 设置精灵鼠标样式
    sprite.buttonMode = true;
    // 设置精灵鼠标事件
    sprite.on('pointerdown', () => {
        console.log('pointerdown');
    });
    container.addChild(sprite);
    
    // 创建精灵
    const sprite2 = new PIXI.Sprite(textures.man);
    sprite2.scale.set(0.1);
    container.addChild(sprite2);
    
    // 把容器添加到舞台
    app.stage.addChild(container);
});
</script>
07、Pixi文字与遮罩
<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'
// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1,
    antialias: true, // 抗锯齿
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view);

// 显示helloWorld文字
const text = new PIXI.Text('helloWorld', {
    fontSize: 180,
    fill: 'wihte',
    align: 'center'
});
// 设置文字的位置
text.x = app.screen.width / 2;
text.y = app.screen.height / 2;
// 设置文字锚点
text.anchor.set(0.5);
// app.state.addChild(text); 

// 创建一个圆形
const circle = new PIXI.Graphics();
circle.beginFill(0x0000ff);
circle.drawCircle(app.screen.width / 2, app.screen.height / 2, 100);
circle.endFill();

// 创建一个精灵
const mujian = PIXI.Sprite.from('./where/mujian.png');

// 创建一个精灵
const bunny = PIXI.Sprite.from('./where/bg.png');
// 用精灵铺满整个屏幕
bunny.width = app.screen.width;
bunny.height = app.screen.height;
// 文字作为精灵的遮罩
// bunny.mask = text;
// bunny.mask = circle;
bunny.mask = mujian;
app.state.addChild(bunny);
</script>
08、Pixi滤镜特效
<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'
// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1,
    antialias: true, // 抗锯齿
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view);

// 创建一个纹理
const texture = PIXI.Texture.from('./where/mujian.png');
// 创建一个精灵
const sprite = new PIXI.Sprite(texture);
// 设置精灵的位置
sprite.x = app.screen.width / 2;
sprite.y = app.screen.height / 2;

// 设置精灵的锚点
sprite.anchor.set(0.5);
// 将精灵添加到舞台
app.state.addChild(sprite);

// 创建一个模糊滤镜
const blurFilter = new PIXI.BlurFilter();
// 设置模糊滤镜的模糊程度
blurFilter.blur = 20;
// 将模糊滤镜添加到精灵上
// sprite.filters = [blurFilter];

// 监听鼠标是否进入精灵
// sprite.interactive = true;
// sprite.on('pointerover', () => {
//    // 设置模糊滤镜的模糊程度
//    blurFilter.blur = 0;
// });
// sprite.on('pointerout', () => {
//    // 设置模糊滤镜的模糊程度
//    blurFilter.blur = 20;
// });

// 滤镜插件 npm i pixi-filters
// import { OutlineFilter, GlowFilter } from 'pixi-filters';
// 创建轮廓滤镜
const outlineFilter = new OutlineFilter(2, 0x000000); // width, color
// 创建发光过滤滤镜
const glowFilter = new GlowFilter({
    distance: 50,
    outerStrength: 5,
    innerStrength: 0,
    color: 0xff0000,
    quality: 0.5,
});
// 将轮廓滤镜添加到精灵上
sprite.filters = [outlineFilter, glowFilter];

</script>
09、Pixi实现波浪水滴特效
<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'
import { ShockwaveFilter } from 'pixi-filters';

// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1,
    antialias: true, // 抗锯齿
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view);
// 创建一个纹理
const texture = PIXI.Texture.from('./where/car.png');
// 创建一个精灵
const sprite = new PIXI.Sprite(texture);
sprite.width = app.screen.width;
sprite.height = app.screen.height;
// 创建容器
const container = new PIXI.Container();
// 将精灵添加到容器中
container.addChild(sprite);
// 将容器添加到舞台
app.stage.addChild(container);

// 添加文字
const text = new PIXI.Text('hello PixiJS', {
    fontSize: 140,
    fill: 0xffffff,
    dropShadow: true,
    dropShadowBlur: 4,
    deopShadowAngle: Math.PI / 2,
    dropShadowDistance: 6,
});
text.x = app.screen.width / 2;
text.y = app.screen.height / 2;
text.anchor.set(0.5);
container.addChild(text);

// 添加置换滤镜
const displacementSprite = PIXI.Sprite.from('./where.displacement.png');
displacementSprite.scale.set(5);
displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
const displacementFilter = new PIXI.DisplacementFilter(
    displacementSprite
);
container.addChild(displacementSprite);

// 添加震波滤镜
const shockwaveFilter1 = new ShockwaveFilter([
    Math.random() * app.screen.width,
    Math.random() * app.screen.height
], {
    radius: 40, // 半径
    waveLenght: 30, // 波长
    amplitude: 10, // 振幅
    nbRipples: 1,
    pixelate: false,
    paused: false,
    autoFit: flase,
    speed: 200, // 速度
}, 0);
const shockwaveFilter2 = new ShockwaveFilter([
    Math.random() * app.screen.width,
    Math.random() * app.screen.height
], {
    radius: 100, // 半径
    waveLenght: 45, // 波长
    amplitude: 80, // 振幅
    speed: 200, // 速度
}, 0);
const shockwaveFilter3 = new ShockwaveFilter([
    Math.random() * app.screen.width,
    Math.random() * app.screen.height
], {
    radius: 160, // 半径
    waveLenght: 65, // 波长
    amplitude: 105, // 振幅
    speed: 300, // 速度
}, 0);

container.filters = [
    displacementFilter, 
    shockwaveFilter1, 
    shockwaveFilter2, 
    shockwaveFilter3
];

app.ticker.add((delta) => {
    displacementSprite.x += 1;
    displacementSprite.y += 1;
    createWave(shockwaveFilter1, 1);
    createWave(shockwaveFilter2, 1.2);
    createWave(shockwaveFilter3, 0.7);
});

function createWave(waveFilter, resetTime) {
    waveFilter.time += 0.01;
    if (waveFilter.time > resetTime) {
        waveFilter.time = 0;
        waveFilter.center = [
            Math.random() * app.screen.width, 
            Math.random() * app.screen.height
        ]
    }
}

// 监听点击事件根据位置创建振波滤镜
app.view.addEventListener('click', (e) => {
    shockwaveFilter3.cventer = [e.clientX, e.clientY];
    shockwaveFilter3.time = 0;
});

</script>
10、Pixi开发谷歌恐龙跑酷小游戏
<script setup>
// 导入pixi.js
import * as PIXI from 'pixi.js'

// 创建应用
const app = new PIXI.Application({
    width: window.innerWidth,
    height: window.innerHeight,
    backgroundColor: 0x1099bb,
    resolution: window.devicePixelRatio || 1,
    antialias: true, // 抗锯齿
})
// 将应用画布添加到Dom中
document.body.appendChild(app.view);

// 添加恐龙游戏的精灵纹理
const baseTexture = PIXI.BaseTexture.from('./where/雪碧图.png');
// 创建恐龙纹理
const dinoTexture = new PIXI.Texture(
    baseTexture,
    new PIXI.Rectangle(75, 0, 88, 100);
);
// 创建恐龙精灵
const dino = new PIXI.Sprite(dinoTexture);
dino.visible = false;
container.addChild(dino);

// 恐龙跑步动画
const runTextures = [];

for(let i = 0; i < 2; i++) {
    runTextures.push(new PIXI.Texture(
        baseTexture,
        new PIXI.Rectangle(1680 + (2 + i) * 88, 0, 82, 100)
    ));
}
const runAnimation = new PIXI.AnimatedSprite(runTextures);
runAnimation.animationSpeed = 0.1;
runAnimation.play();
runAnimation.visible = false;
container.addChild(runAnimation);

// 恐龙跳跃精灵
const jumpTexture = new PIXI.Texture(
    baseTexture,
    new PIXI.Rectangle(1680 + 88, 0, 82, 100)
);
const jumpSprite = new PIXI.Sprite(jumpTexture);
jumpSprite.x = 60;
jumpSprite.y = window.innerHeight - 50 - 100;
jumpSprite.visible = false;
container.addChild(jumpSprite);

// 创建地面精灵
const groundTexture = new PIXI.Texture(
    baseTexture,
    new PIXI.Rectangle(50, 100, 2300, 30);
);
const groundSprite = new PIXI.TilingSprite(groundTexture);
groundSprite.width = window.innerWidth;
groundSprite.height = 30;
// 设置地面精灵的位置
groundSprite.postion.set(0, window.innerHeight - 50);
container.addChild(groundSprite);

// 创建仙人掌精灵
const cactusTexture = new PIXI.Texture(
    baseTexture,
    new PIXI.Rectangle(515, 0, 30, 60)
)
const cactusSprite = new PIXI.Sprite(cactusTexture);
cactusSprite.x = window.innerWidth / 2;
cactusSprite.y = window.innerHeight - 50 - 60;
container.addChild(cactusSprite);

// 创建文字
let startText = new PIXI.Text('开始游戏', {
    fontSize: 36,
    fill: 0x333333,
    align: 'center'
});
startText.x = window.innerWidth / 2;
startText.y = window.innerHeight / 2;
startText.anchor.set(0.5);
container.addChild(startText);

startText.interactive = true;
startText.on('click', () => {
    playGame();
});

let isGameing = false;
let isGameover = false;

// 开始游戏
function playGame () {
    isGameing = true;
    console.log('开始游戏');
    // 现实恐龙的跑步动画
    runAnimation.visible = true;
    runAnimation.x = 60;
    runAnimation.y = window.innerHeight - 50 -100;
}

// 游戏得分
let score = 0// 初始化跳跃的速度
let jumpVelocity = 20; 
// 初始化重力
let gravity = 1;

// 游戏循环
app.ticker.add((delta) => {
    if (isGameover) return;
    if (isGameing) {
        // 地面移动
        groundSprite.tilePosition.x -= 10;
        // 仙人掌移动
        cactusSprite.x -= 10;
        if (cactusSprite.x < -30) {
            cactusSprite.x = window.innerWidth;
            score ++;
        }
    }
    if (jumpSprite.visible) {
        jumpVelocity -= gravity;
        jumpSprite.y -= jumpVelocity;
        jumpVelocity -=1;
        if (jumpSprite.y > window.innerHeight - 50 - 100;
        ) {
            jumpSprite.y = window.innerHeight - 50 - 100;
            jumpVelocity = 20;
            jumpSprite.visible = false;
            runAnimation.visible = true;
        }
    }
    // 检测碰撞
    if (
        jumpSprite.y > cactusSprite.y - 60 &&
        cactusSprite.x < jumpSprite.x + 60 &&
        cactusSprite.x > jumpSprite.x - 60
    ) {
        gameover();
        startText.visible = false;
        
        // 显示游戏结束的文字
        let overText = new PIXI.Text('游戏结束, 最后得分' + score, {
            fontSize: 36,
            fill: 0x333333,
            align: 'center'
        })
        overText.x = window.innerWidth / 2;
        overText.y = window.innerHeight / 2;
        overText.anchor.set(0.5);
        container.addChild(overText);
        overText.interactive = true;
        overText.on('click', () => {
            location.reload();
        });
    }
});

function gameover () {
    console.log('game over');
    isGameover = true;
}

window.addEventListener('keydown', (e) => {
    if (e.code == 'Space') {
        console.log('跳跃');
        runAnimation.visible = false;
        jumpSprite.visible = true;
        jumpVelocity = 20;
    }
});
</script>