游戏中的视觉效果定义了游戏的整体外观,感觉和游戏玩法。 高品质的视觉效果吸引了玩家,这带来了更多的流量和影响力。 这是创造成功游戏并为玩家带来很多乐趣的关键。
在本文中,我们想提出一些关于如何在基于的HTML5游戏中实现不同视觉效果的想法 。 这些示例将基于我们在游戏《 Skytte》中所做的效果。 我们将解释支持它们的基本思想,并提供在我们的工作中使用的效果。
- 低聚货柜| 3D游戏资产[教程]
- Westeros地牢大师指南
- 要成功开发游戏,请不要尽力而为。 这就是为什么...
- 2018年度业绩:来自Kefir的Peter Kostylev关于年度关键点
- 游戏开发恨我们所有人
您将学到什么
在开始之前,我们想阐明一些事情,希望您能从本文中学到:
- 基本的游戏设计:我们将研究通常用于制作游戏和游戏效果的模式,例如:游戏循环,子画面,碰撞和粒子系统。
- 视觉效果的基本实现:我们还将探讨支持这些模式的理论和一些代码示例。
常见模式
让我们从游戏开发中使用的一些常见模式和元素开始。
精灵
这些只是代表游戏中对象的2D图像。 当每个精灵代表一帧连续动画时,精灵可用于静态对象,也可用于动画对象。 它们也可以用于制作用户界面元素。
通常,游戏包含数十到数百个精灵。 为了减少内存使用量和处理这些图像所需的处理能力,许多游戏都使用精灵表 。
雪碧表
这些用于在一个图像中对一组单个精灵进行分组。 这减少了游戏中的文件数量,从而减少了内存和处理能力。 Sprite表单包含许多单个的Sprite,它们在行和列中彼此相邻堆叠,并且像它们包含的Sprite一样,可以静态使用或用于动画。

精灵表示例。 (图片来源:Kriplozoik)
这是Code + Web上的一篇文章,可以帮助您更好地了解使用Sprite工作表的好处。
游戏循环
重要的是要意识到游戏对象不会真正在屏幕上移动。 通过将游戏世界的快照渲染到屏幕上,将游戏时间提前一小段时间(通常是1/60秒),然后再次渲染事物,可以实现移动的幻觉。 这实际上是定格效果,可用于2-D和3-D游戏。 游戏循环是一种实现这种定格的机制 。 这是运行游戏所需的主要组件。 它会随着时间连续运行,执行各种任务。 在每次迭代中,它都会处理用户输入,移动实体,检查碰撞并渲染游戏(最好按此顺序)。 它还可以控制帧之间的游戏时间。
以下是JavaScript中非常基本的游戏循环:

请注意,上面的示例非常简单。 它使用可变增量时间(经过的变量),建议升级此代码以使用固定增量时间。 有关更多详细信息,请参见本文。
碰撞检测
碰撞检测是指找到对象之间的相交。 这对于许多游戏来说都是必不可少的,因为它用于检测玩家是撞墙还是子弹撞到敌人等等。 当检测到碰撞时,可以将其用于游戏逻辑; 例如,当子弹击中玩家时,生命值降低10点。
冲突检测算法很多,并且由于它是性能繁重的操作,因此,明智地选择最佳方法非常重要。 要阅读有关碰撞检测,算法以及如何实现它们的更多信息,这是MDN的文章。
粒子和粒子系统
粒子基本上是粒子系统使用的精灵。 在游戏开发中,粒子系统是一个由粒子发射器和分配给该发射器的粒子组成的组件。 它用于模拟各种效果,例如火灾,爆炸,烟雾和雨水效果。 随着时间的推移会发射粒子,每个发射器都有自己的参数,以定义用于模拟效果的各种变量,例如速度,颜色,粒子的寿命或持续时间,重力,摩擦和风速。
欧拉积分
欧拉积分是一种对运动方程进行数值积分的方法。 每个对象的位置都是基于其速度,质量和力来计算的,并且需要针对游戏循环中的每个刻度重新计算。 欧拉方法是最基本和最有用的方法,如侧滚动射击游戏 ,但是还有其他方法,例如Verlet集成和RK4集成 ,更适合其他任务。 下面我们将展示该想法的简单实现。
您需要一个基本结构来保存对象的位置,速度和其他与运动有关的数据。 我们提出了两个相同的结构,但每个结构在世界空间中的含义不同:点和向量。 通常,游戏引擎使用某种向量类,但是点和向量之间的区别非常重要,并且可以大大提高代码的可读性(例如,您计算的距离不是两个向量之间的距离,而是两个点之间的距离,这更自然)。
点
简单来说,它代表二维空间中的元素,其中x和y坐标定义了该点在该空间中的位置。

向量
向量是具有长度(或大小)和方向的几何对象。 在二维游戏中,矢量主要用于描述力(例如重力,空气阻力和风)和速度,以及禁止运动或光线如何反射物体。 向量有很多用途。

上面的函数创建新的二维向量和点。 在内部,在这种情况下,我们不会在JavaScript中使用new运算符来获得很多性能。 还要注意,有一些第三方库可用于操纵向量(glMatrix是一个很好的选择)。
以下是在上面定义的二维结构上使用的一些非常常见的功能。 首先,计算两点之间的距离:

向量的大小(长度)可以直接从上述函数的最后一行计算得出,如下所示:


向量长度
向量的归一化也非常方便。 下面的函数调整向量的大小,使其成为单位向量; 也就是说,其长度为1,但方向保持不变。


向量归一化
另一个有用的情况是有一个单位向量的方向从一个位置指向另一个位置:

点积是对两个向量(通常是单位向量)的运算,它返回表示这些向量的角度之间的关系的标量。


矢量点积
点积是投影在向量b上的向量a的长度。 返回值1表示两个向量指向相同的方向。 值-1表示向量a指向向量b的相反方向。 值为0表示向量a与向量b垂直。
这是一个实体类的示例,因此其他对象可以从该类继承。 仅描述与运动有关的基本属性。

您可以在游戏中使用像素或米作为单位。 我们鼓励您使用仪表,因为在开发过程中更容易平衡各种情况。 速度应为每秒米,加速度应为每秒米平方。
使用第三方物理引擎时,您只需在实体类中存储对物理实体(或一组实体)的引用。 然后,物理引擎为您在每个体内存储上述属性,例如位置和速度。
基本的Euler集成如下所示:

上面的代码必须在游戏中每个对象的每个帧中执行。 这是上述JavaScript的基本实现:

经过时间是自上一帧(自上次调用此方法以来)以来经过的时间(以秒为单位)。 对于以每秒60帧的速度运行的游戏, 经过的值通常为1/60秒,即0.016(6)s。
前面提到的有关增量时间的文章也涵盖了此问题。
要移动对象,可以更改其加速度或速度。 为此,应使用以下两个功能:

要将对象向右移动,可以执行以下操作:

请注意,设置为运动的对象保持运动 。 您需要执行某种减速来停止移动的对象(可能是空气阻力或摩擦力)。
武器效果
现在,我们将解释如何在HTML5游戏Skytte中产生某些武器效果。
等离子体

冲击波

射线

高射炮

高射武器子弹锥区
要在锥形区域中生成随机点:

random.uniform()函数返回两个值之间的随机浮点数。 一个简单的实现可能看起来像这样:

电子

程序曲线
查找并在其他两个点之间偏移一个点:

以下是上述代码中使用的函数:

寻找最近的邻居
为了找到最接近火箭和电动武器的敌人,我们遍历了一系列活动的敌人,并将它们的位置与火箭的位置进行比较,或者将射击点与电子武器的射击点进行比较。 当火箭锁定目标时,它会向目标飞行,直到撞到或飞离屏幕为止。 对于电子武器,它等待目标在范围内。
基本实现可能如下所示:

结论
这些主题仅涵盖支持它们的基本思想。 我们希望阅读本文后,您对如何开始开发此类东西有了更好的了解。 查看下面的资源,然后尝试自己做类似的事情。
资源:
游戏机制浏览器:各种游戏机制,算法和效果的具体示例集合。 所有示例均使用JavaScript编写。
集成基础:讨论实现一些基本的集成方法。
Amit的游戏编程信息:Amit Patel编写的书签列表,其中包含有关各种游戏编程模式和方法的大量信息。
Tuts + Game Development:游戏开发教程集
Gamedev:最大和最受欢迎的游戏开发门户和论坛。
gafferongames.com:Glenn Fiedler的游戏开发文章。
“什么是Sprite表?”:有关Sprite表及其工作方式的信息和视频。
“ 2D碰撞检测”:来自MDN的游戏开发页面。