源码git
闲来无事就又折腾起微信小游戏来,其实国内几大游戏引擎都支持一键发布到微信小游戏。可是对pixi.js
情有独钟,因此开始进入正题。github
目标:把pixi-filters
的在线demo
放到微信小游戏上。ajax
首先经过微信开发工具创建一个空项目,同时引入pixi.js
和官方提供的weapp-adapter.js
。canvas
在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 })
一切正常的话,结果应该以下图。微信开发
在把pixi-filters
的demo
搬过来以前,先把以前遇到的坑填一下。app
咱们先在场景中添加一张图片,而后让他点击隐藏。iphone
问题是,咱们点击非但不消失,还报错了。函数
这个报错,是由于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.createCanvas
的canvas
,显然是没有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.loader
和 ajax
相关的问题
// weapp-adapter 源码 // src/XMLHttpRequest.js // 添加 addEventListener 方法 addEventListener(ev, cb) { this[`on${ev}`] = cb }
剩下的就是pixi.js
的基本操做,就不写了。顺便添加了一个点击波纹效果。
广而告之时间:
Pixi.js 写的小游戏上线了,欢迎试玩。