northgard吧 关注:4,774贴子:10,452

编辑器简易教程

只看楼主收藏回复

RT,发一个编辑器的简易教程


IP属地:浙江1楼2023-02-12 01:25回复
    首先,说明一下编辑器的入口;
    如下图,在进入游戏以后的主界面,依次点击 创意 - 启动北加尔编辑器 即可启动编辑器


    IP属地:浙江2楼2023-02-12 01:27
    收起回复
      广告
      立即查看
      启动编辑器后,可以看到如下界面;
      其中有两个较为关键的文件,如图所示,分别为 api.xml 和 script.hx
      其中,api.xml 为游戏的接口文档,里面包含了一些游戏参数以及函数的使用方法以及说明;
      script.hx 则为脚本文件,在自定义游戏中想要触发某些效果,需要通过编辑该文件实现,如限定胜利条件等;
      鼠标左键双击文件名即可编辑文件;

      关于api文档,这里不做展开,有兴趣的同学可以结合翻译自行研究,本次教程主要对script.hx进行简要说明;


      IP属地:浙江3楼2023-02-12 01:35
      回复
        双击 script.hx 后,可以在编辑器的右侧栏中看到详细内容,如下图


        IP属地:浙江4楼2023-02-12 01:38
        回复
          接下来,则是认识脚本文件中的函数和变量的作用;
          首先解释一下示例中的 saveInt变量 以及 saveState() 函数;
          saveState() 会在存档时(不论自动还是主动)触发,作用是将变量保存在存档中,避免丢失;
          如下图示例,saveInt 在 saveState() 中被保存,而 localInt 则没有,如果进行了一次存档并重新读档的行为,
          saveInt的值会被保留,而localInt的值会丢失;


          IP属地:浙江5楼2023-02-12 01:47
          回复
            然后,解释一下 init()、onFirstLaunch()、onEachLaunch() 这三个函数;
            init() 会在每次开始游戏的时候被调用(新游戏或者读档);
            onFirstLaunch()仅会在游戏刚开局时被调用(新开的游戏);
            onEachLaunch()会在每次读档时被调用;
            有编程基础的同学,应该可以通过init()内的代码理解这一点


            IP属地:浙江6楼2023-02-12 01:52
            回复
              最后,解释一下regularUpdate()这个函数;
              根据注释可知,该方法在游戏中,每0.5秒会被调用一次


              IP属地:浙江7楼2023-02-12 01:55
              回复
                示例: 编辑胜利条件
                胜利条件一般整局游戏只需要设定一次,因此只需要在onFirstLaunch()这个函数中调用即可;
                因此,可以写一个限定胜利条件的函数;
                如下图,通过调用state.removeVictory()的方法,在本场游戏中移除相关的胜利条件;
                本次的示例方法中,保留了统治胜利,则在本场游戏中,仅能通过统治胜利条件赢得本场胜利;

                在完成这个限定胜利条件方法的编写后,再在onFirstLauch()中调用它即可;

                如此,便完成了限定胜利条件脚本的编写


                IP属地:浙江8楼2023-02-12 02:07
                收起回复
                  广告
                  立即查看
                  示例:给玩家添加增益效果
                  想要给人类玩家添加一些增益效果,如提高食物/木材/金钱/知识的产量,亦或是提高幸福度、增加战团数量,也可以写一个对应功能的函数,并在上述介绍的初始函数中调用;
                  每行代码的含义已在注释中标明;

                  随后,可同样在onFirstLaunch()中调用;
                  当然,也可以在onEachLaunch()和regularUpdate()中调用;
                  但是,并不确定增益效果是否可以重复叠加,有兴趣的同学可以尝试一下;


                  IP属地:浙江9楼2023-02-12 02:17
                  回复
                    示例:给AI添加增益效果
                    具体的实现可以参考上一个示例, 示例:给玩家添加增益效果
                    仅需要将判断是否是AI的条件取反(即在第二个红框中的 "human.isAI" 前加个 "!")
                    同样的,在初始函数中调用即可


                    IP属地:浙江10楼2023-02-12 02:21
                    收起回复
                      在上述几个示例后,如果有同学有兴趣自己设计一些函数,但又不知道对应功能的函数以及参数的作用时,则需要参考 api.xml;
                      同样通过左键双击的方式打开api.xml;
                      通过快捷键CTRL + F 唤出检索栏,即下图右上角红框中的内容;
                      通过在检索栏中输入字符可以快速搜索(快捷键F3是迅速选中下一条,Shift + F3是选中上一条);
                      以 示例:给玩家添加增益效果 中的addBonus()方法为例;
                      如图,检索栏中输入了"addBonus",可以看到第二个红框中的"addBonus"全部被高亮(棕褐色)显示;


                      IP属地:浙江11楼2023-02-12 02:29
                      回复
                        简要说明一下;
                        如下图,
                        一、白框表明 一个函数/参数 说明的起始和结束;
                        二、红框则表明这是一个 函数(方法) 还是 一个参数;(一般而言, "method"指方法,"null"指参数,ps:仅作参考)
                        三、黄框中的内容,仅会出现在方法中,表明这个方法的入参,即调用这个方法需要提供的参数;
                        以addBonus举例,addBonus需要一个类型为"BonusSave"的参数才能被成功调用;
                        一般而言,方法中出现了"Void",可以无视这个入参;ps:仅作参考
                        四、绿框(haxe_doc)中的内容则是对该方法/参数的说明;
                        如图中的内容,经过翻译可知,addBonus()方法是添加一个征服模式中的增益效果,且这个效果并不会在一局游戏中被永久保存,必须在每次开始游戏(读档)后被调用;


                        IP属地:浙江12楼2023-02-12 02:39
                        回复
                          那么,以addBonus()方法为例,尽管已知该方法需要一个名为"BonusSave"的参数才能被调用,那又怎么知道什么是"BonusSave"呢?
                          同样的,还是通过检索 api.xml,可以查到这个定义
                          有编程基础的同学应该知道 typedef 这个关键字是什么意思;
                          简言之,typedef 就是解释声明了 XX 的定义,比如,说明了 BonusSave 就是下图这么一个结构;
                          红框“<a>”则说明了这个定义中包含的属性,就是每一个绿框;
                          绿框中对每个属性进行了解释;
                          通过下图可以得知,BonusSave包含了unitId、resId、isAdvanced、id、buildingId这几个属性;


                          IP属地:浙江13楼2023-02-12 02:49
                          回复
                            再对其中两条属性进行举例说明:
                            以isAdvanced和id为例,可以发现这两条属性,一条包含了红框中的内容,一条没有包含;
                            红框中的内容表明的是这个参数是否是必须的,包含红框则说明这个参数可以不需要;

                            在了解了“BonusSave"的构成后,再重新看 示例:给玩家添加增益效果 中编写的方法,
                            可以发现id、resId、isAdvanced这三个属性,都是BonusSave中的,只需要在外层添加一层"{}"即可;
                            由于resId和isAdvanced都是非必须的;
                            addBonus()调用可以简化为addBonus({id: ConquestBonus.BResBonus})


                            IP属地:浙江14楼2023-02-12 02:57
                            回复
                              广告
                              立即查看
                              还是以addBonus()方法为例,现在已经知道了这个方法内的参数如何设定,那这个BonusSave中的id和resId的值又怎么确定呢?
                              可以通过下图的方式识别;
                              首先选中编辑器导航栏中的Database;

                              随后,选中View;

                              此时,编辑器的右侧栏会弹出新的内容;


                              IP属地:浙江15楼2023-02-12 03:03
                              回复