大多数战棋游戏都有予玩家在战斗开始前根据游戏的局势对作战单位的挑选以及位置部署的能力,本项目也是如此的。现在来看看在本项目中的单位出战功能与部署功能是如何实现的。
这是单位挑选场景的节点结构的折叠图(完整的节点树见文章末尾),有6部分:
(注:CR为custom_这个场景的缩写,没有实际意义)
(资料图片)
TitleCR:显示标题
UnitInfo: 显示Pointer指向的单位的信息。
InfoCR:显示如已出战人数等信息
UnitList:单位的列表,用来显示单位的图像与名字等缩略信息,该节点下面有一个TempUnitItem的单位模板
Items:显示功能选项,如“出击”和”观察“选项在这个节点下
Pointer:一个用来显示现在选中的项的框
属性:
start:这个方法用于启动并接受一个单位数组来设置这个场景。该方法由上一节介绍的Scene调用,单位数组就是由Scene的create_units方法提供的。
下面来是对于输入事件的处理
这里面做了两件事,一是在不同状态下的切换操作二是根据模式分配输入事件给不同的方法处理。
然后是对输入事件的一个拦截控制,因为在“观察模式”下,Scene的指针是需要接受得到输入事件来移动与查看场景信息的所以在“观察模式”不会拦截输入事件,而不是“观察模式”时,面板是显示的,不希望Scene的指针接受到输入事件来移动哦,所以需要用get_viewport().set_input_as_handled()方法来拦截输入事件阻止它继续传递。
_btn_list_move:处理Pointer在Items上的移动与点击,
在这个方法中,“出击”匹配项会发出了一个"depart_signal"信号,这个信号表示要开始进行战斗并代表玩家已经挑选好了出战的成员。这个信号在Scene节点进行连接:
可以看到这个游戏的开始由depart_signal这个信号决定的,这个lambda里面做了一些准备工作,例如关闭挑选界面的UI以及将我们挑选的这些单位的控制权交给玩家(其他没有挑选的单位都是没有控制权的)并将这些单位加入UnitManage来进行单位注册。
_unit_list_move:处理Pointer在单位列表上的移动与点击
可以看到这两个方法的逻辑与是大致相同的。
在发出"add_unit_signal"添加信号与"remove_unit_signal"删除信号时,都会由Scene节点的子节点Deploy处理。这个信号在Scene的_ready方法中进行连接:
Deploy:部署点,部署点是在挑选出战成员时可供单位部署的位置。
上一节有简要的概括。现在来详细看一下Deploy的使用方法。要使用Deploy需要先给它添加任意个有position属性的节点作为子节点。
它根据子节点来决定可选位的数量与位置。
在制作关卡时,只需要给它添加Sprite节点(其他的也可以)来决定部署点的位置。
不过目前部署点是在运行时决定的,如果需要多次使用Deploy与要在游戏过程中改变Deploy需要对这部分进行调整(后续应该会进行调整)。
Scene将PreparePlan的add_unit_signal与remove_unit_signal信号都交由Deploy进行处理,它们的实现很简单,就是遍历positions找到没有使用的位置就进行设置,或者找到要删除的unit就进行删除
在观察模式下进行单位位置的调整
上面在PreparePlan的_btn_list_move方法中有提到“观察模式”,在加入观察模式时,PreparePlan显示的节点将发生变化,它会隐藏部分面板,并且不再阻止输入事件的传递。这将允许玩家操作Scene的Pointer来操作部署点与查看敌方的棋子信息。
这时Scene将会根据Deploy的显示状态来将Pointer点击事件交给Deploy处理
deploy的pointer_callable方法会在没有选中unit时尝试进行选中,在已经选中unit时会尝试进行位置交换
这一系列的组合的效果:
在调整好位置后,就可以开始战斗了。
总结
PreparePlan决定出战单位,Deploy决定单位的位置。PreparePlan与Deploy之间没有直接联系,由Scene作为桥梁。这得益于Godot的信号机制。
在创建新关卡时,只需要给Deploy添加拥有位置属性的子节点即可。而最大出战人数则需要在PreparePlan的检查器中调整,需要勾选“子节点可编辑”选项。
下一节我们将介绍一下用于管理单位的UnitManage,看它是如何管理Unit的行动的。
致歉:因为项目的更新随时都有可能会破坏原有的代码,您在看到此文时它可能已经不是最新的了,请以现在项目的具体情况为准。欢迎大家给项目提Issues项目地址:/DH-DoveG/dh-srpg-demo
关键词: