跟我一起学ruby (转)

跟我一起学ruby 
By Tiger 
注:本教程转载自在游戏先行者论坛,版权属于作者Tiger。 
第一篇 
第二篇 

第一篇 
自序 
从今天起我就要开始学Ruby了。怎么样,没见吧?一个新人写教程。就凭我坚强的毅力,科学的自学方法,以及我的钻研精神,我有信心学通Ruby,而同样是新手的你也可以!由于本教程是菜鸟教莱鸟若有什么不对的地方还请前辈指教!如果没人看,就当我自愚自乐了。 
====================================================================== 
卷首语 
-------------------------------------------------------------------------- 
准备知识 
一、为什么要学Ruby? 
不用说一定是帮助发挥RM的潜力啦。而Ruby有多好多坏都与我无关,因为我学它只为了一个原因--RM! 
二、什么是Ruby? 
它是一种纯粹的面向对象编程的脚本语言。这就像C语言啦,就是一种电脑听得懂的语言,就好比你对电脑大叫一声“我要上网”它是不会让你上网的,必须通过一种语言来告诉它,Ruby就是其中之一,当然Ruby也要用打的,不是用说的... 
三、学Ruby要准备啥?当然是RM了,我还准备了三个东西: 
.笔记本--别看不起它,这可是重中之重,你的一些疑问与炅感、研究得出的结论都可记在上面. 
.一个新工程,我暂时把它命名为Test,它将用研究与实践. 
.另一个新工程,我暂时把它命名为标准,它的作用是万一你把自带的Ruby改得面目全非,有它可以做参照。当然RM的脚本数据是保存在 Data 文件夹内的 Scripts.rxdata 文件中的,你也可以对此文件进行备份。 
-------------------------------------------------------------------------- 
实践基础 
一、关于脚本脚本编辑器: 
.RM中,进入脚本脚本编辑器的方法是按F11或在主菜单「工具」菜单中选择「脚本编辑器」。。 
.脚本编辑器中一些快捷键(感谢carol3,这不是我发现的): 
tab:可以跳格、能够自动进行缩进 
ctrl + 鼠标滚轮 : 调整文字的大小 
ctrl + F:查找本页脚本 
ctrl + shift + F:查找所有脚本 
ctrl + H:替换 
ctrl + A:全选 
ctrl + C,ctrl + V:拷贝粘贴 
ctrl + Z,ctrl + Y:撤销与重做 
F3:和ctrl + F配套使用,"查找下一个" 
F4,F5:选择上一个/下一个脚本 
F6:把现在选的这一行命名为本脚本名 
ctrl + enter:保存并关闭本窗口 
二、创建程序的步骤: 
.确定程序的目标-比如你的目标是做一个求三角形面积的程序。 
.确定要使用什么样的方法-我知道S=1/2ah=1/2abSinC,求角度太烦,且后者不是单独的乘除运算,故吾选前者。 
.创建程序。 
三、编程中应养成的好习惯: 
.写注释。很多人认为写注释是在浪费时间——但别忘了——当你在写代码时,也许你的思路清楚;然而当程序逐渐变大,或当你面对几个月前写的代码时,注释的作用就显而易见了。 
在 Ruby 中,# 符号后面的一整行文字会认定为注释。当你要写大块的注释时, 也可以用 =begin 和 =end 的中间的一切为注释。 
注释是绿色的,不会执行,不会影响到程序的运作,只作为编写者标记的备忘记录来使用。 
未完成... 
四、编译错误的看法 
当你拼写、语法有错误了,程序就会停止运行,并告诉你相关的信息,此时再按F11进入脚本编辑器,就会看到光标放在了出错的那一行。 
如图: 
行:未初始化的常量“Persond” 
具体的方法我还没有总结。未完成... 
-------------------------------------------------------------------------- 
Type&Run 
(本来下文是不准备发的,但有人说本教程写的有些脱离RM,所以发了下文——不准备发的原因是我不知道carol3的“RGSS区置顶脚本整理中,目前收集脚本:30,望大家添加”一帖中竟然有教程!而且有一部分与我的几乎一样,算了,为了保证教程的完整性,我就把我写的发上来了...绝非抄袭!) 
让我们来入手Ruby: 
实践:标题画面的部分自定义 
实践目的: 
.学会Ruby的研究方法。 
.学会根据注释来做一些实验。 
.熟练脚本编辑器中一些快捷键的使用。 
打开脚本脚本编辑器 
.在脚本脚本编辑器的左边找到scene_title 
.可以在右边的筐架中看到第一行: 
#===================================================================== 
# Scene_Title 
#------------------------------------------------------------------------------ 
# 处理标题画面的类 
#===================================================================== 
我们知道这是注释,它的意思就是说scene_title这代码是用于处理标题画面的。同理,我们可以随便看看其它的组(组就是类似scene_title的在脚本脚本编辑器的左边的一窜一窜的代码),怎么样,它们的用途一目了然吧! 
.既然知道它是用于处理标题画面的,我们就拿它开刀吧! 
游览一下:读取数据库;生成系统对象;...这些都太深奥了在往下看—— 
s1 = " 新游戏" 
s2 = " 继续" 
s3 = " 退出" 
终于看到了熟悉的中国字了,呵!这不是RM中标题画面的选项吗! 
看看它上面的注释——生成命令窗口。果然是标题画面的选项。 
我们改了它试试: 
s1 = "新的轮回" 
s2 = "旧的回忆" 
s3 = "随风而逝" 
按ctrl + enter:保存并关闭本窗口。 
再按F12运行游戏。果然成功了! 
.人的野心总是无限的,我还想添加一个关于本游戏!好再试试: 
s1 = "新的轮回" 
s2 = "旧的回忆" 
s3 = "随风而逝" 
s4 = "关于本游戏" 
.贪得无厌总有一些心虚,再看看它下面的内容再运行游戏吧! 
@command_window = Window_Command.new(192, [s1, s2, s3]) 
@command_window.back_opacity = 160 
@command_window.x = 320 - @command_window.width / 2 
@command_window.y = 288 
有x、y大盖是在说选项的框框吧!糟了,多了一个选项,框框就一定要变长,如果不去修该框框的属性选项会出现选项无法显示出来的情况。管它呢!就算是真的我也无能为力... 
第一行有个(192, [s1, s2, s3])s1,s1,s3好象与s1 = "新的轮回"等中的s1,s1,s3说的是同一个东西吧?既然我加了s4,就得把s4也加进去: 
@command_window = Window_Command.new(192, [s1, s2, s3,s4]) 
s4;s3之间学它样也用 , 连接。 
.再运行游戏。果然出现了关于本游戏选项而且框框也能自动调整把四个选项纳入其中。可见我们刚才的猜测是错的,有x、y大盖是在说框框 
的位置? 
由图可知:红色框中的星星与框框上端的相对位置在修改前后没有变过,而蓝框中框框下端与RPG字符的相对位置的相对位置发生了变化,也就是说,框框上端的位置是不变的,当有新的选项时,自动延伸框框的下端。而有x、y大盖是在说选项的框框的上端的位置? 
.再试试: 


s1 = "新的轮回" 
s2 = "旧的回忆" 
s3 = "随风而逝" 
s4 = "关于本游戏" 
s5 = "asd" 
s6 = "sdasd" 
s7 = "weqw" 
@command_window = Window_Command.new(192, [s1, s2, s3,s4,s5,s6,s7]) 


果然,有标题显示不出了。 
.再看看: 
s1 = "新的轮回" 
s2 = "旧的回忆" 
s3 = "随风而逝" 
s4 = "关于本游戏" 
@command_window = Window_Command.new(192, [s1, s2, s3,s4,s5]) 
这会出错。 
s1 = "新的轮回" 
s2 = "旧的回忆" 
s3 = "随风而逝" 
s4 = "关于本游戏" 
@command_window = Window_Command.new(192, [s1, s2, s3]) 
关于本游戏将不会被显示。 
.现在的关于本游戏还无用处。我们可以参照"新的轮回""旧的回忆""随风而逝"来给它功能。凡是它们有的我都给关于本游戏加上。往下看,注意到有: 
def update 
@command_window.update 
# 按下 C 键时 
if Input.trigger?(Input::C) 
case @command_window.index 
when 0 # 新游戏 
command_new_game 
when 1 # 继续 
command_continue 
when 2 # 退出 
command_shutdown 
end 
end 
end 
when-当...时,这好象类似条件分歧的条件部分,注释告诉我这是选择新游戏;继续;退出不同命令的分歧。 
那么command_new_game;command_continue;command_shutdown就是动作了。他们会不会是Ruby中已经定义过的东西?如果是那么你为关于本游戏写其它的东西是没用的。那就让关于本游戏和退出共用一个东西吧: 


def update 
@command_window.update 
# 按下 C 键时 
if Input.trigger?(Input::C) 
case @command_window.index 
when 0 # 新游戏 
command_new_game 
when 1 # 继续 
command_continue 
when 2 # 退出 
command_shutdown 
when 3 
command_shutdown 
end 
end 
end 


运行之,果然是这样!按了关于本游戏就退出了。可见command_shutdown是用来调用退出命令的。那它会不会是Ruby中已经定义过的东西?我们再往下看: 

#-------------------------------------------------------------------------- 
# 命令:新游戏 
#-------------------------------------------------------------------------- 







#-------------------------------------------------------------------------- 
# 命令:继续 
#-------------------------------------------------------------------------- 







#-------------------------------------------------------------------------- 
# 命令:退出 
#-------------------------------------------------------------------------- 
这好象是在分类讨论。它们都以 def xxxxxxx开头,而xxxxxxx的内容就是前面分歧中各选项所对的内容了。可见那它不是Ruby中已经定义过的东西。那就为我们自定义留下了余地: 


def update 
@command_window.update 
# 按下 C 键时 
if Input.trigger?(Input::C) 
case @command_window.index 
when 0 # 新游戏 
command_new_game 
when 1 # 继续 
command_continue 
when 2 # 退出 
command_shutdown 
when 3 
abc 
end 
end 
end 


复制一下 命令:退出中的内容,并粘贴在退出后,把粘贴的内容中的 def command_shutdown改为def abc。运行之效果和前面一样。 
好了就我现在的实力,也只能进行到此了,如果懂一些语法,可以把def asd下面的内容改一改。 
-------------------------------------------------------------------------- 
总结 
未完成... 
-------------------------------------------------------------------------- 
作业 
.程序开发的步骤? 
.试着使用脚本编辑器中一些快捷键。 
提高题: 
试着总结脚本编辑器使用中出现的一些错误类型及其看法。 
未完成... 
------------------------------------------------------------------------------------------------------------------------- 
答案 
略 

第二篇 
第一章——类,对象和方法 
-------------------------------------------------------------------------- 
准备知识 
既然说Ruby是一种纯粹的面向对象编程的脚本语言,那么我就从对象开始学起。 
一、对象是什么? 
游戏中的任何东西都可以被可以解释为对象。 
钱的数目是对象,村长是对象,流氓甲也是象。因为Ruby所能处理的值都是对象,为了方便对象的操作就引进了类的概念。 
二、类是什么? 
对象的种类就称为类。 
村长和流氓甲属于NPC类,钱的数目属于自然数类(注:这里所说的类你可以自己定,你也可以说村长和流氓甲属于人类:属于哺乳类:属于...) 
一些特殊的属于这个类的对象叫作类的实体(或实例)。 
在日常生活中,我们对一切对象的分类都是有一定层次的。 
我们知道:生物〉动物〉哺乳类〉人类 
村长和流氓甲属于人类,它就一定有哺乳类的属性,也就一定有动物的属性。我们称生物是动物的父类,动物是生物子类,不难发现子类会继承父类的属性。当然也会遇到这样的情况:父类的某些属性不可以被某一特定的子类继承——虽然一般鸟类都会飞,但企鹅是鸟类中不会飞的一个子类。 
得到自然界这种规律的启发,Ruby就引进了继承。它大大减少了程序员的工作量,我们只需要定义一个父类(或叫做超类)的属性,它的子类就会自动继承它父类的属性。当然当你遇到像上文提及的那个企鹅特例还要新增或重定义子类和父类之间的区别。继承的意思,就是保持被继承者的性质但却同时拥有自己独有的特性。 
引进了类只是方便对象的操作,那么究竟怎么操作对象呢?那就要用方法了。 
三、方法是什么? 
方法是某个类中所有的对象专用的命令。 
你只需在某个对象上调用某个方法就可以让这个对象施行这个方法所代表的方法。而这个被操作的对象称为“作用实例”或是“方法的参数”。 
比如说你养了许多狗,(狗是一个类,被你养的狗是它的子类)有一个叫旺财(旺财是对象,也是实例),你每天训练他们坐下(这是在定义一个方法),之后每当你发号坐下这个命令时(这是在调用坐下这个方法)被你养的狗就会坐下。(你就通过方法完成了对对象的操作)。假如被你养的狗还分狼狗和哈巴狗二类,(狼狗和哈巴狗是被你养的狗的子类),它们会继承它父类中定义过的方法。当然一个类中可以定义许多方法(你可以教狗许多东西)。 
又比如说把Ruby看作CD机,CD机所操作的一切东西——CD就是所有的对象,类是歌曲的风格(如R&M是一类,Rap是另一类);当然你也可以把歌手当类的分法(如周杰伦是一类,陈奕迅是另一类),而调用方法就是按播放按钮,停止按钮,暂停按钮等。 
实践基础 
在Ruby中创造一个对象并对其进行操作的步骤如下: 
首先得定义类的属性—— 
一、类的定义 
格式: 
class 类名 
类中定义的内容 
end 
注意:类名必须以大写字母开头。 
如果是一个子类就这样写: 
class 子类名< 父类名 
类中定义的内容 
end 
或在定义后面直接写上: 
class 子类名 < 父类名 
end 
这只是让父类继承父类,不是重定义。为什么这么说呢? 
光有一个类还不行,接着再往里面塞方法,以便以后对对象的操作。 
二、方法的定义 
方法的定义写在“类中定义的内容”那里 
格式: 
def 
方法中定义的内容 
end 
注意:方法必须以小写字母开头。 
当然当你遇到像上文提及的那个企鹅特别的子类时,你还要重定义子类和父类之间的区别这叫称为重载,格式同上。方法的调用如反复定义,则以最后一次为准。 
在子类方法中调用父类相同方法的情况下,要使用关键词 super。super将调用被当前方法覆盖的父类中的同名方法。 
格式: 
super(定义的内容, ... ) 
若省略括号和参数时,将会把当前方法的参数原封不动地传递给父类中的同名方法。若调用时不想使用参数的话,请使用括号显式地标出,像super()这样。 
最后创造一个属于这个类的对象(实例)—— 
三、实例的创造 
格式: 
实例名 =类名.new 
实例终于创造好了,现在就该对它进行操作了。 
四、方法的调用 
在ruby里,我们通过点 . 来调用一个对象的方法 
格式: 
已创造的实例名.方法名 
如果你要创造一只临时存在的实例,并给其加上方法: 
(类名.new).方法名 
或: 
类名.new.方法名 


class NPC 
def intro 
print "我是NPC?" 
end 
end 
class Lioumang<NPC 
def talk 
print "XX在村子的南方" 
end 
end 
流氓甲=Lioumang.new 
流氓甲.talk #显示 我是NPC? 
流氓甲.intro #因为流氓甲继承了它的父类的方法,所以显示 XX在村子的南方 


说明: 
~5定义一个类——NPC 
~11定义一个NPC的子类——Lioumang 
~4为NPC定义一个名叫intro的方法,print " "的做用是显示“”内的东西。(先不要管它怎么运作的) 
~10为Lioumang定义一个名叫talk的方法 
创造实例——流氓甲 
为流氓甲调用talk的方法 
为流氓甲调用intro的方法 

二 


class NPC 
def intro 
print "aaa" 
end 
end 
class Lioumang<NPC 
def intro 
print "bbb" 
end 
end 
流氓甲=Lioumang.new 
流氓甲.intro 


说明: 
显示的是bbb,可见方法的调萌绶锤炊ㄒ澹�蛞宰詈笠淮挝�肌5�绻?3行变为 流氓甲=NPC.new 则显示aaa
三 


class NPC 
def intro 
print "aaa" 
end 
def talk 
print "ccc" 
end 
end 
class NPC 
def intro 
print "bbb" 
end 
end 
流氓甲=NPC.new 
流氓甲.intro 
流氓甲.talk 


说明: 
先显示的是bbb,再显示ccc,可见类如反复定义,则以保留他们交集的补集,他们的交集以最后一次为准。但如果13行变为 流氓甲=NPC.new 则显示aaa。 
四 


class NPC 
def talk(a=nil) #nil为空集 
p a 
end 
end 
class Lioumang < NPC 
def talk(a) 
super(5) # 以5作为参数进行调用 
super(a) # 以5作为参数进行调用 
super # 以5作为参数进行调用,super(a)的简写 
a = 1 
super # 以1作为参数进行调用,super(a)的简写 
super() # 无参数的调用 
end 
end 
Lioumang.new.talk 5 


说明: 
~4方法的作用是显示变量a,而a=nil,既显示nil 
可见:若省略Super的括号和参数时,将会把当前方法的参数原封不动地传递给父类中的同名方法。若调用时不想使用参数的话,请使用括号显式地标出,像super()这样。