探索Pixi.js的潜力:打造专业级网页游戏《消消乐》(上)

网页游戏以其便携性通常内嵌在各大app中,通过提供沉浸式的游戏体验拉近用户与app之间的距离,最终将用户流量转换为具体的物质价值,这就是网页游戏的价值之一。

本文将带你从零使用Pixi.js打造一款专业级别的网页游戏—消消乐,在线体验网址。通过本文,你会学习到如何使用Pixi及其生态开发一款专业的游戏,充分感受pixi在交互式应用上的魅力。

本文传达的技术或思想不会限制在pixi应用,比如静态资源处理,游戏路由管理器设计理念,缓存池,可暂停可恢复的异步队列管理器等等一系列最佳实战,你都可以直接或举一反三应用到自己的实际项目当中。

游戏主要界面预览

首页

image.png

准备状态

image.png

消除状态

image.png

游戏及结束状态

QQ20230807-123411-HD.gif

Pixi简介及其生态

Pixi.js是一款开源的、基于WebGL的2D渲染引擎,被广泛应用于创建交互式的、富有创意的Web应用程序比如游戏,DIY设计等。

在笔者使用pixi期间,个人非常喜欢它的以下特性:

  1. 灵活的API设计。使它可以方便地与其它库相结合,比如 pixi-react
  2. 遮罩系统。类似于CSS中的mask-image或PS中的剪切蒙版,我们可以很方便地将图像、容器等限制在其它图形图像的可视区域内。笔者之前写过一个基于Vue3+Pixi.js开发的DIY设计项目,就是得益于pixi灵活的API设计与遮罩系统,使它可以很方便地与Vue3自定义渲染器相结合并实现了可设计区域。
  3. 较为丰富的生态
    • @pixi/ui:基于pixi的,通用的,可扩展的UI组件库;
    • @pixi/layout:简单快捷地在游戏中创建响应式布局。
    • @pixi/sound:音频管理。基于WebAudio API。
    • AssetPack:静态资源打包器。通过它,我们可以生成manifest.json静态资源清单文件,打包纹理图集(类似于雪碧图),压缩图片,json等,格式转换如ttf转体积更小woff2格式,wav转兼容性更好的MP3格式等。这些功能可帮助我们优化静态资源,以加快加载时间、提高性能和改善用户体验。
    • pixi-spine:在pixi中应用spine动画

以上库我们在打造消消乐游戏中都会使用到,当然,还有大名鼎鼎的js动画库gsap以及家喻户晓的现代构建工具 vite

此外,pixi是基于WebGL的,这使得它能够利用硬件加速来实现高效的渲染,据官方透露,PixiJS V8将会对WebGPU进行更好的支持,届时其渲染性能也会更上一层。pixi社区也提供了丰富的滤镜库以帮助我们实现各种图像效果比如模糊,渐变,色彩调整,马赛克,置换等等。当然,对ts的支持也至关重要,在使用这种多API的库时,我可不希望点一个对象没有任何提示~。

未来pixi还会进一步支持3D渲染,游戏引擎,脚手架等,使游戏开发更轻松,更高效。总之,pixi的潜力很大,在构建数字化内容网站时,限制我们的往往是想象力,而不会是pixi或其它技术本身了。更多详情详见pixi官网,下面我们进入正式的开发当中。

准备工作

在开发前我们需要准备一些开发工具,它们可以帮助我们更好更快地理解pixi。

1.PixiJS Devtools。一款可视化、用于开发调试pixi应用的浏览器扩展插件,在火狐、谷歌扩展商店都有提供下载。通过它我们可以看到画布中元素之间的嵌套关系,重要的是我们可以看到元素支点(pivot或anchor)的位置,这对于元素的布局太有用了!

2.AI工具。先不说pixi目前没有中文文档,即使翻译成中文,其中有一些专有名词在我们没有足够的实战经验下也会难以理解(这一点真的劝退大部分人),比如元素属性tiny,texture,变换矩阵等,这就需要AI工具帮我们快速解读。我为项目编写了大量注释,一方面除了帮助他人理解,另一方面也为AI工具提供了详细的代码上下文,这样,AI会更加理解你的意图以便给出更符合我们预期的答案。目前免费的这里推荐codeGeeX(清华系)codeium,VSCode扩展中直接搜索下载即可,不过codeium貌似授权需要魔法。如果你已经有心仪的AI工具可以忽略这里。

3.语言翻译工具。在阅读pixi官方文档以及本项目源码注释时,你可能会需要到。笔者使用的是 沉浸式翻译

当然,还有一款心仪的代码编辑器,以及一颗对游戏或好奇或热爱的心。Let us go.

打包静态资源

首先我们需要使用pnpm init初始化项目,并且安装相关依赖:

安装生产依赖

这里值得注意的@pixi/ui使用的是0.5版本

pnpm i @pixi/sound @pixi/ui@0.5.0 gsap pixi-spine pixi.js

安装开发依赖

pnpm i vite @assetpack/cli @assetpack/plugin-compress @assetpack/plugin-ffmpeg @assetpack/plugin-json @assetpack/plugin-manifest @assetpack/plugin-texture-packer @assetpack/plugin-webfont -D
  1. @assetpack/cli:assetpack脚手架。
  2. @assetpack/plugin-compress:使用 sharp 压缩图像的AssetPack插件。
  3. @assetpack/plugin-ffmpeg:使用ffmpeg转换音视频文件的AssetPack插件。这里需要在系统上安装ffmpeg,首先在ffmpeg官网下载系统对应的安装包,解压,安装。最后需要配置系统环境变量,以下是mac操作:
# 打开.zshrc,没有就新建
open ~/.zshrc

# 加入以下代码,$PATH后面跟ffmpeg可执行程序所在的文件夹
export PATH=$PATH:/Users/用户名/Downloads

# 使环境变量生效
source ~/.zshrc

最后在终端输入ffmpeg -h检验一下,系统就会在指定的$PATH中查找对应的可执行程序进行启动。

  1. @assetpack/plugin-json:用于压缩JSON文件的AssetPack插件。
  2. @assetpack/plugin-webfont:用于将ttf、otf、woff和svg格式字体转换成体积更小的woff2字体的AssetPack插件。
  3. @assetpack/plugin-manifest:生成manifest.json资源清单文件,这是pixi V7版本中加载资源清单的最佳实践。
  4. @assetpack/plugin-texture-packer:使用Texture Packer生成纹理图集(类似雪碧图或者序列帧集合)的AssetPack插件,可用于优化请求次数。

使用assetpack打包资源

新建.assetpack.js,配置如下:

import {
    compressJpg, compressPng } from '@assetpack/plugin-compress';
import {
    audio, ffmpeg } from '@assetpack/plugin-ffmpeg';
import {
    json } from '@assetpack/plugin-json';
import {
    pixiManifest } from '@assetpack/plugin-manifest';
import {
    pixiTexturePacker } from '@assetpack/plugin-texture-packer';
import {
    webfont } from '@assetpack/plugin-webfont';

export default {
   
    entry: './raw-assets', // 原始资源存放位置
    output: './public/assets/', // 打包后存放位置
    cache: false, // 不使用缓存
    plugins: {
   
        webfont: webfont(), // 字体转woff格式
        compressJpg: compressJpg({
    // 压缩jpeg
            compression: {
   
                quality: 90
            }
        }),
        compressPng: compressPng(), // 压缩png
        // audio: audio(), // 快捷配置将wav转mp3,但会同时生成ogg格式
        // 因此这里使用ffmpeg进行更详细的配置
        ffmpeg: ffmpeg({
   
            inputs: ['.wav'],
            outputs: [
                {
   
                    formats: ['.mp3'],
                    recompress: true, // 是否重新压缩。比如mp3转mp3也压缩
                    // options必须提供,可以为空对象
                    options: {
   
                        audioBitrate: 96,
                        audioChannels: 1,
                        audioFrequency: 48000,
                    }
                },
            ]
        }),
        json: json(), // 压缩json
        texture: pixiTexturePacker({
   
            texturePacker: {
   
                removeFileExtension: true, // 移除扩展名
            }
        }),
        // 名称末尾带{m}标识的文件夹或文件都会添加到manifest清单
        manifest: pixiManifest({
   
            output: './public/assets/assets-manifest.json'
        }),
    },
};

在.assetpack.js配置中,由于我们使用到了es6 module,因此需要在package.json中配置type: "module"。然后在package.json中添加打包的npm script:

{
   
    "assetpack": "assetpack"
}

最后运行一下assetpack命令pnpm run assetpack即可打包资源。关于assetpack插件用法请自行查阅文档,最后简单看下打包结果(具体可在文末找到项目地址,将其clone到本地运行查看结果)。

image.png

  1. common是游戏欢迎页,游戏页,游戏结果页的共同资源。
  2. game是游戏页需要的资源。
  3. home是游戏欢迎页需要的资源。
  4. preload是加载页需要的资源。
  5. result是游戏结果页需要的资源。
  6. assets-manifest.json就是所有资源的清单文件。它的格式大概如下:
{
   
  "bundles": [
    {
   
      "name": "preload",
      "assets": [
        {
   
          "name": [
            "preload/cauldron-skeleton.atlas"
          ],
          "srcs": [
            "preload/cauldron-skeleton.atlas"
          ],
        }
        // ...
      ]
    },
    {
   
      "name": "home", 
      "assets": [
        // 一系列资源列表...
      ]
    },
    // ...
  ]
}
纹理图集打包预览

image.png

使用vite启动一个最简单的pixi项目

1.新建src/app.ts

创建并导出一个Pixi应用

import {
    Application, Text } from "pixi.js";
import {
    isDev } from "./utils/is";

Text.defaultResolution = 2;
Text.defaultAutoResolution = false;

export const app = new Application<HTMLCanvasElement>({
   
    backgroundColor: 0xffffff,
    backgroundAlpha: 0,
    resolution: 2,
})

isDev() && (globalThis.__PIXI_APP__ = app);
  • Text.defaultResolution = 2; 表示文字抗锯齿
  • isDev() && (globalThis.PIXI_APP = this); 开发环境启用Pixi DevTool

2.新建src/main.ts

引入app并将canvas元素(即app.view)添加到页面上。

import {
    app } from "./app";

async function init() {
   
    // add canvas element to body
    document.body.append(app.view)

    // hide loading
    document.body.classList.add('loaded')
}

init()

3.新建index.html

应用入口文件,引入main.ts,并添加值为"module"的type属性,同时添加CSS loading动画。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta char
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值