学习 PixiJS — 视觉效果

29

平铺精灵

平铺精灵是一种特殊的精灵,可以在一定的范围内重复一个纹理。你可以使用它们创建无限滚动的背景效果。要创建平铺精灵,需要使用带有三个参数的 TilingSprite 类(PIXI.extras.TilingSprite)

用法:

let tilingSprite = new PIXI.extras.TilingSprite(texture, width, height);

参数:

名称 默认值 描述
texture 平铺精灵的纹理
width 100 平铺精灵的宽度
height 100 平铺精灵的高度

除此之外,平铺精灵具有与普通精灵所有相同的属性,并且与普通精灵的工作方式相同。他们还有 fromImage 和 fromFrame 方法,就像普通精灵一样。以下是如何使用名称是 brick.jpg 的100 x 100像素的图像创建200 x 200像素的平铺精灵。并且从画布左上角偏移30像素。

以下是关键代码:

let tilingSprite = new PIXI.extras.TilingSprite(
 PIXI.loader.resources[imgURL].texture, 200, 200
);
tilingSprite.x = 30;
tilingSprite.y = 30;

下图显示了 brick.jpg 图像以及上面代码的效果。

在这里插入图片描述

你可以使用 tilePosition.x 和 tilePosition.y 属性来移动平铺精灵使用的纹理。以下是如何将平铺精灵使用的纹理移动30像素。

tilingSprite.tilePosition.x = 30;
tilingSprite.tilePosition.y = 30;

这里不是在移动平铺精灵,而是移动平铺精灵使用的纹理。下图是两种情况的对比。

在这里插入图片描述

你还可以使用 tileScale.x 和 tileScale.y 属性更改平铺精灵使用的纹理的比例。以下是如何将平铺精灵使用的纹理的大小增加到1.5倍的关键代码:

tilingSprite.tileScale.x = 1.5;
tilingSprite.tileScale.y = 1.5;

原图 与 上面代码实现的效果的对比:

在这里插入图片描述

tileScale 和 tilePosition 都有一个 set 方法,可以一行代码设置 x 属性和 y 属性。

参数:

名称 默认值 描述
x 0 新的 x 属性值
y 0 新的 y 属性值

用法:

tilingSprite.tilePosition.set(30, 30);
tilingSprite.tileScale.set(1.5, 1.5);

平铺精灵是创建重复图像模式的便捷方式。因为你可以移动纹理的位置,所以你可以使用平铺精灵创建无缝的滚动背景。这对于许多类型的游戏都非常有用。让我们来看看如何做到这一点。

首先,从无缝平铺图像开始。无缝图像是图案在各方面匹配的图像。如果并排放置图像的副本,它们看起来就像是一个连续的大图像,上面示例中用到的 brick.jpg 就是这种图像。

接下来,使用此图像创建一个平铺精灵。然后在游戏循环中更新精灵的 tilePosition.x 属性。

关键代码:

function play() {
 tilingSprite.tilePosition.x -= 1;
}

效果图:
在这里插入图片描述

查看示例

你还可以使用此功能创建一个称为视差滚动的伪3D效果。就是在同一位置层叠多个这样的平铺精灵,并使看上去更远的图像移动得比更近的图像慢。就像下面这个示例一样!

两张用于做平铺精灵的图像:
在这里插入图片描述
在这里插入图片描述

实现的效果图:
在这里插入图片描述

查看示例

着色

精灵有一个 tint 属性,给这个属性赋值一个十六进制颜色值可以改变精灵的色调。

我们来试试吧!

关键代码:

sprite.tint = 0xFFFF660;

原图 与 上面代码实现的效果的对比:

在这里插入图片描述

查看示例

每个精灵的 tint 属性默认值是白色(0xFFFFFF),也就是没有色调。如果你想改变一个精灵的色调而不完全改变它的纹理,就使用着色。

蒙版

Pixi 允许你使用 Graphics (图形)对象来屏蔽任何精灵或具有嵌套子精灵的容器。蒙版是隐藏在形状区域之外的精灵的任何部分的形状。要使用蒙版,先创建精灵和 Graphics 对象。然后将精灵的 mask 属性设置为创建的 Graphics 对象。

示例:

首先,用皮卡丘的图像创建一个精灵。然后创建一个蓝色正方形并定位在精灵的上方(形状的颜色并不重要)。最后,精灵的 mask 属性设置为创建的正方形对象。这样会只显示正方形区域内精灵的图像。精灵在正方形之外的任何部分都是不可见的。

原图 与 使用蒙版后的对比:

在这里插入图片描述

关键代码:

//创建精灵
let Pikachu = new PIXI.Sprite(PIXI.loader.resources[imgURL].texture);

//创建一个正方形对象
let rectangle = new PIXI.Graphics();
rectangle.beginFill(0x66CCFF);
rectangle.drawRect(0, 0, 200, 200);
rectangle.endFill();
rectangle.x = 100;
rectangle.y = 100;

//给精灵设置蒙版
Pikachu.mask = rectangle;

查看示例

你还可以为蒙版设置动画,去做出一些有趣的效果。而且如果是用 WebGL 渲染的话,还可以用精灵作为蒙版。下面这个示例是用三张图片做成精灵,然后把一个精灵作为蒙版,并且给蒙版设置动画的示例。

在这里插入图片描述

效果图:
在这里插入图片描述

查看示例

混合模式

blendMode 属性确定精灵如何与其下层的图像混合。

如下所示,可以将它们应用于精灵:

sprite.blendMode = PIXI.BLEND_MODES.MULTIPLY;

以下是可以使用的17种混合模式的完整列表

没有混合

  • NORMAL(正常)

对比比较(饱和度模式)

  • SOFT_LIGHT(柔光)
  • HARD_LIGHT(强光)
  • OVERLAY(叠加)

对比比较(差集模式)

  • DIFFERENCE(差值)
  • EXCLUSION(排除)

减淡效果(变亮模式)

  • LIGHTEN(变亮)
  • COLOR_DODGE(颜色减淡)
  • SCREEN(滤色)
  • ADD(线性减淡,添加)

加深效果(变暗模式)

  • DARKEN(变暗)
  • COLOR_BURN(颜色加深)
  • MULTIPLY(正片叠底)

色彩效果(颜色模式)

  • HUE(色相)
  • SATURATION(饱和度)
  • COLOR(颜色)
  • LUMINOSITY(明度)

这些混合模式和图像编辑器,比如 Photoshop 中使用的混合模式是一样的,如果你想尝试每种混合模式,你可以在 Photoshop 中打开一些图像,将这些混合模式应用于这些图像上,观察效果。

注意:
WebGL 渲染器仅支持 NORMAL,ADD,MULTIPLY 和 SCREEN 混合模式。任何其他模式都会像 NORMAL 一样。

查看示例

滤镜

Pixi 拥有多种滤镜,可以将一些特殊效果应用于精灵。所有滤镜都在 PIXI.filters 对象中。滤镜是 Pixi 最好的功能之一,因为它们可以让你轻松创建一些特殊效果,否则只有通过复杂的低级 WebGL 编程才能实现这些效果。

这是一个如何创建 BlurFilter (模糊滤镜)的示例(其他滤镜遵循相同的格式):

//创建一个模糊滤镜
let blurFilter = new PIXI.filters.BlurFilter();

//设置模糊滤镜的属性
blurFilter.blur = 20;

//将模糊滤镜添加到精灵的滤镜数组中
sprite.filters = [blurFilter];

Pixi 的所有显示对象(Sprite 和 Container 对象)都有一个滤镜数组。要向精灵添加滤镜,先创建滤镜,然后将其添加到精灵的滤镜数组中。你可以根据需要添加任意数量的滤镜。

sprite.filters = [blurFilter, sepiaFilter, displacementFilter];

使用它就像使用其他普通数组一样。要清除所有精灵的滤镜,只需清除数组即可。

sprite.filters = [];

除了这些属性,所有滤镜还包括额外的 padding 和 uniforms 属性。padding 增加了滤镜区域周围的空间。uniforms 是一个可用于向 WebGL 渲染器发送额外值的对象。在日常使用中,你永远不必担心设置 uniforms 属性。

PixiJS4.0.0版本的时候,将非核心滤镜转移到新的包 — pixi-filters,现在 PixiJS 内置的滤镜有下面这几种。

用来修改对象透明度的滤镜。
在其他一些文档中,你可能看到的是 VoidFilter 这个滤镜,这是因为在 PixiJS4.6.0版本的时候,才添加 AlphaFilter,而弃用 VoidFilter。

BlurFilter 将高斯模糊应用于对象。可以分别为x轴和y轴设置模糊强度。

BlurXFilter 将水平高斯模糊应用于对象。

BlurYFilter 将垂直高斯模糊应用于对象。

ColorMatrixFilter 类允许你对 显示对象(displayObject) 上每个像素的 RGBA 颜色和 alpha 值应用5x4矩阵变换,以生成一组具有新的 RGBA 颜色和 alpha 值的结果。它非常强大!使用它可是实现黑白、调整亮度、调整对比度、去色、灰度、调整色调,等许多效果。

DisplacementFilter 类使用指定纹理(称为置换贴图)中的像素值来执行对象的位移。你可以使用这个滤镜来实现扭曲的效果。
这篇文章中已经讲过什么是 DisplacementFilter(置换滤镜)了,并且文章中也有一个不错的示例

快速近似抗锯齿滤镜。

注意:Pixi 的滤镜仅适用于 WebGL 渲染,因为 Canvas 绘图 API 太慢而无法实时更新它们。

这里有一个示例,包含了 Pixi 中绝大部分的滤镜。

查看示例

视频纹理

你可以将视频用作精灵的纹理,就像使用图像一样容易。使用 Texture 类的 fromVideo 方法就可以创建视频纹理。

videoTexture = PIXI.Texture.fromVideo(videoUrl);
videoSprite = new PIXI.Sprite(videoTexture);
stage.addChild(videoSprite);

或者,也可以使用 fromVideoUrl 方法从 URL 地址创建视频纹理。

视频纹理只是一个普通的 HTML5 <video> 元素,你可以通过纹理的 baseTexture.source 属性访问它,如下所示:

let videoSource = videoTexture.baseTexture.source;

然后,你可以使用任何 HTML5 <video> 元素的属性和方法控制视频,例如 play 和 pause 。

videoSource.play();
videoSource.pause();

查看 HTML <video> 元素的完整规范,可以知道所有可以使用的属性和方法。

查看示例

适配多种分辨率

如果你对物理像素、设备独立像素、设备像素比,等一些名词还不熟悉,可以先看看这篇文章

Pixi 会自动调整像素密度,以匹配运行内容的设备的分辨率。你所要做的就是为高分辨率和低分辨率提供不同的图像,Pixi 将帮助你根据当前的设备像素比选择正确的图像。

注意:当你创建高分辨率图像时,可以将“@2x”添加到图像文件名称后面,以说明图像是支持高分辨率的屏幕,例如,Retina 屏幕。同时这也会设置精灵的 baseTexture.resolution 属性(sprite.texture.baseTexture.resolution)。

第一步是找出当前的设备像素比。你可以使用 window.devicePixelRatio 方法执行此操作。将此值分配给变量。

let displayResolution = window.devicePixelRatio;

displayResolution 是一个描述设备像素比的数字。它由运行应用程序的设备自动提供。1是标准分辨率; 2是高密度分辨率; 你将越来越多地发现一些报告3的超高密度显示器。

下一步是将此值分配给渲染选项的 resolution 属性。在创建 Pixi 应用时执行此操作,如下所示:

//创建一个 Pixi应用 需要的一些参数
let option = {
   width: 640,
   height: 360,
   transparent: true,
   resolution: displayResolution
}
//创建一个 Pixi应用
let app = new PIXI.Application(option);

然后根据设备像素比选择正确的图像加载到纹理中。如下所示:

let texture;
if (displayResolution === 2) {
    //加载高分辨率图像
    texture = PIXI.Texture.fromImage("highResImage@2x.png");
} else {
    //加载普通分辨率图像
    texture = PIXI.Texture.fromImage("normalResImage.png");
}
let anySprite = new PIXI.Sprite(texture);

如果你需要知道加载纹理的设备像素比是多少,可以使用 texture 的 baseTexture.resolution 属性(texture.baseTexture.resolution)找出。

查看示例

绳(Rope)

另一个有趣的效果是 Rope。它允许精灵像波浪一样振荡或像蛇一样滑行,如下图所示。

在这里插入图片描述

首先,从想要变形的事物的图像开始。滑行蛇实际上是一个简单的直线图像,如下图所示。

在这里插入图片描述

然后决定你想要独立移动蛇的段数。蛇图像的宽度为600像素,因此大约20个片段会产生很好的效果。将图像宽度除以段数,就是每个绳段的长度。

let numberOfSegments = 20;
let imageWidth = 600;
let ropeSegment = imageWidth / numberOfSegments;

接下来,创建一个包含20个 Point 对象的数组。每个 Point 的 x 位置(第一个参数)将与下一个 Point 分开一个 ropeSegment 的距离。

let points = [];
for (let i = 0; i < numberOfSegments; i++) {
 points.push(new PIXI.Point(i * ropeLength, 0));
}

现在使用 PIXI.mesh.Rope 方法 new 一个 Rope 对象。这个方法需要两个参数:

  • 一个是 Rope 对象使用的纹理
  • 一个是包含 Point 对象的数组
let snake = new PIXI.mesh.Rope(PIXI.Texture.fromImage('snake.png'), points);

将蛇添加到一个容器中,这样可以更容易定位。然后将容器添加到舞台并定位它。

let snakeContainer = new PIXI.Container();
snakeContainer.addChild(snake);
stage.addChild(snakeContainer);
snakeContainer.position.set(10, 150);

现在为游戏循环中的 Point 对象设置动画。通过 for 循环将数组中的每个 Point 按照椭圆形的轨迹移动,形成波浪效果。

count += 0.1;
for (let i = 0; i < points.length; i++) {
    points[i].y = Math.sin((i * 0.5) + count) * 30;
    points[i].x = i * ropeLength + Math.cos((i * 0.3) + count) * numberOfSegments;
}

查看示例

这里还有一篇文章,讲的是用 Rope 来实现游动的锦鲤的效果,看上去也很好玩。

总结

本文主要聊了聊平铺精灵、着色、蒙版、混合模式、滤镜、视频纹理、适配多种分辨率、绳(Rope),相关的东西。

如果你觉得文字解释的不清楚,在每小节中,都有一个或者多个相应的示例,你可以点开看看,而且示例中的注释也比较清楚。
还有就是因为 PixiJS 的 API 时常有变化,所以要注意 PixiJS 的版本,文中大部分示例用的版本是4.8.2,如果你在尝试使用的时候,发现和示例的效果不一样,可以先检查一下版本。

如果文中有错误的地方,还请小伙伴们指出,万分感谢。

上一篇 学习 PixiJS — 粒子效果

下一篇 学习 PixiJS — 补间动画


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

载入中...