魔塔吧 关注:66,149贴子:2,172,197

【教程】脱离魔塔样板的RM(XP/VX)魔塔制作教程

只看楼主收藏回复

一楼给百度。
这份教程不断更新,希望大家能多多捧场。如果制作的步骤成功完成了,或者制作中遇到了麻烦,请尽管在这里分享或者求助。如果我说的有什么错误或者疏漏,也欢迎提出来。


1楼2011-07-26 08:28回复
    补充一个地址,刚才和谐了。
    http://tieba.baidu.com/p/1137838789


    7楼2011-07-26 08:34
    回复
      南大鼓励呀?


      来自手机贴吧8楼2011-07-26 12:08
      回复
        我只希望这帖子的标题是【教程】C++魔塔制作教程


        9楼2011-07-26 12:14
        回复
          C++技术比较复杂,我自己的技术也没有达到这个,而且得从更基础的地方开始写(和魔塔的范畴不是很大了)。如果有兴趣可以去参考下《游戏编程入门》。


          11楼2011-07-26 12:17
          回复

            接下来,我们就要踏上魔塔制作的行列了。无论大家准备的是RMXP还是RMVX,都没关系。首先新建一个工程,我们就将在这个空白的工程上进行属于自己的魔塔之旅。
            这时,制作的问题一下子就出现了:“我们应该怎么把一个RM默认工程改造成魔塔的系统呢?要改哪里的脚本吗?”
            不是这样,一开始还有更重要的问题要去考虑。那就是,RM默认工程离一个魔塔的系统,还有多大距离。找到了距离,才有了努力的方向。
            这是一个找不同的游戏,问题就是:RM默认的工程和魔塔样板,在系统方面有什么不同呢?
            最重要的不同,就在于魔塔的战斗方式。当我第一次接触RM时(当时我还没有接触魔塔样板),就在想,RM真是太适合制作魔塔了,因为RM走路是一格一格的,魔塔也是。当时我尝试用RM制作魔塔,结果在制作战斗的时候就失败了。RM中角色攻击敌人,伤害总有那么一点浮动,但是魔塔里战斗的伤害是可以用怪物手册来查的,也就是伤害全都固定。这个该怎么做呢?当时我想了很久,最后以失败告终。当看到魔塔2006完全忽略了战斗过程,直接一碰怪物战斗就结束,我才发现自己被坑了。
            魔塔要不要战斗过程,怎么用战斗过程才是好的,这个暂时先不论。不管你的魔塔采用打算慢速战斗还是快速战斗,伤害计算总是要的,否则怪物手册就不知道写什么好了。现在,大家可以考虑一下伤害计算的过程了。
            伤害计算的过程其实很简单,可以分成三个大部分。一是获取角色和敌人的各项能力,二是根据这些能力来计算伤害是多少,三是把伤害输出来告诉玩家。你可能会说,这么说是废话,和大象装到冰箱里那个笑话似的,中间的计算步骤还是没说。其实,代码最短的部分反而是中间的计算。魔塔样板的伤害计算,大多数代码都花在了根据敌人的不同属性来调整能力上。我们暂时从最简单的战斗做起,不考虑属性,甚至魔防都先不要考虑。
            进入主题,下面我们就来写一个能计算伤害的脚本。请大家大胆地点击“脚本编辑器”按钮,即使之前从来没点过这个按钮也不用怕。然后,把左边脚本列表往下拉,直到看到最后一个Main。点击Main,然后按键盘上的Insert键,你会看到脚本编辑器多出了一个新的脚本位置,而且里面一片空白。这也没什么可怕,慢慢地我们就能把这片空白填满了。脚本很少是一次写成一大段的,一般都是从最简单开始慢慢增加,最后不知不觉就能完成自己所需要的所有功能。
            这个时候,可以打开原来魔塔样板的脚本,■enemy property,我们就要达到一个这脚本的效果,来计算敌人的伤害。
            #==============================================================================
            # ■ Enemy_property
            #------------------------------------------------------------------------------
            #  确定怪物的属性及伤害等。
            #==============================================================================
            首先会看到这些绿色的字。脚本前面加了#号,是注释的意思,就是说执行的时候不会运行这些东西。真正脚本的开始是下面:
            class Enemy_property
            于是,你可以在自己那个空白的脚本上面加上:
            class JiSuanShangHai
            end
            如果没接触过脚本的,可能会问:魔塔样板用的是Enemy_property,为什么你会把它换掉呢?其实这是类的名字(不理解类没关系,只要理解成一个类是处理一件事情的一部分脚本就行了),我就直接写计算伤害的拼音了,以后使用这个类的时候,叫它的名字就可以了,不管是Enemy_property还是JiSuanShangHai都是一样。
            你可能还会问,为什么我这里多了个end呢?因为class是表示下面要写一个类,end表示这个类写完了,魔塔样板中计算伤害类的最后也是有end的。
            接着我们来细化刚才写的类。
            class JiSuanShangHai
            def initialize
            end
            end
            initialize是类生成实例的时候自动调用的方法。这是什么意思呢?你写在编辑器中的类就相当于一个模具,你可以用它制造很多很多产品,一般模具是不会用来使用的,制造出的产品才会使用(当然也有例外)。这些产品就是实例。你可以设置成每个产品都是功能齐全,使用的时候直接用一个产品就可以搞定所有事情,也可以在模具上设置一些小开关,让它生产出的产品有一些微小的差别,需要什么功能就创造出什么样的产品。放到现在我们的伤害计算上,就是每次生成产品的时候只生成用来计算一个敌人伤害的产品呢,还是第一次产生完一个产品,以后有什么事情都用这个产品来处理。


            12楼2011-07-26 14:57
            回复
              ……只是尽力想尝试让有需求的制作者能实现自己的目标。很多时候制作遇到问题并不是技术难以提高了。另外如果有不准确或者错误的地方请提出什么的。


              14楼2011-07-26 15:30
              回复
                LZ是谁?不认识


                IP属地:江苏15楼2011-07-26 15:36
                回复
                  C++不复杂,画个线路图就可以了。


                  IP属地:江苏16楼2011-07-26 15:36
                  回复
                    继续啊啊啊啊啊啊啊


                    17楼2011-07-26 17:29
                    回复
                      辛苦了LZ


                      18楼2011-07-26 17:50
                      回复
                        LZ神隐,鉴定完毕


                        IP属地:浙江19楼2011-07-26 17:54
                        回复
                          你画地图呢啊~


                          IP属地:江苏20楼2011-07-26 18:12
                          回复
                            魔塔样板用的是前一种方法,可能原因是方便管理。于是我们就也用第一种方法进行。这样,在生成产品的时候,需要告诉它敌人的编号。于是我们就把initialize部分改成:
                            def initialize(enemy_id)
                            end
                            enemy_id就是我们输入的敌人编号,以后在计算的时候也会用到这个编号。当然如果你要换成其他的名字,比如eid,也是可以的,只要在后面涉及这个名字的时候全部统一就行了。
                            为什么还不切入主题呢?那么,我们就先把initialize放一下,去研究如何才能计算出敌人的伤害。在def initialize…end后面换一行,加上:
                            def cal_damage
                            end
                            cal_damage就是计算伤害的方法。说了这么多,可能会问:我从刚才的内容中只知道class里面要套def,那么def是什么意思呢?def是定义方法的关键词,也就是说,获得了类的实例产品后,它有哪些功能。它有了这些功能你才能用它去实现你的目的,比如计算。
                            现在我们可以把目光集中到def cal_damage … end的内部了。刚才说过,计算伤害有三个步骤。我们先从第一步获取能力开始。按照魔塔样板的惯例,也为了方便编辑,角色的能力我们就从默认角色的力量、灵巧等属性读取,敌人的能力就从数据库中敌人的各种信息读取。
                            在魔塔样板中,通常会看到这样一句话:
                            $game_actors[$game_variables[1]+1].hp/str/dex/……
                            $game_actors[n]就是代表第n号角色,后面.str等等表明了角色的哪一条信息。相信很多制作者已经对这方面有了解了。但是,初遇这个的制作者可能会问,下划线和点有什么区别呢?
                            下划线可以理解为连接符号,前面和后面属于一个整体,也就是说$game_actors是一个整体来看的。点表示访问属性或者方法,可以理解成从前面的对象中取出一个特定的属性或者特定的方法。为了方便理解,点读成“的”有的时候也能理解脚本的意思。比如
                            $game_actors[1].hp = 3 可以读成:游戏角色第一号的生命成为(变成或者赋予)3。至于前面的$符号,下面将会讲解到相关的内容。
                            为了方便大家参考,我们假定这部魔塔只有一个角色,如果掌握了以后制作多角色的也同样没问题。并且,假设游戏中用到的角色是1号(也就是默认的阿尔西斯)。那么我们的角色当然就是$game_actors[1]。同样,按照惯例,力量和灵巧分别代表角色的攻击和防御,那么就可以得到下面两行脚本:
                            actor_atk = $game_actors[1].str
                            actor_def = $game_actors[1].dex
                            actor_atk和actor_def是计算过程中会使用到的变量,每次写$XXXXXX总让人觉得有点麻烦,并且以后可能会添加敌人属性,比如让角色防御暂时下降50%一类,那么直接改$game_actors[1].dex,战斗后角色防御力就永远下降了,最后再加一条语句恢复倒是也行,不过总让人觉得很麻烦。
                            角色到这里应该没问题了,接下来是敌人。敌人的攻击防御肯定也是要了,并且敌人要加上生命。为什么不计算主角的生命呢?在计算的时候,我们就假设主角的生命是无穷多的,主角永远能够继续战斗下去,直到敌人被打败,经过计算得到一个总的伤害。如果事实上角色没有那么强,总的伤害已经超过角色的生命了,那么再去执行角色死亡游戏结束的事件。敌人从数据库中读取,假设敌人的ID是1号,那么下面需要的脚本就是:
                            enemy_hp = $data_enemies[1].hp
                            enemy_atk = $data_enemies[1].atk
                            enemy_def = $data_enemies[1].pdef
                            注意,这里用的属性是pdef,因为数据库中敌人除了pdef物理防御外还有魔法防御,而魔法防御是我么你用不上的。
                            但是,我们需要的敌人不一定是1号啊。魔塔中那么多敌人,如果像上面那样写,就永远只能获得1号敌人的能力了。怎么办,要把cal_damage后面也加个括号也加个enemy_id么?
                            没有那么麻烦。回到initialize上,现在initialize里面还是空白,一行代码也没有。于是,我们就加一行:
                            @enemy_id = enemy_id
                            可能你会说,为什么这里出现两个enemy_id了,不会出错么?另外那个@符号在这里使用是什么原因呢?
                            首先,@enemy_id和enemy_id是两个不同的东西。enemy_id是我们刚才通过initialize后面的括号传送进去的敌人编号,@enemy_id是刚刚第一次出现的变量。至于@符号,是说明下面那个变量是一个实例变量。F1帮助是这样说的:实变量可以在其类或子类的方法中引用。什么意思呢?就是整个类中,不管哪个def,都可以用到这个变量,如果没@,一个def中用完这个变量就抛弃了,更不能在另外一个def中用。所以说,要把initialize里面收到的敌人编号继续用在计算伤害的cal_damage,就得借助一个全局变量。这样下面的内容就好修改了,直接写成这样:
                            enemy_hp = $data_enemies[@enemy_id].hp
                            enemy_atk = $data_enemies[@enemy_id].atk
                            enemy_def = $data_enemies[@enemy_id].pdef
                            到现在,我们已经进入了伤害计算的大门。剩下的工作涉及到的新知识就不会很多了,如果大家已经对伤害计算有了思路,可以直接写出来,并且测试一下自己计算的结果对不对。


                            21楼2011-07-26 18:19
                            回复
                              于是上面的内容比较多,大家可以慢慢看下,打开自己的工程尝试尝试。因为内容较多,和一些其他原因,明天暂时不更新了……


                              22楼2011-07-26 18:21
                              回复