• 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({
    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,  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,之所以一步步去实现,主要是因为对一些东西还不了解。

     
    写博客能赚钱吗?如果不赚钱,那这个签名又有什么意义!所以大家多多给我发红包,多多祈祷,祈祷我成为万元户,然后普渡众生!
  • 相关阅读:
    Java之CyclicBarrier使用
    HashMap,LinkedHashMap,TreeMap的区别
    阿里巴巴常考面试题及汇总答案
    HashTable, HashMap,TreeMap区别
    Java集合类详解
    java代码的几个utils,基本可以直接用
    adb控制手机屏幕滑动(批处理)
    在设备上启用 adb 调试,有一个小秘密
    python clickZan
    python控制鼠标键盘
  • 原文地址:https://www.cnblogs.com/wangzisheng/p/8930391.html
Copyright © 2020-2023  润新知