【青训营】-从前端视角看游戏开发

1,025 阅读7分钟

在进入正题前,我们先来讨论一下什么是游戏

广义上的游戏

  • 最广泛的定义
    一种有组织的玩耍,一般是以娱乐为目的,有时也有教育目的
    在英语中,体育比赛(Game)也是游戏,只要其活动本周带有目的、规则、挑战和互动,我们都可以把其归为游戏

  • 比如
    篮球作为体育活动具有一定的规则约束,对参与者的体力和策略选择有要求,双方具有对抗性和互动,最终通过胜利来获得心理上的愉悦,因此可以定义为游戏

现在我们把范围缩小一下:电子游戏

在游戏中,玩家依托电子设备(如电脑,游戏机,手机等)进行交互

下面我们举一些例子:

时间游戏名游戏类型相关信息
1970年《银河战士》雅达利游戏街机家用电脑
1980年《合金装备》FC游戏街机黄金时代、早期网络游戏、LCD掌机游戏
1990年《雷神之锤》3D游戏街机衰退、掌机降临、3D出现
2000年《魔兽世界》网络游戏网络游戏崛起、游戏控制方式变革
2010年《王者荣耀》移动端游戏高分辨率、开发成本、移动端、小游戏

狭义上的游戏

狭义上的游戏即通过游戏引擎制作的电子游戏

游戏的分类: 根据玩法进行大类分,再经过小类细化

动作类(ACT)冒险类(AVG)模拟类角色扮演类(RPG)策略类(SLG)其余分支
射击游戏文字冒险游戏模拟经营游戏+动作回合制战略游戏音乐游戏
格斗游戏动作冒险游戏模拟养成游戏+模拟回合制战术游戏休闲游戏
动作冒险游戏视觉小说模拟沙盒游戏+策略即时战略游戏体育游戏
动作角色扮演游戏(ARPG)解密冒险游戏+冒险即时战术游戏竞速游戏
模拟动作游戏恋爱冒险游戏养成游戏
  • 现在的游戏可能是多个分类的重合,但是会有一个主标签
  • 那么前几年比较热门的MOBA类游戏属于什么游戏呢?
  • 即多人在线战术竞技游戏,也称即时战略游戏(RTS)

游戏开发和传统前端开发的差异

接下来通过三个方面来讲解

  1. 开发链路和角色
  2. 为什么要用游戏引擎
  3. 前端开发过渡到游戏开发

开发链路和角色

游戏开发的团队分工:
组建一个最小但最完整的游戏开发团队只需要3个人:策划、程序、美术。当然,能力足够强的话可以作为独立开发者。

游戏开发的基本链路

graph LR
立项阶段 -.->创意 -.-> 市场
原型阶段 -.-> 游戏玩法 -.-> 开发可行性
Alpha阶段 -.-> 宏观设计 -.-> 剧情/角色设计 -.-> 音效/UI设计 -.-> 体验设计
Beta阶段 -.-> 测试 -.-> 迭代 
运营阶段 

为什么要用游戏引擎

游戏引擎最大的游戏:渲染

  • 引擎的诞生就是因为一家公司做了一款游戏,做下一款游戏时复用了上一款游戏的代码,后来发现这些代码几乎每个游戏都会用到,抽离出来就成了一个引擎。
  • 如果不使用引擎,你可以做复杂的动效渲染和交互吗?当然可以。方便吗?不一定。
  • 所以游戏引擎更像是一套解决方案,让你在制作某一类型的产品的时候能够提高你的开发效率。

但是

  • 做多平台移植
    React Native、Weex、Cordova等方案也可以做到。
  • 做物理效果
    MatterJS、ammo.js等物理引擎可以用。
  • 做动画
    CSS实现又不是不行。复杂点?封装一个动画库。

那为什么要用游戏引擎呢?

  • 因为你想要的它能够给你一套完整的实现方案,不需要你再自己去拼凑、封装,让你花更少的时间做出更好的效果,特别是关于渲染效率和性能优化。
  • 它提供游戏开发时需要的常见功能:引擎会提供许多组件,使用这些组件能缩短开发时间,让游戏开发变得更简单;专业引擎通常会能比自制引擎表现出更好的性能。
  • 游戏引擎通常会包含渲染器,2D/3D图形元素,碰撞检测,物理引擎,声音,控制器支持,动画等部分。

前端开发过渡到游戏开发

需要先有一个明确的认知:前端开发和游戏开发不是相斥的。

现在市场上很多H5游戏、小游戏都是Web前端开发制作的,而不是专门的游戏开发团队、专业的游戏研发同学开发其原因可能在于
1. 接触前端开发的研发数量远大于接触游戏开发的数量(招聘成本高)
2. 2d游戏引擎的上手门槛已经足够低(易上手)
3. 活动H5中的游戏玩法的实现方式比较模糊(开发界限模糊)

  • 现在很多主流的2d游戏引擎都支持使用Javascript进行开发同时使用相关的工程化能力,也是游戏开发向web前端开发靠拢的一种表现。

  • 因此,以web前端开发的视角看2d游戏引擎,无非是一套框架、一套解决方案而已。但是开发理念上还是有差别的:游戏开发更关注内容。

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

PixiJS

微信截图_20210906154123.png

  • 官网乍一看很像一个游戏引擎,但是上面也明确说了:“用最快、最灵活的2D WebGL渲染器创建精美的数字内容”(谷歌机翻)。因此它本质上还是一个渲染引擎,而且自称做得最好。
  • 它不仅仅能做游戏,还能使用这个技术去创建任何交互式内容,比如APP,还能够在它的基础上做自己的游戏引擎。(AVG.is和 Phaser.is 的渲染引擎就是Pixi

加载玩法

1.安装和引入

npm安装 或者 通过script标签引入<script src="pixi.min.js"></script>

2.创建Pixi应用和舞台(Stage)

//第一步,创建一个显示的矩形区域,创建一个Pixi应用实例的时候会自动创建一个canvas并计算出怎么让你的图片在canvas中显示。 
let app = new PIXI.Application(f width: 250,height:250 });
//app.stage就是一个【舞台】,它包含了所有你想用Pixi显示的东西

//第二步,把canvas添加到DOM Tree中。
document.body.appendChild(app.view);
// PIXI.Applicatton计算了应该使用Canvas还是WebGL去渲染图像,取决于当前浏览器支持哪一个,一般优先使用WebGL.

// 如果你希望Canvas是透明的,或者强制使用Canvas模式,可以设置 
let app = new PIXI.Application({ 
width:250, 
height:250,
transparent: true, 
forceCanvas:true,
})

3.显示一张图片

首先理解一个概念:Sprite(精灵)

  • 学习CSS的时候可能有听过精灵图/雪碧图的概念,但是Pixi或者更多游戏引擎中Sprite的概念是一个用于承载图像的对象,你能够控制它的大小、位置等属性来产生交互、动画。
  • 创建和控制Sprite是学习Pixi很重要的部分,而创建一个Sprite需要了解图片怎么加载到Pixi中。

这里就有一个概念:纹理缓存(指可以被GPU处理的图像)

  • Pixi使用纹理缓存来存储和引用Sprite所需要的纹理。纹理的名称字符串就是图像的地址。
  • 现在有一个"images/cat.png",我们就可以使用PIXlutils.TextureCache["images/cat.png"]来在纹理缓存找到它,
  • 使用前当然要先把它转化成纹理存储在纹理缓存中,这时候可以使用PIXIloader加载进来。
PIXI.loader.add("images/cat.png").load(res => {
    let sprite = new PIXI.Sprite(
        PIXI.loader.resources["images/cat.png"].texture
        );
});
  • 现在已经创建了一个Sprite了,下一步就是显示它。
  • 我们前面说到过一个舞台的概念,记住,舞台是用来包裹你所有精灵的主要容器。(重点:你不应该看见任何没有被加入舞台的精灵)
  • 我们要显示图像就得把它添加到舞中。 这时候我们运行程序就能看到

image.png

4.让图片动起来

前面说到了可以设置Sprite的位置和大小

sprite.width = 80;
sprte.height = 120;
sprite.position.set(10, 10);
sprite.scale.set(2,2);
sprite.rotation = 0.5;

如果希望每帧移动一个像素该怎么办,这个时候就需要用到游戏循环。(任何游戏循环的代码都会每帧调用一次)

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