使用 Pixi.js 開發微信小遊戲

源碼git

預覽

閒來無事就又折騰起微信小遊戲來,其實國內幾大遊戲引擎都支持一鍵發佈到微信小遊戲。可是對pixi.js情有獨鍾,因此開始進入正題。github

目標:把pixi-filters的在線demo放到微信小遊戲上。ajax

首先經過微信開發工具創建一個空項目,同時引入pixi.js和官方提供的weapp-adapter.jscanvas

game.js裏寫入:微信

import './libs/weapp-adapter'
import * as PIXI from './libs/pixi.min'

const {pixelRatio, windowWidth, windowHeight} = wx.getSystemInfoSync()

new PIXI.Application({
    width: windowWidth * pixelRatio,
    height: windowHeight * pixelRatio,
    view: canvas
})

一切正常的話,結果應該以下圖。微信開發

image.png

在把pixi-filtersdemo搬過來以前,先把以前遇到的坑填一下。app

咱們先在場景中添加一張圖片,而後讓他點擊隱藏。iphone

image.png

問題是,咱們點擊非但不消失,還報錯了。函數

image.png

這個報錯,是由於pixi.js裏有個判斷:ev instanceof ToucEvent 。可是微信官方的weapp-adapter.js並無把TouchEvent綁到window,因此就出問題了。解決辦法也很簡單,改一下weapp-adapter.js的源碼而後從新打包一下。工具

//  src/EventIniter/TouchEvent.js 
// 修改第五行:
export default class TouchEvent {
...

// src/window.js 
// 添加
export TouchEvent from './EventIniter/TouchEvent'

修改完畢後,從新打包並替換掉咱們libs目錄裏的weapp-adapater.js

這時候,又會有問題,就是控制檯不報錯了,可是圖片仍是不會消失。這確實很坑。 問題其實就在於pixi.js的一個mapPositionToPoint的實現,在這裏行不通。

mapPositionToPoint(point, x, y)
    {
        let rect;

        // IE 11 fix
        if (!this.interactionDOMElement.parentElement)
        {
            rect = { x: 0, y: 0, width: 0, height: 0 };
        }
        else
        {
            rect = this.interactionDOMElement.getBoundingClientRect();
        }

        const resolutionMultiplier = navigator.isCocoonJS ? this.resolution : (1.0 / this.resolution);

        point.x = ((x - rect.left) * (this.interactionDOMElement.width / rect.width)) * resolutionMultiplier;
        point.y = ((y - rect.top) * (this.interactionDOMElement.height / rect.height)) * resolutionMultiplier;
    }

上面的interactionDOMElement就是wx.createCanvascanvas,顯然是沒有parentElement,也沒有getBoundingClientRect

這個從新映射的原理很簡單。簡單說就是canvas的尺寸與渲染尺寸。

iphone5爲例,全屏canvas(landscape)大小是568x320而渲染尺寸(devicePixelRatio=2)是1136x640

事件監聽捕獲到的位置是基於canvas(設備)的,好比有個sprite在屏幕右下角,此時pixi.js獲取到的點擊座標是568, 320,而sprite在渲染尺寸的位置是1136, 640,若是不進行正確的映射就沒法觸發pixi.js內部實現的監聽函數。

// 由於在微信小遊戲裏canvas確定是全屏的,因此映射起來就很簡單暴力
// 能夠有兩種修改
app.renderer.plugins.interaction.mapPositionToPoint = (point, x, y) => {
    point.x = x * pixelRatio
    point.y = y * pixelRatio
}

PIXI.interaction.InteractionManager.prototype.mapPositionToPoint = (point, x, y) => {
    point.x = x * pixelRatio
    point.y = y * pixelRatio
}

總體代碼以下:

import './libs/weapp-adapter'
import * as PIXI from './libs/pixi.min'

const {pixelRatio, windowWidth, windowHeight} = wx.getSystemInfoSync()

const app = new PIXI.Application({
    width: windowWidth * pixelRatio,
    height: windowHeight * pixelRatio,
    view: canvas
})

app.renderer.plugins.interaction.mapPositionToPoint = (point, x, y) => {
    point.x = x * pixelRatio
    point.y = y * pixelRatio
}

const bkg = PIXI.Sprite.fromImage('./textures/bkg.jpg')
bkg.interactive = true
bkg.on('pointerdown', ev => {
    bkg.visible = false
})

app.stage.addChild(bkg)

還有一個PIXI.loaderajax 相關的問題

// weapp-adapter 源碼
// src/XMLHttpRequest.js
// 添加 addEventListener 方法 
addEventListener(ev, cb) {
  this[`on${ev}`] = cb
}

剩下的就是pixi.js的基本操做,就不寫了。順便添加了一個點擊波紋效果。

廣而告之時間:

Pixi.js 寫的小遊戲上線了,歡迎試玩。

colloc

相關文章
相關標籤/搜索