>  기사  >  위챗 애플릿  >  pixi.js를 사용하여 WeChat 게임을 개발하는 방법 알아보기

pixi.js를 사용하여 WeChat 게임을 개발하는 방법 알아보기

coldplay.xixi
coldplay.xixi앞으로
2020-10-29 17:39:514806검색

WeChat 미니 프로그램 개발 칼럼에서는 pixi.js를 활용하여 WeChat 미니 게임을 개발하는 방법을 소개합니다.

pixi.js를 사용하여 WeChat 게임을 개발하는 방법 알아보기

1. PixiJS 렌더링 엔진 사용

WeChat 미니 게임은 BOM 및 DOM API 없이 브라우저와 다른 JavaScript 실행 환경입니다. 그러나 pixi.js는 다른 HTML5 기술과 결합된 JavaScript를 사용하여 미디어를 표시하고 애니메이션을 생성하거나 대화형 이미지를 관리합니다. 브라우저에서 제공하는 BOM 및 DOM API를 사용합니다. 따라서 위챗 미니게임에서 pixi.js를 사용하려면 엔진을 수정해야 합니다.

그러나 미니 게임은 대부분의 Canvas 2d 및 WebGL 1.0 기능을 지원합니다. 지원 정보는 RenderingContext를 참조하세요. pixi.js는 그래픽 생성에 WebGL 또는 Canvas가 사용되는지 자동으로 감지할 수 있습니다.

어떤 종류의 엔진이든, 게임이 실행될 때 궁극적으로 수행되는 대부분의 작업은 사용자 상호 작용에 따라 화면을 업데이트하고 사운드를 재생하는 것입니다. 미니게임의 개발 언어는 JavaScript이므로 엔진 최하위 레벨에서는 Drawing API와 Audio API를 JavaScript를 통해 호출해야 합니다.

런타임에 JavaScript 코드 조각이 호출할 수 있는 API는 宿主环境 的。我们最常用的 console.logJavaScript 언어의 핵심 부분이 아니라 브라우저의 호스트 환경에서 제공되는 API에 따라 달라집니다. 일반적인 호스팅 환경에는 브라우저, Node.js 등이 포함됩니다. 브라우저에는 BOM 및 DOM API가 있지만 Node.js에는 없습니다. Node.js에는 fs 및 net과 같은 Node.js 핵심 모듈에서 제공하는 파일 및 네트워크 API가 있지만 브라우저에는 이러한 모듈이 없습니다. 예를 들어 브라우저에서 정상적으로 실행되는 다음 코드는 Node.js에서 실행될 때 오류를 보고합니다.

let canvas = document.createElement('canvas')复制代码

Node.js 호스트 환경에서는 내장된 전역 변수 문서를 전혀 제공하지 않기 때문입니다.

ReferenceError: document is not defined复制代码

미니게임의 실행환경은 브라우저와는 다른 호스트 환경입니다. BOM, DOM API를 제공하지 않고, wx API를 제공합니다. wx API를 통해 개발자는 Native에서 제공하는 드로잉, 오디오 및 비디오, 네트워크, 파일 및 기타 기능을 호출할 수 있습니다.
pixi.js를 사용하여 WeChat 게임을 개발하는 방법 알아보기
캔버스를 생성하려면 wx.createCanvas()를 호출해야 합니다

let canvas = wx.createCanvas()let context = canvas.getContext('2d')复制代码

오디오 객체를 생성하려면 wx.createInnerAudioContext()를 호출해야 합니다

let audio = wx.createInnerAudioContext()// src 地址仅作演示,并不真实存在audio.src = 'bgm.mp3'audio.play()复制代码

화면의 너비와 높이를 변경하려면 wx.getSystemInfoSync()

let { screenWidth, screenHeight } = wx.getSystemInfoSync()复制代码

를 호출해야 합니다. 하지만 pixi.js 기반 렌더링 엔진은 다음과 같은 방식으로 스테이지를 생성하고 페이지에 마운트합니다

document.body.appendChild(app.view);复制代码

오류 이때 발생하는 이유는 위에서 언급한 바와 같이 미니게임의 호스트 환경인 Document와 Window에 내장된 두 개의 전역변수인 브라우저가 전혀 제공되지 않기 때문입니다. 미니게임 환경은 브라우저와는 다른 호스팅 환경이기 때문입니다.

ReferenceError: document is not definedReferenceError: window is not defined复制代码

그래서 기본적으로 pixi.js를 기반으로 개발된 소규모 게임은 pixi.js 구현 시 브라우저 환경별 API인 BOM 및 DOM을 어느 정도 사용할 수 있기 때문에 직접 소규모 게임으로 마이그레이션하여 사용할 수 없습니다. pixi.js를 수정하고 BOM 및 DOM API 호출을 wx API 호출로 변경해야만 미니게임 환경에서 실행할 수 있습니다.

하지만 pixi.js의 코드를 변경할 수 없으며 API 구현을 직접 수정할 방법도 없습니다. 렌더링 엔진과 게임 로직 코드 사이에 레이어를 추가하여 BOM을 시뮬레이션하는 것입니다. DOM API 적응 레이어를 어댑터라고 부릅니다. 이 Adaptation 레이어는 엔진이 wx API를 통해 접근할 창과 문서 객체의 속성과 메소드를 전역적으로 시뮬레이션하여 엔진이 환경의 차이를 느낄 수 없도록 합니다.
pixi.js를 사용하여 WeChat 게임을 개발하는 방법 알아보기
Adapter는 기본 라이브러리의 일부가 아닌 사용자 코드입니다. Adapter에 대한 소개는 Adapter 튜토리얼을 참조하세요.

2. Adapter Adapter

1. weapp-adapter

미니게임의 실행 환경은 iOS의 경우 JavaScriptCore이고 Android의 경우 V8이며, 전역 문서 및 창 개체가 없습니다. . 따라서 DOM API를 사용하여 Canvas, Image 등의 요소를 생성하려는 경우 오류가 발생합니다.

const canvas = document.createElement('canvas')复制代码

하지만 wx.createCanvas 및 wx.createImage를 사용하여 문서를 캡슐화할 수 있습니다.

const document = {    createElement: function (tagName) {
        tagName = tagName.toLowerCase()        if (tagName === 'canvas') {            return wx.createCanvas()
        }        else if (tagName === 'image') {            return wx.createImage()
        }
    }
}复制代码

이제 코드는 브라우저에서 요소를 생성하는 것처럼 캔버스와 이미지를 생성할 수 있습니다.

const canvas = document.createElement('canvas')const image = document.createImage('image')复制代码

마찬가지로 new Image()를 구현하여 Image 객체를 생성하려면 다음 코드를 추가하기만 하면 됩니다.

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 还模拟了以下对象和方法:

  • document.createElement
  • canvas.addEventListener
  • localStorage
  • Audio
  • Image
  • WebSocket
  • XMLHttpRequest
  • 等等...

需要强调的是,weapp-adapter 对浏览器环境的模拟是远不完整的,仅仅只针对游戏引擎可能访问的属性和调用的方法进行了模拟,也不保证所有游戏引擎都能通过 weapp-adapter 顺利无缝接入小游戏。直接将 weapp-adapter 提供给开发者,更多地是作为参考,开发者可以根据需要在 weapp-adapter 的基础上进行扩展,以适配自己项目使用的游戏引擎。

2. pixi-adapter

小游戏基础库只提供 wx.createCanvas 和 wx.createImage 等 wx API 以及 setTimeout/setInterval/requestAnimationFrame 等常用的 JS 方法。

1.全局对象

window对象是浏览器环境下的全局对象。小游戏运行环境中没有BOM API,因此没有window对象。但是小游戏提供了全局对象GameGlobal,所有全局定义的变量都是GameGlobal的属性。

console.log(GameGlobal.setTimeout === setTimeout);console.log(GameGlobal.requestAnimationFrame === requestAnimationFrame);复制代码

以上代码执行结果均为true。 开发者可以根据需要把自己封装的类和函数挂载到GameGlobal上。

GameGlobal.render = function(){    // 具体的方法实现}
render();复制代码

2. Element 元素构造

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 {

}复制代码

3. document 构造

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()
      }
    }
  }
}复制代码

4.统一入口

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 尝试运行,然后遇到的问题再逐个解决掉。

相关免费学习推荐:微信小程序开发

위 내용은 pixi.js를 사용하여 WeChat 게임을 개발하는 방법 알아보기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.im에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제