赞 | 342 |
VIP | 10 |
好人卡 | 8 |
积分 | 262 |
经验 | 235776 |
最后登录 | 2024-9-23 |
在线时间 | 2387 小时 |
Lv5.捕梦者 (版主) 遠航の猫咪
- 梦石
- 3
- 星屑
- 23186
- 在线时间
- 2387 小时
- 注册时间
- 2005-10-15
- 帖子
- 1166
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
第五章 幕后的黑手——解构RGSS
第一节 脚本编辑器
前面,我们已经完成了在事件中插入脚本以完成我们所需要的效果的方法。也许有的人要问,***效果怎么实现?假如,我想让战斗后多获得一倍的金钱,怎么实现?
可以说,大多数游离于RPG Maker XP默认系统运行方式之外的特殊效果,是要通过修改脚本才能够实现的。注意这里的修改,可不是像我们之前那样在事件里插一些脚本这么简单,这里的修改,需要我们进入游戏系统的背后,找到控制游戏进程的幕后黑手,对他做点手脚。
幕后的黑手在哪里?建立一个测试工程,然后按F11键,你看到了什么?
一个和数据库窗口大小有的一拼的——脚本编辑器。
脚本编辑器左边是一列选择框,这个就好比是数据库中“角色”左边的那一列选择,你点中某一项,右边那个文本框中的内容就会相应的发生变化——显示出一段段不同的Ruby程序来。好多啊!这些程序,连辍起来,就构成了控制RMXP游戏行为的中枢——RGSS(严格来说,还不完整,因为RGSS隐藏瞬糠执?朊挥邢允驹诮疟颈嗉?髦校??
习惯了事件脚本的小打小闹以后,一下子这样的信息大潮袭来,是不是有点透不过气的感觉呢?没关系,你只需要找到你要找的,修改你想改的,就可以了。问题是……在哪里?
要回答“在哪里”这个问题,我们就得从内部拆解RGSS这个庞大的东西。
第二节 类、对象、属性与方法
经过了第二、第三章的术语解释以后,这里我们不得不再用点术语来说明一些东西。
看一下脚本编辑器左边的列表,就像你的角色1号叫做“阿尔西斯”(你也可以让他叫做“啊你去死”)一样,这里的每一项都有自己的名字:Game_Temp, Game_System.....直到Main。这左边的每个项目,都对应着RGSS中一个“类”的定义。当然也有例外,有的“类”的定义实在是太长了,不得不分开来写,变成Game_Battler 1, Game_Battler 2等等……
那么“类”是什么呢?
我们是人类,所以“人”就是一个“类”。
猫属于哺乳动物类,所以“哺乳动物”就是一个“类”。
所以这个就很好理解,游戏中,所有的角色都是同一“类”,所有的NPC也都是同一“类”,所有的武器也都是一“类”,防具、道具等等都是“类”。
更有意思的是,那些具象或抽象的东西,也被定义成“类”,方便游戏处理,比如所有的战斗就是同一“类”,所有的窗口也都是同一“类”。
各种“类”之间是不一样的,比如在战场上,我方所有角色是一“类”,敌方的怪物和我方就不是同一个“类”了。
但是,就像自然界的不同“类”之间或许会有部分程度的相似,比如我是猫而bluefool是狗但我和他都是动物一样,Ruby中的“类”也允许这样的情况。在上面的例子中,我方和敌方虽然不是“同一类人”,但是我方的角色可以攻击,魔法,防守,敌方的怪物也可以这么做,在战斗场景内部,是没有差别的,于是RGSS给这种无差别的公共类起了个名字叫“超级类”,命名为“战斗者”——Game_Battler。
仅有“类”是不够的,就像别人问“SailCat是谁”你说“SailCat是猫”或“SailCat是女生”甚至“SailCat是66RPG的贵宾会员”提供不了他想要的信息量一样。除了“类”,我们还要有“对象”。否则你告诉游戏“阿尔西斯是角色”,游戏仍然对他的HP SP 攻防体魔等一无所知,这个游戏仍然转不起来。
这里的“对象”可不是诸如你的gg或者他的mm这样的“对象”,一个对象,就是一个“类”的实体化存在。
那么“对象”在脚本编辑器的哪里?哦,对象不在脚本编辑器里,它是在游戏过程中,由系统动态生成处理的。为什么?因为人是会动的,场景也是会变的啊,不然程序里都写死了你玩什么啊,真笨。
就像世界上有无数猫,无数狗,无数人,无数花草一样,“类”的实体化存在个数是没有限制的,所以理论上“对象”的数目也没有限制。当然,因为RMXP限制了我们只能创建999个角色999个敌人999个道具……所以你很难突破(不是不可以突破),但是这个只能算技术限制。概念上来说,一个“类”可以有无穷多个对象。
比如和2个NPC交谈后发生了一场战斗,我方出了4个人,敌方出了6个怪物,那么按RGSS理解,这里有2个Game_Event对象,1个Scene_Battle对象,4个Game_Actor对象,6个Game_Enemy对象以及10个Game_Battler对象。
那么属性是什么呢?属性就是一个对象区别于另外一个对象的特征。
阿尔西斯之所以成为阿尔西斯,因为他的名字是阿尔西斯,而不是克露塔,因为他的职业是剑士而不是法师,因为他会用十字斩而不是治疗。
对于一个角色来说,名字是属性,职业是属性,特技也是属性。
而方法又是什么呢?方法就是一个对象可以改变自己或别人属性的途径。
为什么你要让阿尔西斯加入队伍?因为他可以在战斗中砍杀怪物,他可以和NPC对话,他可以行走……
所以对于一个角色来说,打怪物,放魔法,行走,触发事件等都是方法。
不过由于Ruby语言的特性,属性和方法的区分(至少在语法上)不是很明显。但是你仍然可以按你自己的习惯去分开理解,这并不影响你编写程序实现功能的思路。
属性或者方法就是在脚本编辑器的右边了。我们可以看一下现在你能看到的东西:
class Game_Temp
attr_accessor :map_bgm
....
def initialize
....
end
end
不缩进的那个class....end,就是类的定义。右边的名字,就是你在左边项目里看到的名字,当然你可以改成不一样的(谁吃饱了没事改类名字……)。
attr_accessor就是一个属性,这个类还有好多好多属性。
def initialize.....end就是一个方法,这个类只有这一个方法。观察这个方法可以发现,它仅仅是改变自身各个属性的值而已。这种方法可以说是最简单的方法了,它只管自己,不管别人,而且由于它的特殊命名(initialize),它只会在对象被建立时,执行一次。
以上所有的这些东西怎么连辍起来成为RMXP的系统呢?
游戏中的每一件物事,大到一张地图,小到一块石头,大到整个系统,小到一帧动画,都是一个对象。
每个对象都有自己所属的类和自己的属性,这样阿尔西斯就不会变成克露塔,更不会变成幽灵,释放魔法也不会变成攻击敌人,更不会变成游戏结束。
每个对象都有自己的方法,这样阿尔西斯就能杀掉怪物,你就能完成NPC交的任务,Boss就能导致你Game Over。
明白了吗?我想你应该明白了。RGSS就是一个基于“对象”的处理程序脚本。
看了以上这段罗嗦以后,也许你心里只有一个问题。说了这么多,我也基本上搞清楚了RGSS的运作,那么,我能干吗?
第三节 我能做什么
我能做什么?
你能做什么?之前我们已经说过了,想要实现你的效果,就是——进入后台,找到中枢,对他下手。
所以你就是对RGSS下手。
也就是对里面的“类”、“对象”、“属性”和“方法”下手。
你可以修改、增加、删除(如果你有这个本事)游戏的类;
你可以修改、增加、删除游戏中的对象;
你可以修改、增加、删除对象的属性;
你可以修改、增加、删除对象的方法。
好了,一共3*4=12种,在脚本编辑器里你就只能干这12件事了,没别的了。但是这已经足够使你成为你游戏完完全全的真正主人了。
那么我怎么做?
第四节 更多金钱,更多欢乐
说了这么多,让我们来演练一下吧。我想让战斗后多获得一倍的金钱,怎么实现?
好的,首先,想要实现这个效果,你应该知道你所修改的东西,涉及到哪个类,哪个对象,哪个属性或者方法。
我想让*战斗后*多获得一倍的金钱,所以这个应该是战斗类——Scene_Battle,以及它的对象——全局场景对象$scene。
因为我方获得金钱,而不是敌方,更不是具体哪个角色或怪物,所以这个方法里会牵涉到Game_Party,以及它的对象$game_party。
因为获得金钱是在战斗结束后,所以这个方法肯定是战斗胜利后才会调用到。
因为获得的金钱是从敌人身上拿来的,所以这个方法里肯定会牵涉到Game_Enemy类以及对象$game_troop,而且会牵涉到这个怪物的“金钱”属性。
综合以上三点,我们定位到Scene_Battle 2的方法start_phase5上,这个方法全文如下:
#--------------------------------------------------------------------------
# ● 开始结束战斗回合
#--------------------------------------------------------------------------
def start_phase5
# 转移到回合 5
@phase = 5
# 演奏战斗结束 ME
$game_system.me_play($game_system.battle_end_me)
# 还原为战斗开始前的 BGM
$game_system.bgm_play($game_temp.map_bgm)
# 初始化 EXP、金钱、宝物
exp = 0
gold = 0
treasures = []
# 循环
for enemy in $game_troop.enemies
# 敌人不是隐藏状态的情况下
unless enemy.hidden
# 获得 EXP、增加金钱
exp += enemy.exp
gold += enemy.gold
# 出现宝物判定
if rand(100) < enemy.treasure_prob
if enemy.item_id > 0
treasures.push($data_items[enemy.item_id])
end
if enemy.weapon_id > 0
treasures.push($data_weapons[enemy.weapon_id])
end
if enemy.armor_id > 0
treasures.push($data_armors[enemy.armor_id])
end
end
end
end
# 限制宝物数为 6 个
treasures = treasures[0..5]
# 获得 EXP
for i in 0...$game_party.actors.size
actor = $game_party.actors
if actor.cant_get_exp? == false
last_level = actor.level
actor.exp += exp
if actor.level > last_level
@status_window.level_up(i)
end
end
end
# 获得金钱
$game_party.gain_gold(gold)
# 获得宝物
for item in treasures
case item
when RPG::Item
$game_party.gain_item(item.id, 1)
when RPG::Weapon
$game_party.gain_weapon(item.id, 1)
when RPG::Armor
$game_party.gain_armor(item.id, 1)
end
end
# 生成战斗结果窗口
@result_window = Window_BattleResult.new(exp, gold, treasures)
# 设置等待计数
@phase5_wait_count = 100
end
很容易找到,最有“嫌疑”的是这句话:gold += enemy.gold,以及$game_party.gain_gold(gold)。对于我们的要求来说,只要将金钱翻倍就可以了,因此可以改成。
gold += enemy.gold * 2
也可以改成
$game_party.gain_gold(gold * 2)
推荐前面一种改法,因为翻倍的结果会显示在战斗结果窗口中。
好了,修改一下,保存游戏,在数据库中进入战斗测试,打败敌人,你看看你是不是得到了2倍的金钱呢?
我们只是修改了一行RGSS,就实现了“战斗后获得金钱翻倍”的功能,多爽。
如果你要更复杂的效果怎么办呢?下一讲中,我们将实现一个更为复杂的效果,在讲解中告诉你,如何增加一个类的属性与方法。请看第六章:因为出众,所以不同。
本章范例工程:http://rpg.blue/upload_program/files/RubyTutorial5.zip
gpra8764:
[本贴由 叶舞枫 于 2007-6-15 18:20:37 进行了编辑] |
|