PIXI入门系列之基本使用(上篇)

2024-04-27 19:12
文章标签 使用 入门 系列 基本 pixi

本文主要是介绍PIXI入门系列之基本使用(上篇),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

在之前文章PIXI开篇中对于PIXI的定位以及历史进行了说明,相信对PIXI整体有了一定的认知,本篇是入门系列的第二篇,本篇文章主要介绍相关PIXI API的具体使用以及一些关键知识点,相关的细节性还是需要结合PIXI API文档来具体查看。PIXI版本是v8.1.0。

基础入门

import { Application, Assets, Sprite } from "./pixi.js";const initStage = async () => {// 创建应用const app = new Application();// 初始化应用逻辑await app.init({ width: 640, height: 360 });// 挂载到HTML DOM上document.body.appendChild(app.canvas);// 加载图片资源并且创建精灵元素await Assets.load("./bunny.png");const sprite = Sprite.from("./bunny.png");// 添加到stage中app.stage.addChild(sprite);// 应用ticker实现动画let elapsed = 0.0;app.ticker.add((ticker) => {elapsed += ticker.deltaTime;sprite.x = 100.0 + Math.cos(elapsed / 50.0) * 100.0;});
};
initStage();

上面是一个非常简单的PIXI案例,逻辑很简单就是创建Sprite元素添加到应用Application中,然后水平方向实现往返动画。

从上面代码逻辑中实际上可以知道很多信息:

  • 使用Application类创建应用实例,使用Assets加载图片,使用Sprite创建精灵元素
  • 应用实例的stage属性可以添加元素从而构成父子关系
  • 应用实例的ticker属性可以添加回调函数从而实现动画逻辑,回调函数就是每一帧逻辑,从而知道ticker内部是使用requestAnimationFrame来实现的
  • 应用实例的canvas属性就对应着一个canvas DOM对象,可以知道PIXI内部会创建canvas HTMLElement

结合上面的简单案例以及官网的细节,这里提炼下PIXI相关的思想以及相关API:

  • 图形元素:构成场景的内容元素,在PIXI中一个图形元素通常也是一个可渲染对象,可以是Sprite(精灵)、Text(文本)、Graphics(图形)、Container(容器)、Mesh(网格模型)等
  • 场景图:一系列可渲染对象构成场景图,而场景图是树结构从而构成元素之间的父子关系,即图形元素类似于容器可以添加子元素,从而构成一个场景树
  • 资源管理:使用Assets实现本地资源的加载管理

PIXI中可渲染对象表示可以被PIXI渲染呈现出来的对象,对于可渲染对象中的Sprite和Mesh,这里简单说明下:

  • Mesh表示网格模型,在3D中几何物体是依据网格模型创建的,顶点数据+材质数据构成物体,纹理可以应用到Mesh上
  • Sprite表示精灵模型,在3D中精灵模型就是一个二维平面,这个平面无法翻转始终面向屏幕,纹理可以应用到Sprite上

PIXI的定位是渲染2D内容,虽然是WebGL实现,但由于底层封装所以暴露出来的一些3D知识不是太多,如果有3D知识基础,那么理解PIXI中纹理Texture、Sprite、Mesh就会非常容易。这里只需要记得PIXI渲染的是2D视觉内容,在PIXI中Mesh、Sprite都是平面,其他摄像机以及投影等3D概念不需要了解。

Container

Container类代表着容器,在PIXI中它是非常重要的类,它主要提供容器以及显示对象的功能:

  • 容器功能意味着一个Container可以添加其他子对象,从而实现分组功能
  • 显示对象功能是指PIXI中可以控制是否渲染或显示某个图形元素

Container的基本使用如下:

const group = new PIXI.Container()
group.addChild(new PIXI.Sprite.from('./bunny.png'))

在PIXI中Container的属性有:

  • 位置属性:position
  • 角度属性:angle(角度)、rotation(弧度)
  • 变换属性:rotate、scale、skew、pivot(中心位置,相当于transform-origin)
  • 显示属性:renderable(可渲染)、visible(可见)
  • 透明度:alpha
const container = new Container();
container.position.set(4,4);

上面只是Container基础使用,实际上Container是非常复杂的,还涉及到交互事件、矩阵等其他属性或方法。

Sprite & Spritesheet

Sprite是PIXI中最常见的可渲染对象,每个 Sprite 都包含要绘制的纹理Texture,纹理可以简单的看成图片,在PIXI中纹理可以来源于图片或者视频。

Sprite的基本使用如下:

const texture = await Assets.load('https://pixijs.com/assets/bunny.png');
const bunnySprite = new Sprite(texture);app.stage.addChild(bunnySprite);

需要注意的是:Sprite必须设置纹理属性,实际上Sprite还有其他的属性:

  • Sprite继承自Container,所以也可以设置对应的位置、角度等属性
  • Sprite的属性anchor,它表示锚点,用于设置渲染、缩放等变换的中心点

在PIXI中纹理的加载可以通过两种API方式实现,除了上面的Assets方式,PIXI提供Texture类来实现:

const sameTexture = Texture.from('assets/image.png');

在PIXI中Sprite按照功能有多个分类:

  • Sprite:基础精灵
  • TilingSprite:平铺精灵,渲染平铺图像的快速方法
  • AnimatedSprite:动画精灵,应用多个纹理从而实现动画效果

Spritesheet表示精灵表,Spritesheet 的基本思想是将一系列图片打包成单个图片,跟踪每个源图片的最终位置,并将该组合图片用作生成的 Sprite的纹理,是优化项目的关键工具,具体使用查看PIXI官网。

Graphics & GraphicsContext

Graphics是一个复杂的图形类,它实现PIXI图形的创建,可以实现线、矩形、圆、椭圆、弧线、贝塞尔曲线等图形。

Graphics类的基本使用如下:

const obj = new Graphics().rect(0, 0, 200, 100).fill(0xff0000);app.stage.addChild(obj);

图形类提供了一系列的绘制方法,可以类比Canvas API来熟悉,两者有很多相似的地方。

在PIXI中还可以使用GraphicsContext来创建图形,GraphicsContext表示图形上下文,也可以实现相关图形的创建。GraphicsContext主要的应用场景是共享同样的绘制指令从而生成多个Graphices。

const circleContext = new GraphicsContext().circle(100, 100, 50).fill('red')const circle1 = new Graphics(circleContext)
const circle2 = new Graphics(circleContext)

Graphices本质上就是图形上下文来提供的图形绘制命令,原理和Canvas API相同,即Graphices提供context属性,只不过可以省略简写而已

const circleGraphics = new Graphics()circleGraphics.context.circle(100, 100, 50).fill('red')
文字Text

在PIXI中文字绘制有三种方式:

  • Text:静态文本,很好地控制文本的样式,适用少量文本
  • BitmapText:动态文本,占用内存低,适合大量文本
  • HTMLText:使用HTML渲染文本
const basicText = new Text({ text: 'Basic text in pixi' });const bitmapFontText = new BitmapText({text: 'bitmap fonts are supported!\nWoo yay!',style: {fontFamily: 'Desyrel',fontSize: 55,align: 'left',},
});const htmlText = new HTMLText({text: 'Hello Pixi!',style: {fontFamily: 'Arial',fontSize: 24,fill: 0xff1010,align: 'center',}
});
Assets

Assets提供基于Promise的资源管理方案,在PIXI中使用Assets可以加载常见格式的文件,例如json、图片、字体文件等。

Assets是一个单例的全局对象,无需实例化,具体使用如下:

const bunny = await Assets.load('bunny.png');

Assets实际上是PIXI封装好的方案,通常情况下使用改API就足够了,但是在PIXI中对于资源管理需要知道的是:

  • Loader:加载器,资源的加载都是通过其来实现的
  • BackgroundLoader:后台加载器,允许资源的加载在后台进行

Assets底层就是通过Loader来实现的,其他一些更加具体的可以查看PIXI API文档。

Ticker

Ticker提供在下一个请求的动画帧上执行的逻辑,可以实现循环渲染,实际上Ticker底层是基于requestAnimationFrame来实现的。

Ticker的基本使用如下:

const ticker = new Ticker()
ticker.add(() => {})// 或者关闭自动开始,手动控制渲染
ticker.autoStart = false
ticker.stop();
const animate = (time) => {ticker.update(time);renderer.render(stage);requestAnimationFrame(animate);
};
animate(performance.now());

Ticker的使用很简单,具体的内部实现后续源码系列会进行详细说明。

事件Events

在PIXI中事件系统支持Pointer、Mouse、Touch事件类型,任何派生自Container的对象都可以设置对应的EventMode从而成为可交互的对象

通常情况下可渲染对象(例如Container、Sprite)都可以注册相关事件,具体如下:

const texture = await Assets.load('https://pixijs.com/assets/bunny.png');
const sprite = Sprite.from(texture);
// 设置事件模式
sprite.eventMode = 'static';
sprite.on('click', (event) => {
});

这里需要注意的是eventMode,在PIXI中事件模式的值按照是否响应事件分为两类:

  • 不响应事件:none、passive、auto
  • 响应事件:static、dynamic

不同值代表着不同的处理逻辑,详细的说明需要结合源码来梳理,这里只需要知道通常情况下使用static就行。

在PIXI中EventEmitter API是事件系统的基础,而Container继承了EventEmitter,所以派生自Container的都可以应用事件,所以在PIXI中常见的类实例基本上都可以应用事件。

Application

想要在PIXI渲染出一个最小场景,需要哪些必须的处理逻辑呢?具体如下:

  • 一个渲染器,用于具体的渲染工作
  • 一个场景图,表示场景中视觉元素

在PIXI中可以使用相关API来创建渲染器,具体如下:

  • WebGLRenderer:webGL渲染器
  • WebGPURenderer:webGPU渲染器
  • autoDetectRendere:自动根据当前浏览器支持情况选择合适的渲染器

所以最小化场景的渲染处理逻辑如下:

// 创建场景容器
const stage = new Container();// 创建渲染器
const renderer = await autoDetectRenderer({width: 600,height: 800
});
// 挂载canvas dom
document.body.appendChild(renderer.canvas);
// 使用渲染器渲染场景
renderer.render(stage)

为了避免繁琐的处理逻辑,PIXI提供Application API来便捷实现场景的渲染,Application类会自动创建渲染器、Ticker实例和根Container

const app = new Application();
// Application需要通过调用init方法来实例化,相关参数的传递也是在此进行
await app.init({ background: "#1099bb", resizeTo: window });
document.body.appendChild(app.canvas);

通常情况下,开发者无需自己创建对应的渲染器,渲染器涉及到WebGL/WebGPU的相关知识,相对来说是比较复杂的。

这里简要说明下Application的实例属性:

  • canvas:获取canvas dom
  • renderer:获取渲染器对象
  • stage:获取根容器
  • ticker:获取ticker实例对象

遮罩Mask

在PIXI中提供遮罩功能mask,所谓的遮罩实际上是用指定形状的图层遮盖图形元素从而实现对应的效果,在CSS中也提供了相关属性。在PIXI中遮罩的使用非常简单,基本上常见的可渲染对象都有一个mask属性,该属性的值可以是Graphics或Sprite,具体使用如下:

const container = new Container();
const thing = new Graphics();container.mask = thing// 遮罩对象也需要被添加到场景中
app.stage.addChild(thing, container)

总结

本篇文章熟悉PIXI基本API的使用,主要介绍了Application、Container、Sprite、Graphics、Text、Ticker、Assets、事件系统Events、遮罩Mask,对于PIXI API的介绍使用必然无法做到面面俱到,具体细节需要结合官网文档。

实际上PIXI中还有纹理Texture、滤镜Fliter、Mesh和Shader,由于涉及到3D的一些概念,所以打算单独开一篇文章去较为详细的介绍下。

这篇关于PIXI入门系列之基本使用(上篇)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/941305

相关文章

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

java使用protobuf-maven-plugin的插件编译proto文件详解

《java使用protobuf-maven-plugin的插件编译proto文件详解》:本文主要介绍java使用protobuf-maven-plugin的插件编译proto文件,具有很好的参考价... 目录protobuf文件作为数据传输和存储的协议主要介绍在Java使用maven编译proto文件的插件

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问

SpringBoot线程池配置使用示例详解

《SpringBoot线程池配置使用示例详解》SpringBoot集成@Async注解,支持线程池参数配置(核心数、队列容量、拒绝策略等)及生命周期管理,结合监控与任务装饰器,提升异步处理效率与系统... 目录一、核心特性二、添加依赖三、参数详解四、配置线程池五、应用实践代码说明拒绝策略(Rejected

C++ Log4cpp跨平台日志库的使用小结

《C++Log4cpp跨平台日志库的使用小结》Log4cpp是c++类库,本文详细介绍了C++日志库log4cpp的使用方法,及设置日志输出格式和优先级,具有一定的参考价值,感兴趣的可以了解一下... 目录一、介绍1. log4cpp的日志方式2.设置日志输出的格式3. 设置日志的输出优先级二、Window

Ubuntu如何分配​​未使用的空间

《Ubuntu如何分配​​未使用的空间》Ubuntu磁盘空间不足,实际未分配空间8.2G因LVM卷组名称格式差异(双破折号误写)导致无法扩展,确认正确卷组名后,使用lvextend和resize2fs... 目录1:原因2:操作3:报错5:解决问题:确认卷组名称​6:再次操作7:验证扩展是否成功8:问题已解

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker