在开发自己的小版本Pong时,我开始挑选出所有游戏中以一种或另一种形式存在的游戏设计和开发作品。 以下是我到目前为止已经确定的部分和每个部分的实现(尽管很粗糙)的细分。
在开始学习之前,我想指出,在游戏设计和开发领域中有很多单词和缩写,作为程序员/终身游戏玩家,其中大多数都是显而易见的,对我来说很有意义。 如果有什么不合理的地方,请告诉我,我会尽力帮助解释。
游戏循环
我在Pong实施的每周更新中发布了此链接,作为有关什么是游戏循环的基础入门,但是我想再次强调它的重要性,并提供此链接作为更深入的用法和实现说明。 游戏循环对于您实施的任何游戏绝对至关重要。 如果您不熟悉循环,那么您将学到很多东西,应该在开始阅读本文之前先做一下。
如果您没有在每周更新中找到它,我会使用JavaScript来对游戏进行编程,因为与更流行的游戏编程语言相比,我有更多的使用经验。 另外,如果我的变量名对您来说很奇怪,那是因为多年来我一直在使用改良的匈牙利表示法,而且习惯很难打破。 无论如何,这是我的游戏循环:
首先,不要做我做的事。 是的,它可以工作,但是维护或重用并不容易。 您需要了解的这段代码是,我定义了一个我称为oGame的对象,并为其指定了成员fps,以定义游戏应以每秒运行的帧数。 换句话说,我已经设置了我希望此循环每秒运行一次并更新播放器在屏幕上看到的内容的次数。
在此循环中,您可以看到我正在计算球的位置以及AI球拍的位置。 另外,您可以看到我从使用CalculateAIPaddlePosition()的简单方法开始,并在后来的oGame.ball.update()的开发中开始切换到基于对象的方法。
更好的实现将更加通用。 类似于function(){for(所有实体){entity [i] .update(); 实体[i] .draw(); }。 我将开发一个较小的框架,该框架将具有更通用的版本,并在完成时进行深入解释。
实体
那么,我指的是那些实体? 好吧,一切。 玩家将以某种方式与之互动的所有事物都是某种实体。 它们都应该有一种初始化的方法,一种可以更新的方法,以及一种在屏幕上绘制它们的方法。 在Pong的情况下,我们有2个球拍,一个球,每个球员的得分,开始游戏菜单和游戏结束/重新开始菜单。 这些中的每一个都是一个实体,它们以不同的方式交互。
实体之间的交互将定义游戏玩法,到目前为止,我们实体之间的大多数交互以触摸的形式出现。 具体来说,如果球碰到了桨,我们将需要响应该事件。 这是我的处理方式:
此功能首先找到球与球员球拍的偏移量。 偏移量为我们提供了一个坐标,其顶部和左侧的值是元素距页面顶部和左侧的像素数。 这类似于我们在数学课上长大的x / y坐标平面。
在获取找出是否发生击球所需的信息之后,我们检查球的左侧是否小于球员球拍的宽度(换句话说:检查球的左侧是否在右侧)玩家球拍的一侧)。 如果是这样,我们知道该球在其水平区域内就可以命中,但是我们还没有完成。
接下来,我们检查一下球是否垂直位于桨叶的顶部和底部之间。 为此,我检查了球的顶部是否大于(垂直小于)或等于球拍的顶部,然后检查球的顶部小于(垂直大于)或等于球的底部。桨。 机敏的读者会注意到我刚才注意到的错误:最后检查应该是将球的底部与球拍的底部进行比较。 我们可以通过将“ oBallOffset.top <= oPaddleOffset.top + oPaddle.height”更改为“ oBallOffset.top + oGame.ball.diameter <= oPaddleOffset.top + oPaddle.height”来添加此功能。 否则,它的命中率将低于可能的命中率。 当然,检查越精确,添加到游戏中的难度就越大。
现在您可能会问:为什么将球的顶部与球拍的顶部进行比较,而不是检查圆上的一个点是否确实触碰了球拍? 像编程中的所有答案一样,答案是懒惰。 将圆视为正方形更容易,更快捷。 我创建了一个Hitbox(或边界框),我过去经常作弊,这使我的生活更轻松。 对于快速移动的物体,这非常好,因为互动发生得如此之快,以至于玩家最有可能永远不会注意到圆圈的左上部分实际上没有碰到桨。
输入项
好了,我们知道如何检查球是否击中了桨,但是当球员想要移动桨时,我们应该如何移动它呢? 答案是输入,幸运的是,在大多数编程语言中,这很容易处理。 这是我所做的:
我使用jQuery的keydown函数来检测何时按下了某个键,然后检查所按下的键是否是我期望的那个表示玩家想向上或向下移动的键。 在这种情况下,我选择了W键和S键分别表示向上和向下。 在每种情况下,我都为偏移创建了一个新的最高值,该最高值将桨叶移动了其速度值。 从那里开始,我检查以确保桨叶不会移动到页面顶部上方或页面底部下方。 从那里开始,只是为元素设置新的偏移量,并且一切都按计划进行。
人工智能
“好吧,”你说。 “但是AI桨呢? 那应该怎么工作?”好问题。 你会问一个金星。 由于这是我第一次尝试创建任何形式的AI,因此我发现这是最困难的部分。 将来我将不得不对其进行一些研究,但是现在这是我的处理方式:
就像使用paddle hit逻辑一样,我首先获取了解决该问题所需的信息。 我使用球的位置来确定桨是否需要向上或向下移动,并进行了相同的检查以确保其位于页面的顶部和底部。 在函数的结尾,我像以前一样更新了桨的位置,但是我希望您注意到最后一行。 我正在设置一个用来控制何时允许调用此函数的标志。 之前,在游戏循环中,您会注意到以下代码:
在这里,我正在检查是否应允许AI拨片移动,如果允许,然后告诉它等待一段随机的时间,然后再允许其移动。 我真正在做的是试图模仿另一个控制AI桨的人。 稍微随机的等待时间应该有点像人类的反应时间。 随机将其设置为有时太慢或太快,以便有时您可以击败它,而有时则是无与伦比的。
我认为,这是创建成功的竞争性AI的关键部分:您需要感觉自己可以击败它,但是您需要知道它也可以击败您。
ew。 我们完成了吗?
金田 Pong这样简单的例子就说明了游戏开发的其他部分,我们一定会介绍的,但是就目前而言,您应该有很多东西可以解决。
如果您有任何问题,意见或疑虑,请告诉我。 我很乐意回应任何事情。 如果您以前没有找到链接,则可以在这里玩游戏,代码在这里。