學習 PixiJS — 視覺效果

FEWY發表於2019-02-03

平鋪精靈

平鋪精靈是一種特殊的精靈,可以在一定的範圍內重複一個紋理。你可以使用它們建立無限滾動的背景效果。要建立平鋪精靈,需要使用帶有三個引數的 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 內建的濾鏡有下面這幾種。

  • AlphaFilter 用來修改物件透明度的濾鏡。
    在其他一些文件中,你可能看到的是 VoidFilter 這個濾鏡,這是因為在 PixiJS4.6.0版本的時候,才新增 AlphaFilter,而棄用 VoidFilter。

  • BlurFilter BlurFilter 將高斯模糊應用於物件。可以分別為x軸和y軸設定模糊強度。

  • BlurXFilter BlurXFilter 將水平高斯模糊應用於物件。

  • BlurYFilter BlurYFilter 將垂直高斯模糊應用於物件。

  • ColorMatrixFilter ColorMatrixFilter 類允許你對 顯示物件(displayObject) 上每個畫素的 RGBA 顏色和 alpha 值應用5x4矩陣變換,以生成一組具有新的 RGBA 顏色和 alpha 值的結果。它非常強大!使用它可是實現黑白、調整亮度、調整對比度、去色、灰度、調整色調,等許多效果。

  • DisplacementFilter DisplacementFilter 類使用指定紋理(稱為置換貼圖)中的畫素值來執行物件的位移。你可以使用這個濾鏡來實現扭曲的效果。 在這篇文章中已經講過什麼是 DisplacementFilter(置換濾鏡)了,並且文章中也有一個不錯的示例

  • FXAAFilter 快速近似抗鋸齒濾鏡。

  • NoiseFilter 雜色效果濾鏡。

注意: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 — 補間動畫

相關文章