草稿箱躺了一年的文章:记录初次使用PIXI实践探索、可应用场景和搭配第三方库的玩法;
技术选型:Pixi + GSAP、 扫下方二维码或点击体验地址。
因部分接口下线,体验为纯前端代码
游戏部分完整地图:从开发视角来分析,需要实现以下三点:
1. 场景移动 & 人物移动
1.1
人物的站立和行走切换:通过切换两个精灵的透明度
序列帧动画使用
Pixi.AnimatedSprite
方法,但这并不是唯一方案,也可以使用包含动画定义的精灵表Pixi.Spritesheet
,再或者使用pixi-spine
跳转下文示例🔗
代码示例片段:
// 创建容器,放站立和行走精灵
const playerWrap: PIXI.Container = new PIXI.Container();
const textureArray = [
PIXI.Texture.from('img_01.png'),
PIXI.Texture.from('img_02.png'),
...
];
// 行走序列帧
const playerRuning = new PIXI.AnimatedSprite.from(textureArray);
playerRuning.alpha = 0;
// 站立状态
const playerStand = PIXI.BaseTexture.from('https://mat1.gtimg.com/qqcdn/tnewsh5/short-term/centralAxis/game-player.png');
// 放入容器
playerWrap.addChild(playerRuning, playerRuning);
// 通过alpha值切换显示
playerRuning.alpha = 0;
playerStand.alpha = 1;
GKA处理序列帧的小工具。
1.2
人物移动,通过GSAP控制背景的Y轴如下示意图
,同时切换人物行走状态;
场景关系示意图:
水平对其可视窗口演示:
1.3
地图平移临界情况:地图不能再向上平移时候,开始平移人物Y轴,直至临界点;上图后两张示意
1.4
GSAP处理地图超出回归原点的渐补动画。再次称赞GSAP,处理多段动画非常轻松!
2. 转盘转动 & 转动音效
2.1
转盘的角度:计算转动到目标数值的角度,再通过GSAP进行渐补旋转动画:
// 旋转角度累计
const currentDeg = ref(0);
// 转盘一格角度
const STEP_DEG = 72;
// 两圈起步
const BASE_CIRCLES = 360 * 2;
const getRotateDeg = (r: number) => {
if (r > lastStep.value) {
currentDeg.value = currentDeg.value + BASE_CIRCLES + Math.abs((lastStep.value - r) * STEP_DEG);
} else {
currentDeg.value = currentDeg.value + BASE_CIRCLES - Math.abs((lastStep.value - r) * STEP_DEG);
}
};
const deg = getRotateDeg('目标数字')
// 旋转动画
gsap.to('转盘元素', {
rotate: -deg,
duration: 2,
// Ease Visualizer: https://greensock.com/ease-visualizer
ease: 'circ.out',
onComplete: () => {
cb();
},
});
在后期整理文章时,发现GSAP中 DirectionalRotationPlugin 可以实现当前角度补间至目标角度。
2.2
转盘点击的同时播放音乐:sound功能比较完善,即使非pixi项目也可以作为音效处理方案
// 音乐播放插件
import { sound } from '@pixi/sound';
// 加载音乐
sound.add('table', {
url: `https://mat1.gtimg.com/qqcdn/tnewsh5/short-term/centralAxis/table.mp3`,
preload: true,
});
// 播放
sound.play(‘table’);
3.海报部分:标签部分提前绘制并设置为透明,根据解锁情况显示。
这里Pixi
跟html2canvas
做一个比较:
Pixi
写海报花的时长多一些,但渲染效果和体验上优于后者,并且不会出现奇怪的兼容问题。html2canvas
异步生成在体验上会差一点,并且各个版本存在不同问题;优点是处理掺杂逻辑的海和非固定尺寸的海报非常方便,且开发快。 附两个html2canvas例子来对比:
自己撸了个工具:可以同时输出Pixi
& HTML2canvas
源代码,实现粘贴即用、减少重复代码开发。
【低代码概念为自己做一款辅助开发工具。】
接下来是开发过程以及结束后调研的笔记部分和应用:
Pixi可以做一些有意思的事情:此处省略代码块,底部附部分demo
- 使用Pixi中
SimpleRope
方法:成功复原出一张表情包🐧!演示DEMO
Pixi 内置滤镜: 演示DEMO
// 直接使用PIXI.filters的BlurFilter滤镜
const filterContainer: PIXI.Container = new PIXI.Container();
const blurFilter1 = new PIXI.filters.BlurFilter();
filterContainer.filters = [blurFilter1];
Pixi 滤镜置换: 动态的滤镜
const filterContainer: PIXI.Container = new PIXI.Container();
const displacementSprite = PIXI.Sprite.from('xxx');
const displacementFilter = new PIXI.filters.DisplacementFilter(displacementSprite);
filterContainer.filters = [displacementFilter];
const velocity =1;
const ani = () => {
requestAnimationFrame(bgAutoAni);
displacementSprite.x += velocity;
displacementSprite.y += velocity;
};
ani();
Pixi-filter 更多滤镜开箱即用: PixiJS 在4.0.0版本的时候将非核心滤镜转移到新的包。
// 引入滤镜
import { AsciiFilter } from '@pixi/filter-ascii';
import { PixelateFilter } from '@pixi/filter-pixelate';
// @param {number}
const Filter1 = new AsciiFilter(10);
const Filter2 = new PixelateFilter(20);
// 创建精灵
const spring = PIXI.Sprite.from('https://xxxxxx.png');
// 单个滤镜
img.filters = [Filter1];
// 混合多个滤镜
img.filters = [Filter1, Filter2];
- Pixi内使用Spine:演示DEMO
素材扒自spine官网
Pixi的定位是渲染引擎,能力有限;如果需要制作交互型应用,可以引入三方库来协作开发。
-
Pixi + p2.js:
在pixi中使用物理引擎
演示DEMO
-
Pixi + Bump.js
在pixi中使用碰撞检测
实现Chrom断网小游戏。演示DEMO
// 2D 碰撞检测
const b = new window.Bump(PIXI);
// true触碰 false未触碰
const isHit = b.hit(spirit1, spirit2);
-
Pixi+ GSAP 实现动画类H5。演示DEMO
文章中部分示例代码仓库:
最后附上相关链接:有兴趣的小伙伴自行查阅
Pixi官网 pixijs.com/
物理引擎 www.cpiet.com/
Spine zh.esotericsoftware.com/