欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

HTML5游戏开发进阶篇之单位智能移动实现教程

程序员文章站 2022-11-28 10:26:48
向被选中的单位下达命令,并使其执行该命令。将实现最基本的命令:使用自动寻径导航算法实现的单位智能移动。 7.1 命令单位 单击左键选中单位,通过单击右键给单位下达命令。 用右...

向被选中的单位下达命令,并使其执行该命令。将实现最基本的命令:使用自动寻径导航算法实现的单位智能移动。

7.1 命令单位

单击左键选中单位,通过单击右键给单位下达命令。

用右键单击地图上的一点,就会移动到这个点。

右键单击一个敌军单位或建筑会攻击该单位。

右键单击友方单位会命令选中的单位跟随并保护该友方单位。

选中采油车后用右键单击油田会命令采油车移动到油田上,并展开成炼油厂。

mouse中click()方法

7.2 发送和接收命令

game.sendCommand()

为每个item添加Orders属性

7.3 执行指令

为每个需要的单位实现processOrders(),并在游戏动画循环中为所有的单位调用该方法。

7.4 实现飞行器移动

aircraft.js中processOrders()方法

7.5 路径规划

Dijkstra算法及其变种A*算法是两种最常用的基于图论的寻径算法

A*算法额外使用一个启发式距离变量,因此,它比Dijkstra算法运行得更快,效率更高。

代码https://devpro.it/javascript_id_137.html中找到最新的代码和一个生动的例子。

7.6 定义寻径格网

创建二维数组网格game.currentMapTerrainGrid

每次添加或移除建筑或地形单位时,该数组都要被重新创建。

为每个建筑定义passableGrid属性,这样就可以允许建筑的某个部分可通行(比如,星港的下半部分)。

已经为A*算法定义好了移动格网

7.7 实现车辆移动

vehicles对象添加默认的processOrders()方法

值得注意的是,虽然车辆能够绕过不可通行的地形,但仍然会与其他车辆重叠在一起。

解决该问题的一个简单方案是,将所有车辆所在的网格标记为不可通行。然而,这个过于简单的方法可能导致地图上的大面积堵塞,因为车辆经常穿过多个网格。该方案的另一个缺点是,如果试图同时移动若干车辆穿过一处较窄的通道,第一辆通过的车就会阻塞通道,导致其后的车辆试图寻找另一条较远的路径,或者,在更坏的情况下,认为不存在可行的路径而放弃。

较好且可行的解决方案是,实现包含碰撞检查的导航,在车辆拥堵时改变车辆的移动方向,但仍然尽可能保存原有的路径。

7.8 碰撞检测和导航

与路径规划一样,导航是一个相当复杂的人工智能问题。参考论文Steering Behaviors for Autonomous Characters被认为是在游戏中开发导航机制的基础和起点。

游戏中导航的实现相当简单。首先,检查某行进中的车辆在其路径上是否会与其他车辆碰撞。如果是,那么为将要发生碰撞的车辆生成来自碰撞对象的斥力和较小的朝向原先行进方向的拉力。

接着,我们将这两个力向量相加来确定车辆接下来的方向以避开碰撞。车辆将一直向新的方向移动,直到不再检测到任何可能发生的碰撞,此时车辆再回到之前规划好的路径上。

基于将要发生碰撞的车辆间的距离来区分“硬撞击”和“软撞击”。即将发生“软撞击”的车辆会一边继续移动,一边调整方向,而即将发生“硬撞击”的车辆则会停止移动,原地转向。

vehicle对象实现默认的checkCollisionsObject()

7.9 将采油车展开为炼油厂

vehicle.js

7.10 流畅移动

使动画看上去更流畅的一个简单方法就是在动画循环之间对车辆的移动进行插值。计算距离上一次动画循环的时间,并创建一个插值量,该插值量用来决定单位在“动画循环间隔中的”绘制循环中的位置。这个小改动将使单位看上去以更高的帧频运动,即使动画循环实际上每秒才运行10次。

HTML5游戏开发进阶篇之单位智能移动实现教程