天天热点评!PixiJS 修炼指南 - 01. 启程
简介
什么是 PixiJS
PixiJS 是一个使用便捷且高效的2D渲染引擎——没错,它不是大而全的游戏引擎,而是更轻量的渲染引擎。
(资料图)
这也使得它更专注于做好高效的2D渲染工作,给予WebGL高效渲染,实现上万对象渲染的粒子效果;同时也提供了更高的自由度,可用于做任何游戏类型的渲染层,甚至仅仅用于宣传页面的2D动画绘制。
同时,作为渲染引擎,它又比纯粹的 Canvas 使用起来更为便捷,可以直接通过操作 Sprite、Container、Graphics等对象的属性完成画面中渲染效果的更新。
这样轻量易上手而又高效的渲染引擎,对于快速搭建轻量级的H5小游戏或者游戏 demo 来说可谓再合适不过。
而且,从2014年10月的第一个版本发布至今已过去近十年,仍然在不断更新迭代。2022年的 PixiJS v6 开始更是提供了 TypeScript 的支持,提供了内部对象更加方便的智能提示支持,也让大型项目使用 TS 开发后更加规范和可维护。最新的 v7 更是抛弃了各种历史包袱,更新到了现代化的前端项目生态,并且改进了一些历史 API(比如 interactive),提供新的更深入优化项目性能的能力。
对于诸如骨骼动画、游戏滤镜、物理引擎、跨平台框架等需求,PixiJS 也有各种第三方工具、插件的支持,可扩展性也十分优秀。
为什么写这篇文章
这样优秀的工具,却可能因为官方团队人力有限无暇顾及文档维护,或是觉得都是基本的开发概念不需要再重新写文档赘述,官方的文档较为简陋,基本只是罗列 API 的参考手册。
对于之前没太多了解的新同学来说,上手可能要走不少弯路。
于是就想在个人学习的笔记基础上,梳理一个从基础概念开始的学习流程供大家参考,希望能对有需要的同学有所帮助。
搭建项目
首先,我们来搭建一个使用 PixiJS 渲染的游戏项目。
方法 1. 静态引用 dist 资源
如果只是想快速体验,可以参考官方文档指南,在页面内通过 <script>标签引入 PixiJS 的 dist 文件后,直接在静态项目内体验使用 PixiJS:
<script src="https://pixijs.download/release/pixi.js"></script><script> const { Application } = window.PIXI; const app = new Application({ width: 640, height: 360, backgroundColor: 0x6495ed, }); document.body.appendChild(app.view);</script>这一方式的优点是快速可用。
但缺点也很明显,没有构建环境的支持无法使用 TypeScript 等相关能力,也不具备 Tree Shaking 优化项目产物大小等前端构建项目的常用特性。
方法 2. 基于 npm 包构建(推荐)
这一途径则是在现有的前端构建项目中,通过 npm/pnpm 安装 PixiJS,再 import 需要的模块到页面内进行开发。
优点是可以完整地使用所有 PixiJS 应有的能力,以及前端构建项目所具有的所有便捷特性。缺点是搭建最初的项目结构稍微需要花一点时间。
推荐使用 Vite 创建一个基本的 Vanilla + TypeScript 项目,再安装 pixi.js和几个常用的 PixiJS 基本子包:
$ npm create vite@latest my-pixi-demo$ cd my-pixi-demo$ npm install -S pixi.js @pixi/utils然后清空项目的入口脚本(一般为 src/main.ts),修改为:
import { Application } from "pixi.js";const app = new Application({ width: 640, height: 360, backgroundColor: 0x6495ed,});document.body.appendChild(app.view as HTMLCanvasElement);启动开发构建服务:
$ npm run dev点击打开出现的开发预览页面链接,不出意外的话,就能看到游戏的画布出现在浏览器内了。
开始工作
创建成员
刚才我们搭建完项目后,创建了一个 PixiJS 提供的 Application对象,它就是我们开发的 游戏应用了。
只不过目前它里面空空如也,只是绘制了一个指定背景色和宽高尺寸的空画布。
接下来我们就要往里面加入各种成员,让它热闹起来。
import { Application, Graphics, Sprite, Text,} from "pixi.js";const app = new Application({ width: 640, height: 360, backgroundColor: 0x6495ed,});document.body.appendChild(app.view as HTMLCanvasElement);// 创建文本成员const slogan = new Text("Hello, developer!", { fill: 0xffffff, fontSize: 32,});slogan.position.set(20, 20);// 创建图形成员const sloganBg = new Graphics();sloganBg.position.set(10, 10);sloganBg.lineStyle(4, 0x333333, .25);sloganBg.beginFill(0xefefef, .5);sloganBg.drawRoundedRect(0, 0, slogan.width + 20, slogan.height + 20, 10);sloganBg.endFill();app.stage.addChild(slogan, sloganBg);// 创建精灵成员const sprite = Sprite.from("https://hk.krimeshu.com/sprite-minion.png");sprite.anchor.set(0.5, 0.5);sprite.position.set(app.screen.width / 2, app.screen.height / 2);app.stage.addChild(sprite);效果大致如下:
基本概念
上面的例子中,除了之前提到的 Application之外,主要有以下几个新面孔:
TextGraphicsSprite以及 Application的几个成员:
显然,Text、Graphics和 Sprite将会是我们之后开发游戏常用的成员类型。其中的 Text和 Graphics顾名思义很好理解,就是 文本和 图形。而 Sprite其实也是它的字面意思“精灵”,它是具有图形材质和一系列属性、操作方法的成员对象,是我们在游戏中直接操作的基础单元之一。
1. 容器与层级
如果查看他们的 type 声明就会发现,它们具有这样的继承派生关系:
符号
->表示继承。
Graphics -> ContainerSprite -> ContainerText -> Sprite -> Container可见它们都属于一个共同的祖先类别 Container,而 Container又继承于更原始的 DisplayObject。
可推测 DisplayObject是 PixiJS 中可用于绘制的 可显示对象,应该是渲染底层操作的基础单位。
而 Container是在 DisplayObject的基础上具有类似 Web 节点性质的树形结构对象。整个游戏需要绘制的成员,都以嵌套的树形结构最终挂载于 app.stage这个顶级 Container之下。
实际上因为 PixiJS 没有 CSS 的层级概念,绘制时其实就是按照遍历整个 app.stage的树形结构,从上到下、从前到后进行绘制,后绘制对象覆盖先绘制的对象的优先级来决定层级覆盖关系。
Graphics、Sprite和 Text则是在 Container基础上,拥有更多特化后的绘制能力和操作方法的可显示对象具体子类。将它们的实例通过 addChild加入到游戏的 app.stage中,就会被 PixiJS 绘制出来,最终出现在我们眼前了。
const text1 = new Text("...");const text2 = new Text("...");// ...app.stage.addChild( text1, text2, //...);2. 屏幕
除了 app.stage之外,上面还用到了 app.screen和 app.view这两个 Application的属性。
通过查看类型定义,我们发现前者的类型是 Rectangle,即矩形,对其的官方定义为:
Rectangle对象是一个由它左上角的 原点(x, y)和自身 宽度width+高度height定义的区域。
而 app.screen就是我们整个游戏应用的矩形渲染区域,平时游戏中只有位于这个区域内的可显示对象才能被用户在页面上看到。
3. 画布
最后的 app.view则是 PixiJS 应用的渲染器所持有的 Canvas 画布对象引用。
在我们的例子中,因为创建 Application时没有传入画布对象,所以 PixiJS 内部会帮我们创建符合指定属性的画布,并挂载在 app实例的 view属性上。在这一切完成之后,我们最后将创建的 app.view画布通过 appendChild()加入到页面的 DOM 树内。
同样的,我们也可以不使用自动创建的画布,而是使用页面上已有的 Canvas 画布对象来创建 Application应用对象:
const canvas = document.querySelector("#cvsMyGame");const app = new Application({ view: canvas, width: canvas.width, height: canvas.height,});这个例子里,如果我们不将 canvas 的宽高传给 Application的构造参数,PixiJS 将会用一个默认的尺寸创建游戏,并修改为 canvas 的新宽高。所以还是需要获取后赋值传入,稍显啰嗦。
4. 更多适配
如果我们的游戏是面向移动端设备开发的话,还需要增加一个分辨率参数,以适配高分辨率设备的像素密度:
const app = new Application({ view: canvas, width: canvas.width, height: canvas.height, resolution: window.devicePixelRatio || 2,});不过如果我们的游戏应用与网页视口的尺寸始终保持一致(即所谓的“全屏游戏”)的话,其实可以也不用传入这么多参数,只需要这样配置:
const app = new Application({ view: canvas, resizeTo: window, autoDensity: true,});通过 resizeTo属性指定应用画布跟随网页窗口尺寸,还可以在用户屏幕旋转、调整窗口尺寸后由 PixiJS 自动调整画布尺寸,以适配用户设备的最新画面状态。
——不过页面内的成员坐标和尺寸并不会按新旧尺寸的比例进行调整更新,毕竟实际游戏场景的成员数可能相当多,而且不同成员的定位适配策略通常并不相同,还是需要在检测到对应 resize事件后自行调整。
这次我们创建了一个基本的 PixiJS 游戏应用,并对一些基础概念进行了说明。
但这个基本 demo 中还是有不少东西没有说清楚,并且这个应用的代码也没有合理组织,之后我们将在这个基础上继续补充和完善。
如果有什么纰漏与谬误欢迎指出~
标签:
进入了发展快车道 冷链行业市场规模正在快速膨胀
2022-03-21
行业正站在风口 数字化时代在为传统的自行车产业赋能
2022-03-21
以做强实体经济支撑为重点 成都单个项目年度计划投资同比提升
2022-03-21
拥有多个国际赛事的直播版权 广州游戏电竞企业业绩向好
2022-03-21
投诉量激增 直播带货存在这么多问题的主要原因是什么?
2022-03-21
工作专班深入到各企业 春寒料峭挡不住松原市施工热情
2022-03-21
引导企业向提供“产品+服务”转变 湖南加快智能农机服务化转型
2022-03-21
创新平台建设和科技成果转化 德州加大力度重奖创新
2022-03-21
潜在风险进一步放大 商品房现房销售已是大势所趋
2022-03-21
有序复工复产 1—2月份工业经济发展新动能持续增强
2022-03-21
进入了发展快车道 冷链行业市场规模正在快速膨胀
行业正站在风口 数字化时代在为传统的自行车产业赋能
以做强实体经济支撑为重点 成都单个项目年度计划投资同比提升
拥有多个国际赛事的直播版权 广州游戏电竞企业业绩向好
投诉量激增 直播带货存在这么多问题的主要原因是什么?
工作专班深入到各企业 春寒料峭挡不住松原市施工热情
引导企业向提供“产品+服务”转变 湖南加快智能农机服务化转型
创新平台建设和科技成果转化 德州加大力度重奖创新
潜在风险进一步放大 商品房现房销售已是大势所趋
有序复工复产 1—2月份工业经济发展新动能持续增强
多层次高频调度 1至2月河北省工业运行先行指标稳中有增
以车路协同为基础 智能交通推动城市交通绿色高质量发展
人才短板成为制约产业链高质量发展的关键节点
通过技术手段整合调配供给资源 家政行业不断提质扩容
强化产业链深层次合作 加强重大装备国产化“一条龙”模式构建
如何进一步提升纳税人缴费人的减税降费获得感?
探索建设大数据及网络安全示范试点城市有哪些积极意义?
对制造业中小微企业实施缓缴税费政策有哪些积极意义?
进一步增强自我保护意识 消费者需注意辨别谨慎消费
将“走出去”变“请进来” 西安贸易产业转移承接作用不断得到增强
厦门应如何融入“数字中国”的重大战略发展大局?
江苏省如何不断满足老人日益增长的养老服务需求?
建设一体化的职业健康信息管理平台 天津职业人群保障加强
潜力持续释放 1—2月乡村消费品市场恢复略好于城镇
直接对接社会化服务 楼宇调解室将整体提升青岛劳动争议水平
成功化解纠纷11.47万件 银保监会服务质量日趋提高
春雷响百虫出 惊蛰文化在其他方面有了进一步发展
青绿山水画在古代山水画发展史上有着怎样的影响与地位?
开播即爆款 “文化类节目收视率低”这一固有印象被推翻
- 涵盖了109件真迹作品 凯斯·哈林展览将持续至6月13日
- 带有一点自信的自嘲 “隔路”是另一种味道的“凡尔赛”
- 与文渊阁前后呼应 “何以中国”特展隆重致敬文化大成
- 严重者可造成暂时性失明 享受冰雪运动要注意眼睛的健康防护
- 种类繁多让人眼花缭乱 选购牛奶时需要重点关注什么?
- 网课让孩子感到不安焦虑怎么办?八问八答回应广大家长关切
- 循环系统很容易受到刺激 “倒春寒”期间老人该如何做?
- 青少年患者睡眠问题日趋增加 9条建议为孩子助眠
- 我国肥胖人群正逐年递增 不良饮食习惯是重要诱因
- 如何减少噪声对听力的损伤?这份耳部和听力保健小贴士请收好
- 强化住房限购措施 西安限购限售范围进一步扩大
- 多种方式增加供给 进一步降低新市民和青年人的居住成本
- 预计9月下旬海口可实现安居房申请网上办理
- 政策调控力度持续升级 8月百城二手房市场均价止涨转跌
- 8月中国新房找房热度依然保持平稳 环比微涨0.2%
- 进一步加强商品房销售价格备案管理 今年全国楼市调控刷新历史纪录
- 西安第二批集中供地中28宗为现场拍卖方式出让
- 细分化需求得到释放 房屋居住的属性越发凸显
- 佛山顺德龙江近日挂牌商住地起拍价约19.88亿元
- 青岛市4宗地竞品质抽签结果出炉 地溢价均约15%
- 坚持政策支持、多方参与 浙江版保障性租赁住房明确新增比例目标
- 简化审批流程 武汉将实现房源申请配租全程网上办
- 哈尔滨新增本土确诊病例3例 活动轨迹公布
- 哈尔滨市公布3例新增本土新冠肺炎确诊病例活动轨迹
- 山东深耕文化资源 推动旅游业高质量发展
- 今年新增952件(套)!南京大屠杀再添新证
- 四川非遗传承人张雄志:巧手捏面塑 指尖传非遗
- 10月以来我国寒潮为何如此频繁?中国气象局回应
- 56位残疾人士登上黄山 互利互勉共建生活希望
- 安徽潜山两车相撞 已致8人死亡3人受伤
- 上海洋山海关首次在出口货运渠道查获夹带卷烟
- 山西忻州古城:一城风华延续千年历史文脉
- 呼伦贝尔新巴尔虎右旗公布1例无症状感染者行动轨迹
- 新增“53+1” 内蒙古累计本土确诊病例增至185例
- 昆明公安打击破坏生物多样性犯罪 抓获130名涉案嫌疑人
- 山西朔州“11·11”较大透水事故调查报告发布 对38人问责处理
- “海关国门小卫士”竞争上岗 淘汰率接近一半
- 深圳摧毁特大品牌化妆品走私网
- 28人被问责!山西石港煤业“3·25”事故调查报告公布
- 湖南韶山以河长制带动全民治水 让每一处水面“长治久清”
- 上海市奉贤区人大常委会原党组书记袁晓林被“双开”
- 民进会员谈反映社情民意信息工作:心怀大我 敢讲实情
- 80岁“留守”奶奶短视频诉孤独 千万网友心疼:我们陪您唠嗑
- 40年来为子弟兵送出1.3万余双布鞋和鞋垫的“布鞋奶奶”走了
- 当男幼师是什么体验?他们说:有委屈尴尬 但大部分是幸福
- 庐阳警方通报幼童坠亡事件:嫌疑人已被刑拘
- 内蒙古新增本土确诊病例53例、本土无症状感染者1例
- 哈尔滨市启动部分地区第一轮全员核酸检测
- 四川通江发生两车相撞事故 致3人死亡
- 11月谣言在“身边”,别信这些无稽之谈
