美文网首页游戏
使用 pixi.js 开发微信小游戏

使用 pixi.js 开发微信小游戏

作者: JetLu | 来源:发表于2018-04-23 14:25 被阅读5810次

    源码
    phaser3 版

    预览

    闲来无事就又折腾起微信小游戏来,其实国内几大游戏引擎都支持一键发布到微信小游戏。但是对pixi.js情有独钟,所以开始进入正题。

    目标:把pixi-filters的在线demo放到微信小游戏上。

    首先通过微信开发工具建立一个空项目,同时引入pixi.js和官方提供的weapp-adapter.js

    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搬过来之前,先把之前遇到的坑填一下。

    我们先在场景中添加一张图片,然后让他点击隐藏。

    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

    顺便阿里云服务器了解一下: 点我

    相关文章

      网友评论

        本文标题:使用 pixi.js 开发微信小游戏

        本文链接:https://www.haomeiwen.com/subject/xmqclftx.html