PIXI兼容微信小游戲


首先導入官方的weapp-adapter,然后導入pixi.min.js,微信小程序使用ES6的module引用模塊,具體參見ES6的Module。

import './libs/weapp-adapter';
import * as PIXI from './libs/pixi.min';
const { pixelRatio, windowWidth, windowHeight } = wx.getSystemInfoSync()
let game = new PIXI.Application({
width:windowWidth*pixelRatio,
height:windowHeight*pixelRatio,
view:canvas
});

let graphics = new PIXI.Graphics();
graphics.beginFill(0xfff000);
graphics.lineStyle(0, 0xffffff, 1);
graphics.drawRect(80,80,100,100);
graphics.endFill();
game.stage.addChild(graphics);
let clktext = new PIXI.Text("Click Me!",{fill:"#ffffff",fontSize:32});
clktext.interactive = true;
let times = 0;
clktext.on("pointerdown",()=>{
clktext.text = `times${++times}`;
});
clktext.x = 200;
clktext.y = 300;
game.stage.addChild(clktext);

目錄結構如下

保存運行如下:

 完美運行,但是當點擊屏幕的任何位置時,報錯了,內容如下:

TouchEvent未定義,為什么呢?看pixi源碼:

 1 InteractionManager.prototype.normalizeToPointerData = function normalizeToPointerData(event) {
 2         var normalizedEvents = [];
 3 
 4         if (this.supportsTouchEvents && event instanceof TouchEvent) {
 5             for (var i = 0, li = event.changedTouches.length; i < li; i++) {
 6                 var touch = event.changedTouches[i];
 7 
 8                 if (typeof touch.button === 'undefined') touch.button = event.touches.length ? 1 : 0;
 9                 if (typeof touch.buttons === 'undefined') touch.buttons = event.touches.length ? 1 : 0;
10                 if (typeof touch.isPrimary === 'undefined') {
11                     touch.isPrimary = event.touches.length === 1 && event.type === 'touchstart';
12                 }
13                 if (typeof touch.width === 'undefined') touch.width = touch.radiusX || 1;
14                 if (typeof touch.height === 'undefined') touch.height = touch.radiusY || 1;
15                 if (typeof touch.tiltX === 'undefined') touch.tiltX = 0;
16                 if (typeof touch.tiltY === 'undefined') touch.tiltY = 0;
17                 if (typeof touch.pointerType === 'undefined') touch.pointerType = 'touch';
18                 if (typeof touch.pointerId === 'undefined') touch.pointerId = touch.identifier || 0;
19                 if (typeof touch.pressure === 'undefined') touch.pressure = touch.force || 0.5;
20                 touch.twist = 0;
21                 touch.tangentialPressure = 0;
22                 // TODO: Remove these, as layerX/Y is not a standard, is deprecated, has uneven
23                 // support, and the fill ins are not quite the same
24                 // offsetX/Y might be okay, but is not the same as clientX/Y when the canvas's top
25                 // left is not 0,0 on the page
26                 if (typeof touch.layerX === 'undefined') touch.layerX = touch.offsetX = touch.clientX;
27                 if (typeof touch.layerY === 'undefined') touch.layerY = touch.offsetY = touch.clientY;
28 
29                 // mark the touch as normalized, just so that we know we did it
30                 touch.isNormalized = true;
31 
32                 normalizedEvents.push(touch);
33             }
34         }
35         // apparently PointerEvent subclasses MouseEvent, so yay
36         else if (event instanceof MouseEvent && (!this.supportsPointerEvents || !(event instanceof window.PointerEvent))) {
37                 if (typeof event.isPrimary === 'undefined') event.isPrimary = true;
38                 if (typeof event.width === 'undefined') event.width = 1;
39                 if (typeof event.height === 'undefined') event.height = 1;
40                 if (typeof event.tiltX === 'undefined') event.tiltX = 0;
41                 if (typeof event.tiltY === 'undefined') event.tiltY = 0;
42                 if (typeof event.pointerType === 'undefined') event.pointerType = 'mouse';
43                 if (typeof event.pointerId === 'undefined') event.pointerId = MOUSE_POINTER_ID;
44                 if (typeof event.pressure === 'undefined') event.pressure = 0.5;
45                 event.twist = 0;
46                 event.tangentialPressure = 0;
47 
48                 // mark the mouse event as normalized, just so that we know we did it
49                 event.isNormalized = true;
50 
51                 normalizedEvents.push(event);
52             } else {
53                 normalizedEvents.push(event);
54             }
55 
56         return normalizedEvents;
57     };

第四行判斷event是否是TouchEvent類型,報錯顯示就是TouchEvent未定義,TouchEvent是window的事件類型,打印一下window,發現window里沒有TouchEvent屬性,所以報錯

其實只要把window.TouchEvent暴露出來即可,把weapp-adapter.js源碼下載下來,查看源碼發現有TouchEvent,但是沒有對外導出,導出一下,然后在window.js文件再導出一下,打包一下。

webpack打包一下,替換原來的weapp-adapter.js文件,發現沒問題了。但是點擊事件出了問題,監聽不到了,怎么回事呢?

問題出在事件的點擊位置的轉換上,pixi源碼

InteractionManager.prototype.mapPositionToPoint = function mapPositionToPoint(point, x, y) {
        var rect = void 0;

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

        var 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;
    };

向上追溯源碼發現this.interactionDOMElement就是new Application()時傳進來的canvas,打印發現就是一個canvas,沒有parent。

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

iphone5為例,全屏canvas(landscape)大小是568x320而渲染尺寸(devicePixelRatio=2)是1136x640。事件監聽捕獲到的位置是基於canvas(設備)的,比如有個sprite在屏幕右下角,此時pixi.js獲取到的點擊坐標是568, 320,而sprite在渲染尺寸的位置是1136, 640,如果不進行正確的映射就無法觸發pixi.js內部實現的監聽函數。

因為在微信小游戲里canvas肯定是全屏的,所以直接計算position即可
PIXI.interaction.InteractionManager.prototype.mapPositionToPoint = (point, x, y) => {
    point.x = x * pixelRatio
    point.y = y * pixelRatio
}
或者
app.renderer.plugins.interaction.mapPositionToPoint = (point, x, y) => { point.x = x * pixelRatio point.y = y * pixelRatio }

再次運行完美!

 

 還有一個PIXI.loader 和 ajax 相關的問題,
// weapp-adapter 源碼
// src/XMLHttpRequest.js
// 添加 addEventListener 方法 
addEventListener(ev, cb) {
  this[`on${ev}`] = cb
}

基本完成了。大部分內容來自簡書

https://www.jianshu.com/p/38fcbcaf2930,之所以一步步去實現,主要是因為對一些東西還不了解。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM