小游戏开发 | 青训营笔记

327 阅读8分钟

这是我参与「第四届青训营 」笔记创作活动的第 6 天。
本篇笔记记录了小游戏开发的相关知识。主要包含 Web 游戏引擎的介绍,及 Pixi 开发示例简述。

小游戏开发

01. 前端场景下的游戏开发

开发链路和角色

组建一个最小但最完整的游戏开发团队只需要 3 个人:策划、程序、美术。

  • 策划案
    • 立项阶段:创意 市场
  • 游戏Demo
    • 原型阶段:定下核心玩法,确定开发的可行性
  • 体验版本
    • Alpha 阶段:宏观设计(世界观),剧情/角色设计,音效 / UI 设计,体验流程设计(可以体验游戏全流程)
    • Beta 阶段:测试,迭代
    • 运营阶段

image.png

为什么要用游戏引擎

游戏引擎最大的优势:渲染。
游戏引擎更像一套解决方案,在制作某一类产品时使用一些可复用逻辑 / 代码,提高开发效率。

  • 多平台移植
    • React Native、 Weex、 Cordova
  • 物理效果
    • MatterJS、ammo.js
  • 动画
    • CSS、封装一个动画库.

这些效果通过某几个库结合都可以实现,那为什么要用游戏引擎呢?

游戏引擎能够提供一套完整的实现方案,无需再自己去拼凑、封装。可以让你花更少的时间做出更好的效果,特别是关于渲染效率和性能优化。

  • 提供游戏开发时需要的常见功能。
  • 引擎会提供许多组件。
  • 专业引擎会表现出更好的性能。

游戏引擎通常会包括渲染器, 2D / 3D 图形元素,碰撞检测,物理引擎,声音,控制器支持,动画等部分。

02. 游戏引擎

特定类型的客户端游戏引擎

  • The NVL Maker 文字冒险游戏制作器
    • No Code 形式开发,只需要写文字脚本加上一定的配置就可以生成一个文字冒险游戏
    • AVG.js 适用于前端的库,内核是 PixiJS 作为渲染引擎
  • RPG Maker 可以 Low Code 搭建一个关卡类型的游戏,适合代码能力不强但是想发挥自己的创意的开发者。

Web 游戏引擎

利用 CanvasWebGL 为底层技术抽象的图像绘制库(往往还附带一些其他的功能)

Web 游戏引擎的通用能力:

预加载:

  • 游戏中往往存在大量的静态素材,包括场景、元素、声音、动画、模型、贴图等,如果以原生 JS 进行请求,并统筹请求时间和加载时机,将会非常麻烦。
  • 游戏引擎中的预加载引擎将加载时机、加载过程加以抽象,解决加载编码中的效率问题。

展示与图层、组合系统:

  • 对于 Web 游戏编程而言,往往选择 CanvasWebGL 作为渲染方式。
  • Canvas 和 WebGL 作为底层的 API,接口非常基础, 需要用大量的编码来编写简单的展示。
  • 而且图形之间没有组合和图层, 很难处理元素组合和图层问题。渲染引擎和图层、组合系统应运而生。

动画系统:

  • 动画往往被分为 缓动动画逐帧动画。这里讨论缓动动画系统。
  • 缓动动画系统在原生 JS 中需要搭配帧渲染进行考量而进行书写,代码量和思考量巨大,抽象程度低,因此需要游戏引擎动画系统。

音效和声音系统:

  • 游戏相较于普通的 Web 前端而言需要更加立体、及时的反馈,声音和音效是反馈的重要组成部分。
  • 因此声音和音效系统往往包含了声音的播放、音量、截止、暂停等功能的集成。

Web 游戏引擎 Cocos

  • 优势:
    • 平台支持能力好
    • 善的游戏功能支持
  • 缺点:
    • 3D 能力仍在建设中
    • 版本迭代过快

Web 游戏引擎 Laya

  • 优势:
    • 3D 能力比较成熟,号称市场占有率 90%
    • 支持 JS、TS、AS
    • 引擎体积小
  • 缺点:
    • 界面能力不友好
    • 生态很差

Web 游戏引擎 Egret

  • 优势:
    • 工具链比较完善
    • 第三方库支持好
    • 企业定制能力强
  • 缺点:
    • 更新迭代遭瓶颈
    • 生态较差

Web 游戏引擎 CreateJS & Phaser

这两个游戏引擎没有可视化界面。

CreateJS

它是多个库的集合,通过预加载后的素材展示、动画、声音构成游戏。

  • EASELJS:控制素材展示和组合
  • TWEENJS:控制素材缓动动画
  • SOUNDJS:控制声音
  • PRELOADJS:控制加载

PhaserJS

除了 CreateJS 为基础的的展示、声音、动画、加载系统,还设计了摄像机、物理引擎、内置浏览器、插件系统等高级功能。

功能引擎

大型游戏引擎往往是由小的功能引擎组装成的。包含:渲染引擎、物理引擎、UI 系统、声音系统、动画系统、粒子系统、骨骼系统、网络系统等组合而成。

其中最重要的便是 渲染引擎物理引擎

功能引擎是专注于某个方向能力的引擎,其特点是体积小、功能完善。

image.png

2D 游戏引擎的技术架构

以 Cocos 的引擎架构为例子:

image.png

Web 游戏引擎的渲染原理

Pixi 的渲染流程为例子:

  1. 创建一个 Renderer 渲染器,获取它的 view(一个 canvas 对象),添加到 DOM Tree 中。 (或者指定 Dom Tree 中已经存在的 canvas 对象作为 view)
  2. MainLoop 主循环中调用 Reanderer.render() 并传入一个 DisplayObject 作为根节点开发渲染。
    • 主循环每帧调用一次,可以进行一个帧渲染。
  3. 从场景树的根节点开始,以 zIndex 为序从小到大进行深度优先遍历,对每个节点进行渲染操作,由后往前把整个场景绘制一次。
  4. WebGLrender 方法执行过程。
    • image.png
  5. Canvasrender 方法执行过程。
    • image.png

03. 游戏开发技能树

游戏前端开发入门技能树

image.png

为什么使用 Canvas 进行渲染而不使用 DOM?

  • 由渲染效率决定,DOM 渲染较慢
  • 浏览器的渲染模式分为两种:
    • 保留模式:向浏览器的 API 发送渲染命令,由浏览器帮我们渲染
    • 快速模式:直接将指令发送给 CPU,直接执行指令
  • DOM 渲染采用保留模式,Canvas 渲染采用快速模式。

04. PixiJS + Web 开发

Web 项目中加载一个游戏玩法

  1. 安装与引入

    • npm 安装
    • script 引入
  2. 创建 Pixi 应用和舞台(Stage)

    • 舞台:展示所有精灵对象的主要容器。
    // 1. 创建 Pixi 应用,会自动创建一个 canvas 并计算出怎么让你的图片在 canvas 中显示。
    //    app.stage 就是一个舞台,包含了需要显示的图片
    //    计算了应该使用 Canvas 还是 WebGL 去渲染图片,取决于当前浏览器支持哪一个,一般优先使用 WebGL
    let app = new PIXI.Application({width:250, height:250})
    // 2. 将 canvas 添加到 DOM Tree 中
    document.body.appendChild(app.view)
    ​
    // 3. 设置 Canvas 是透明的,或者强制使用 Canvas 模式
    let app = new PIXI.Application({
      width:250,
      height:250,
      transparent:true,
      forceCanvas:true
    })
    
  3. 显示一张图片

    • Sprite承载图像的对象。不同于 CSS 中的雪碧图 / 精灵图。

      • 可以控制它的大小、位置等属性来产生交互、动画
      • 创建和控制 Sprite 是学习 Pixi 很重要的部分,而创建一个 Sprite 需要了解图片怎么加载到 Pixi 中。
    • 纹理缓存指可以被 GPU 处理的图像。

      • Pixi 使用纹理缓存来存储和引用 Sprite 所需要的纹理。
      • 纹理的名称字符串就是图像的地址。
      • "images/cat.png" ,就可以使用 PIXI.utils.TextureCache["image/cat.png"] 来在纹理缓存中找到它。
    • 使用前当然要先把它转化为纹理存储在纹理缓存中,这时候可以使用 PIXI.loader 加载进来。

      PIXI.loader.add("images/cat.png").load(res => {
        let sprite = new PIXI.Sprite(
          PIXI.loader.resources["images/cat.png"].texture
        )
      })
      ​
      app.stage.addChild(sprite)
      
  4. 让图片动起来

    • 设置 Sprite 的位置和大小:

      sprite.width = 80
      sprite.height = 120
      sprite.position.set(10, 10)
      sprite.scale.set(2, 2)
      sprite.retation = 0.5
      
    • 每帧移动一个像素,需要用到游戏循环。

      • app.tiker.add(delta => {
          sprite.x += 1
        })
        

05. Cocos Creator 编辑器开发

Cocos Creator 介绍

是一个完整的游戏开发解决方案,包含了轻量高效的跨平台游戏引擎,以及能更快速开发游戏所需要的各种图形界面工具。

编辑器开发集成的能力

image.png

创建项目

搭建场景

Cocos 的工作流——数据驱动和场景为核心、组件式开发为核心。

image.png

节点 cc.Node 是承载组件的实体,我们通过将具有各种功能的组件(如 SpriteSpineLabel)挂载到节点上,来让节点具有各式各样的表现和功能。

image.png

导入资源 + 显示资源

从操作系统中拖拽文件到 Cocos Creator 中的资源管理器面板上,该操作会自动复制资源文件到项目资源文件夹下,并完成导入操作。

将图片拖动到层级管理器即可生成一个 cc.Sprite

脚本挂载

const {property, ccclass} = cc._decorator
@ccclass
export default class TestComp extends cc.Component {
  onLoad() {
    console.log('TestComp onload')
  }
  
  start(){}
  
  update(dt) {}
  
  onDestroy() {}
}

在 Cocos Creator 中对应的结点将脚本挂载上去。

运行调试