开发JavaScript游戏引擎-1

介绍,设计和第一步。

我最喜欢的游戏是《超级马里奥兄弟》,我仍然喜欢它。 我一直梦想着创造一个像这样的游戏。 也许这就是我现在从事软件开发业务的原因之一。

在本系列中,我将开发一个游戏引擎,该引擎可以扩展以开发任何游戏之王,但是我将以某种方式扩展它,以创建侧面滚动2d街机游戏,例如Mario。

设计
有大量的游戏引擎设计模式。 我将采用一种我认为很简单的设计,并且需要更少的样板代码。 这是组件-实体-系统设计模式。 实体是游戏中的物品,例如马里奥本人,敌人或硬币等。 另一方面,组件是实体的属性,例如其位置或。 组件和实体只是纯数据,将作为纯javascript对象保留在引擎中。 系统是一个纯函数,它接受当前游戏状态并计算下一个游戏状态。 就这样。

组件,实体,系统
首先,我们需要确定游戏状态的结构。 最初,由几个实体组成的数组就足够了。

  const initialGameState = [ 
{
位置:{x:0,y:0},
大小:{宽度:100,高度:100},
颜色:“黑色”
},{
位置:{x:100,y:100},
尺寸:{宽度:60,高度:60},
颜色为橙色'
}
]

这些是游戏中的实体。 也许是两个敌人。 您还可以看到位置大小颜色等组成部分。

图片中只剩下一个缺少的部分:系统。 为了能够可视化我们在做什么,从使用基本画布的简单渲染系统开始就有意义。

 函数rectangleRenderer(状态){ 
state.filter(e => e.size)
.forEach(drawRect)
}

过滤过程是系统的常见部分。 将来,我们将有多个系统处理游戏状态,并且某些系统可能仅处理某些类型的实体。 系统选择(过滤)要使用的实体。 对于矩形渲染器 ,实体必须具有大小组件才能在画布上绘制。 drawRect只是一个辅助函数,可在画布上绘制实体。

 函数drawRect(entity){ 
ctx.save()
ctx.translate(entity.position.x,entity.position.y)
ctx.fillStyle =颜色
“黑色”
ctx.fillRect(0,0,entity.size.width,entity.size.height)
ctx.restore()
}

如您所见,通过分离数据和逻辑,我们已经具有可组合且易于更改的结构。 例如,将来,如果您开发WebGL渲染器,您所需要做的就是用webGLRenderer系统替换长方体渲染器系统( function )。

主游戏循环
没有游戏循环,我们怎么能有一款有效的游戏? 初始游戏状态传递到主游戏循环。 主游戏循环按顺序将系统应用于状态并创建新的游戏状态。 然后,这个新的游戏状态再次传递给main方法。 这就是为什么将其称为游戏循环

函数main(state){ 
const newState =矩形渲染器(状态)
requestAnimationFrame(()=> main(newState))
}

现在我们已经包含了系统中的所有部分。 它看起来还不像马里奥。 但是有效。

在下一篇文章中,我们将深入研究老式2D轴对齐的边界框碰撞检测。 并享受一些街机物理的乐趣。

您可以在这里获取完整的源代码,https://github.com/yortuc/harras

在此之前,祝您黑客愉快!