學習 PixiJS — 交互工具

說明

Pixi 內置一組功能有限的用於鼠標交互和觸摸交互的方法,可是對於遊戲和應用程序所需的豐富交互性,建議使用第三方庫來簡化操做,這篇文章介紹的是 Tink 庫,它有通用的指針對象、拖放精靈、按鈕對象、鍵盤控制 等一些有用的功能。css

使用 Tink

要開始使用 Tink ,首先直接用 script 標籤,引入 js 文件。html

<script src="https://www.kkkk1000.com/js/tink.js"></script>

而後建立它的實例,它的構造函數須要兩個參數,一個是 PIXI,另外一個是渲染器的 view 屬性,也就是用做視圖的 canvas 元素。git

let t = new Tink(PIXI, renderer.view);

變量 t 如今表明 Tink 實例,可使用它來訪問 Tink 的全部方法。github

接下來,在遊戲循環中調用 Tinkupdate 方法,來更新交互的對象,以下所示:web

function gameLoop(){
    requestAnimationFrame(gameLoop);
    state();
    t.update();
    renderer.render(stage);
}

scaleToWindow 函數

這裏提供一個 scaleToWindow 函數,它能夠將畫布縮放到瀏覽器窗口的最大大小。算法

scaleToWindow 函數的源碼在這,使用方法以下所示:json

let scale = scaleToWindow(renderer.view, borderColor);

它須要兩個參數,一個是須要縮放的 canvas 元素,另外一個參數是可選的,表示與畫布相鄰的瀏覽器背景的顏色,它能夠是任何RGB,HSLA 或十六進制顏色值,以及任何 HTML 顏色字符串,例如 blue 或者 red 。canvas

scaleToWindow 函數還返回畫布縮放到的縮放值。segmentfault

設置縮放比例

Tink 的構造函數還能夠傳入第三個參數,這個可選的參數用來確保 Tink 使用的座標將匹配畫布的縮放像素座標。在建立實例的時候能夠直接使用 scaleToWindow 函數的返回值,做爲第三個參數。數組

let scale = scaleToWindow(renderer.view);
let t = new Tink(PIXI, renderer.view, scale);

指針對象

使用 TinkmakePointer 方法能夠建立指針對象,它能夠自動肯定用戶是鼠標交互仍是經過觸摸進行交互。

let pointer = t.makePointer();

一般,一個指針對象足以知足大多數遊戲或應用程序的需求,但你也能夠根據須要製做多個指針對象。

可是若是你的遊戲或應用程序須要進行復雜的多點觸控交互,能夠考慮使用 Hammer 庫。

指針對象有三種事件:

  • press:按下鼠標左鍵或用戶將手指按到設備屏幕時觸發
  • release:釋放鼠標按鍵時或者用戶將手指從屏幕上擡起時觸發
  • tap:單擊鼠標左鍵,或者用戶點擊屏幕時觸發

用法:

pointer.press = () => console.log("觸發 pressed 事件");
pointer.release = () => console.log("觸發 released 事件");
pointer.tap = () => console.log("觸發 tapped 事件");

指針對象還有 xy 屬性,表示它在畫布上的位置。

pointer.x
pointer.y

它還有三個 Boolean 屬性,用於指示指針的當前狀態:isUpisDowntapped

pointer.isUp
pointer.isDown
pointer.tapped

查看示例

指針對象與精靈的交互

指針對象有一個 hitTestSprite 方法,可使用它來檢測指針是否正在接觸精靈。

pointer.hitTestSprite(anySprite);

若是指針位於精靈的矩形區域內,則 hitTestSprite 將返回 true 。

查看示例

hitTestSprite 方法也適用於圓形精靈。只需將精靈的 circular 屬性設置爲 true 便可。

anyCircularSprite.circular = true;

這樣 hitTestSprite 方法就使用圓形碰撞檢測算法,而不是默認的矩形碰撞檢測算法。

查看示例

若是須要指針位於精靈上時顯示手形圖標,能夠將指針的 cursor 屬性設置爲 pointer。當指針離開精靈區域時將其設置爲 auto 將顯示默認箭頭圖標。

示例:

if (pointer.hitTestSprite(anySprite)) {
    //當指針在精靈上時顯示一個手形圖標
    pointer.cursor = "pointer";
} else {
    //當指針移出精靈區域時顯示默認箭頭圖標
    pointer.cursor = "auto";
}

pointer.cursor 只是引用 canvas 元素的 style.cursor 屬性來實現這一點。你也能夠手動設置任何你喜歡的光標樣式值。方法以下:

renderer.view.style.cursor  = "cursorStyle"

不過,這些光標樣式僅適用於基於鼠標的界面,在觸摸界面上,不會起做用。

示例:

在示例中能夠看到將指針移到方形和圓形精靈上,光標是變化的。文本還會根據指針接觸的內容顯示 矩形!圓形!沒有接觸到精靈!。由於圓形精靈的 circular 屬性設置爲 true,你能看到圓形的形狀會被準確檢測到。如下是實現效果的關鍵代碼:

if (pointer.hitTestSprite(rectangle)) {
    message.text = "矩形!";
    pointer.cursor = "pointer";
} else if (pointer.hitTestSprite(circle)) {
    message.text = "圓形!";
    pointer.cursor = "pointer";
} else {
    message.text = "沒有接觸到精靈!";
    pointer.cursor = "auto";
}

查看示例

拖放精靈

你可使用 TinkmakeDraggable 方法向精靈添加拖放功能,它的參數是一個想要能夠拖動的精靈或精靈列表。

示例:

t.makeDraggable(sprite1, sprite2, sprite3);

選擇可拖動的精靈時,其堆疊順序會發生變化,拖動的精靈會顯示在其餘精靈上方。鼠標箭頭圖標在可拖動的精靈上時也會變爲手形。

查看示例

可拖動的精靈有一個名爲 draggable 的 Boolean 屬性,默認值爲 true 。要禁用拖動,將draggable 設置爲 false 便可。

anySprite.draggable = false;

將其設置爲 true 將再次啓用拖動。

要從拖放系統中徹底刪除精靈或精靈列表,須要使用 makeUndraggable 方法,以下所示:

t.makeUndraggable(sprite1, sprite2, sprite3);

按鈕

按鈕是一個重要的用戶界面(UI)組件。Tink 有一個 button 方法,用來建立按鈕。在這以前讓咱們先來了解下什麼是按鈕。

什麼是按鈕?

你能夠將按鈕理解爲可點擊或者可觸摸的精靈。它們具備狀態和動做。狀態定義按鈕的外觀,動做定義它的做用。

大多數按鈕具備如下三種狀態:

  • up:指針未觸摸按鈕時的狀態
  • over:當指針在按鈕上時的狀態
  • down:當指針按下按鈕時的狀態

以下圖所示

基於觸摸的界面的按鈕只有兩種狀態: updown

你能夠經過按鈕的 state 屬性訪問這些狀態,以下所示:

playButton.state

state 屬性可能有 upoverdown 這三個字符串值,你能夠在遊戲邏輯中使用它。

按鈕的動做,以下所示:

  • press:當指針按下按鈕時
  • release:指針從按鈕釋放時
  • over:當指針移動到按鈕區域時
  • out:當指針移出按鈕區域時
  • tap:點擊按鈕時

你能夠爲這些動做定義一個函數,當執行了相應操做時,會觸發這個函數,以下所示。

playButton.press = () => console.log("pressed");
playButton.release = () => console.log("released");
playButton.over = () => console.log("over");
playButton.out = () => console.log("out");
playButton.tap = () => console.log("tapped");

在按鈕對象中,使用 action 屬性能夠知道當前是 pressed 操做仍是 released 操做。

playButton.action

製做按鈕

首先,從定義三個按鈕狀態的三個圖像開始。三個圖像分別是 up.png,over.png 和 down.png 。而後將這三個圖像作成紋理貼圖集 ,你可使用 Texture Packer 這個工具來製做。

接下來,加載紋理圖集到程序中。

//加載紋理貼圖集,加載完後執行 setup 函數
loader.add("images/button.json").load(setup);

而後,在初始化精靈的 setup 函數中,建立一個數組,該數組有個三個成員,按順序分別對應按鈕的 up, over, 和 down 的狀態。

let id = PIXI.loader.resources["images/button.json"].textures;
let buttonFrames = [
    id["up.png"],
    id["over.png"],
    id["down.png"]
];

數組中的成員其實沒必要非要是紋理貼圖集中的幀,若是你願意,也可使用任何單個圖像紋理。

最後,使用 Tinkbutton 方法建立按鈕。使用 buttonFrames 數組做爲第一個參數。

第二個和第三個參數是按鈕的 x 和 y 座標,默認值都是0 。

let playButton = t.button(buttonFrames, 32, 96);

千萬不要忘記將按鈕添加到舞臺上!

stage.addChild(playButton);

示例:

在示例中能夠看到將指針移到按鈕上時,光標變爲手形圖標。並且在視圖中還會根據按鈕狀態和動做顯示相應的文本。

查看示例

從本質上講,按鈕只是一個普通的 Pixi 動畫精靈,所以你能夠像對待其餘動畫精靈同樣對待它。

製做交互式精靈

Tink 有另外一個名爲 makeInteractive 的方法,它容許你向任何普通精靈添加按鈕屬性和方法。

t.makeInteractive(anySprite);

這能夠將任何精靈轉換爲相似按鈕的對象,而後你能夠爲精靈添加 pressrelease 事件方法。而且能夠訪問它的 stateaction 屬性,以下所示:

anySprite.press = () => {
    //當指針按下精靈時執行某些操做
};
anySprite.release = () => {
    //按下精靈後釋放指針時執行某些操做
};

function play() {
    stateMessage.text = `State: ${anySprite.state}`;
    actionMessage.text = `Action: ${anySprite.action}`;
}

查看示例

鍵盤控制

keyboard 是一種監聽和捕獲鍵盤事件的方法。它實際上只是將原生的 keyup 和 keydown 事件封裝起來而已,如下是如何使用 keyboard 方法。建立一個新的鍵盤對象(keyObject ):

let keyObject = t.keyboard(asciiKeyCodeNumber);

它的參數是你要監聽的鍵盤鍵編碼,你能夠在這裏查看每一個鍵對應的編碼。而後你就能夠爲返回值(keyObject)定義 pressrelease 方法,以下所示:

keyObject.press = () => {
    //按鍵按下時執行某些操做
};
keyObject.release = () => {
    //按鍵釋放時執行某些操做
};

keyObject 還具備 isDownisUp 布爾屬性,你可使用它們來檢查每一個鍵的狀態。

Tink 還有另外一個方便的方法 arrowControl ,可讓你使用鍵盤方向鍵快速爲精靈建立一個4個方向的控制器。這個方法須要兩個參數,第一個是須要控制的精靈,第二個是移動速度。

示例:

t.arrowControl(anySprite, 5);
anySprite.vx = 0;
anySprite.vy = 0;

由於 arrowControl 方法能讓精靈移動,用到了精靈的速度屬性(vx,vy),因此須要給這兩個屬性一個初始值,而後在遊戲循環中須要更新精靈的位置,以下所示:

function play() {
    anySprite.x += anySprite.vx;
    anySprite.y += anySprite.vy;
}

最後,就可使用箭頭鍵在四個方向上移動精靈了。

查看示例

注意:
使用高於 4.2.1 版本的 Pixi 時,須要將 tink.js 文件中的 extras.MovieClip 改成 extras.AnimatedSprite

上一篇 學習 PixiJS — 碰撞檢測

下一篇 學習 PixiJS — 小精靈冒險

相關文章
相關標籤/搜索