zoukankan      html  css  js  c++  java
  • 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,之所以一步步去实现,主要是因为对一些东西还不了解。

     
    写博客能赚钱吗?如果不赚钱,那这个签名又有什么意义!所以大家多多给我发红包,多多祈祷,祈祷我成为万元户,然后普渡众生!
  • 相关阅读:
    Time Zone 【模拟时区转换】(HDU暑假2018多校第一场)
    HDU 1281 棋盘游戏 【二分图最大匹配】
    Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】
    Codeforces Round #527 (Div. 3) D2. Great Vova Wall (Version 2) 【思维】
    Codeforces Round #527 (Div. 3) D1. Great Vova Wall (Version 1) 【思维】
    Codeforces Round #528 (Div. 2, based on Technocup 2019 Elimination Round 4) C. Connect Three 【模拟】
    Avito Cool Challenge 2018 E. Missing Numbers 【枚举】
    Avito Cool Challenge 2018 C. Colorful Bricks 【排列组合】
    005 如何分析问题框架
    004 如何定义和澄清问题
  • 原文地址:https://www.cnblogs.com/wangzisheng/p/8930391.html
Copyright © 2011-2022 走看看