In der Kolumne „Entwicklung von WeChat Mini-Programmen“ wird vorgestellt, wie man mit pixi.js WeChat-Minispiele entwickelt.
1. Verwenden Sie die PixiJS-Rendering-Engine.
WeChat Mini Game ist eine andere JavaScript-Laufumgebung als der Browser, ohne BOM und DOM-API. pixi.js verwendet jedoch JavaScript in Kombination mit anderen HTML5-Technologien, um Medien anzuzeigen, Animationen zu erstellen oder interaktive Bilder zu verwalten. Es basiert auf der vom Browser bereitgestellten BOM- und DOM-API. Wenn Sie pixi.js in WeChat-Minispielen verwenden möchten, müssen Sie daher die Engine ändern. Das Minispiel bietet jedoch Unterstützung für die meisten Canvas 2d- und WebGL 1.0-Funktionen. Informationen zur Unterstützung finden Sie unter RenderingContext. pixi.js kann automatisch erkennen, ob WebGL oder Canvas zum Erstellen von Grafiken verwendet wird.
Egal um welche Art von Engine es sich handelt, das meiste, was letztendlich getan wird, wenn das Spiel läuft, ist
das Aktualisieren des Bildschirms und das Abspielen von Sounds, während der Benutzer interagiert
. Die Entwicklungssprache von Minispielen ist JavaScript, daher müssen auf der untersten Ebene der Engine die Zeichen-API und die Audio-API über JavaScript aufgerufen werden.
Die API, die ein Teil des JavaScript-Codes zur Laufzeit aufrufen kann, hängt nicht einmal vom Kern der JavaScript-Sprache ab, sondern wird von der Host-Umgebung des Browsers bereitgestellt. Zu den gängigen Hosting-Umgebungen gehören Browser, Node.js usw. Browser verfügen über BOM- und DOM-APIs, Node.js jedoch nicht; Node.js verfügt über Datei- und Netzwerk-APIs, die von Node.js-Kernmodulen wie fs und net bereitgestellt werden, aber Browser verfügen nicht über diese Module. Beispielsweise meldet der folgende Code, der normal im Browser ausgeführt wird, einen Fehler, wenn er in Node.js ausgeführt wird.
let canvas = document.createElement('canvas')复制代码
宿主环境
的。我们最常用的 console.log
ReferenceError: document is not defined复制代码
Wenn Sie eine Leinwand erstellen möchten, müssen Sie wx.createCanvas() aufrufen.
let canvas = wx.createCanvas()let context = canvas.getContext('2d')复制代码
let audio = wx.createInnerAudioContext()// src 地址仅作演示,并不真实存在audio.src = 'bgm.mp3'audio.play()复制代码
let { screenWidth, screenHeight } = wx.getSystemInfoSync()复制代码
Aber wir können den Code von pixi.js nicht ändern und es gibt keine Möglichkeit, die API-Implementierung direkt zu ändern. Es gibt eine andere Anpassungsmethode, die darin besteht, eine Ebene zwischen der Rendering-Engine und dem Spiellogikcode hinzuzufügen, um die Stückliste zu simulieren und DOM-API-Anpassungsschicht, wir nennen sie Adapter. Diese Anpassungsschicht simuliert global die Eigenschaften und Methoden der Fenster- und Dokumentobjekte, auf die die Engine über die wx-API zugreift, sodass die Engine die Unterschiede in der Umgebung nicht spüren kann.
2. Adapter Adapter . Wenn Sie daher die DOM-API zum Erstellen von Elementen wie Canvas und Image verwenden möchten, tritt ein Fehler auf.
document.body.appendChild(app.view);复制代码
ReferenceError: document is not definedReferenceError: window is not defined复制代码
const canvas = document.createElement('canvas')复制代码
function Image () { return wx.createImage() }复制代码
这些使用 wx API 模拟 BOM 和 DOM 的代码组成的库称之为 Adapter。顾名思义,这是对基于浏览器环境的游戏引擎在小游戏运行环境下的一层适配层,使游戏引擎在调用 DOM API 和访问 DOM 属性时不会产生错误。
Adapter 是一个抽象的代码层,并不特指某一个适配小游戏的第三方库,每位开发者都可以根据自己的项目需要实现相应的 Adapter。官方实现了一个 Adapter 名为 weapp-adapter, 并提供了完整的源码,供开发者使用和参考。
**
Adapter 下载地址 weapp-adapter.zip
weapp-adapter 会预先调用 wx.createCanvas() 创建一个上屏 Canvas,并暴露为一个全局变量 canvas。
require('./weapp-adapter')var context = canvas.getContext('2d') context.fillStyle = 'red'context.fillRect(0, 0, 100, 100)复制代码
除此之外 weapp-adapter 还模拟了以下对象和方法:
需要强调的是,weapp-adapter 对浏览器环境的模拟是远不完整的,仅仅只针对游戏引擎可能访问的属性和调用的方法进行了模拟,也不保证所有游戏引擎都能通过 weapp-adapter 顺利无缝接入小游戏。直接将 weapp-adapter 提供给开发者,更多地是作为参考,开发者可以根据需要在 weapp-adapter 的基础上进行扩展,以适配自己项目使用的游戏引擎。
小游戏基础库只提供 wx.createCanvas 和 wx.createImage 等 wx API 以及 setTimeout/setInterval/requestAnimationFrame 等常用的 JS 方法。
window对象是浏览器环境下的全局对象。小游戏运行环境中没有BOM API,因此没有window对象。但是小游戏提供了全局对象GameGlobal,所有全局定义的变量都是GameGlobal的属性。
console.log(GameGlobal.setTimeout === setTimeout);console.log(GameGlobal.requestAnimationFrame === requestAnimationFrame);复制代码
以上代码执行结果均为true。 开发者可以根据需要把自己封装的类和函数挂载到GameGlobal上。
GameGlobal.render = function(){ // 具体的方法实现} render();复制代码
import { canvas } from './canvas'/** * Base Element */export class Element { style = { cursor: null } appendChild() {} removeChild() {} addEventListener() {} removeEventListener() {} }export const HTMLCanvasElement = canvas.constructorexport const HTMLImageElement = wx.createImage().constructorexport class HTMLVideoElement extends Element { }复制代码
import { Canvas } from './canvas'import Image from './Image'import { Element } from './element'const stack = {}/** * document 适配 */export default { body: new Element('body'), addEventListener(type, handle) { stack[type] = stack[type] || [] stack[type].push(handle) }, removeEventListener(type, handle) { if (stack[type] && stack[type].length) { const i = stack[type].indexOf(handle) i !== -1 && stack[type].splice(i) } }, dispatch(ev) { const queue = stack[ev.type] queue && queue.forEach(handle => handle(ev)) }, createElement(tag) { switch (tag) { case 'canvas': { return new Canvas() } case 'img': { return new Image() } default: { return new Element() } } } }复制代码
import { noop } from './util'import Image from './Image'import { canvas } from './canvas'import location from './location'import document from './document'import WebSocket from './WebSocket'import navigator from './navigator'import TouchEvent from './TouchEvent'import XMLDocument from './XMLDocument'import localStorage from './localStorage'import XMLHttpRequest from './XMLHttpRequest'import { Element, HTMLCanvasElement, HTMLImageElement, HTMLVideoElement } from './element'const { platform } = wx.getSystemInfoSync() GameGlobal.canvas = canvas // 全局canvascanvas.addEventListener = document.addEventListener canvas.removeEventListener = document.removeEventListener// 模拟器 挂载window上不能修改if (platform === 'devtools') { Object.defineProperties(window, { Image: {value: Image}, Element: {value: Element}, ontouchstart: {value: noop}, WebSocket: {value: WebSocket}, addEventListener: {value: noop}, TouchEvent: {value: TouchEvent}, XMLDocument: {value: XMLDocument}, localStorage: {value: localStorage}, XMLHttpRequest: {value: XMLHttpRequest}, HTMLVideoElement: {value: HTMLVideoElement}, HTMLImageElement: {value: HTMLImageElement}, HTMLCanvasElement: {value: HTMLCanvasElement}, }) // 挂载 document for (const key in document) { const desc = Object.getOwnPropertyDescriptor(window.document, key) if (!desc || desc.configurable) { Object.defineProperty(window.document, key, {value: document[key]}) } } } else { GameGlobal.Image = Image GameGlobal.window = GameGlobal GameGlobal.ontouchstart = noop GameGlobal.document = document GameGlobal.location = location GameGlobal.WebSocket = WebSocket GameGlobal.navigator = navigator GameGlobal.TouchEvent = TouchEvent GameGlobal.addEventListener = noop GameGlobal.XMLDocument = XMLDocument GameGlobal.removeEventListener = noop GameGlobal.localStorage = localStorage GameGlobal.XMLHttpRequest = XMLHttpRequest GameGlobal.HTMLImageElement = HTMLImageElement GameGlobal.HTMLVideoElement = HTMLVideoElement GameGlobal.HTMLCanvasElement = HTMLCanvasElement GameGlobal.WebGLRenderingContext = GameGlobal.WebGLRenderingContext || {} }复制代码
思路建议为先引入通用的 Adapter 尝试运行,然后遇到的问题再逐个解决掉。
相关免费学习推荐:微信小程序开发
Das obige ist der detaillierte Inhalt vonErfahren Sie, wie Sie WeChat-Spiele mit pixi.js entwickeln. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!