Project1
标题: [結帖]我開始學腳本啦~~求大神們指點~~ [打印本页]
作者: david_ng223    时间: 2014-2-1 09:30
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-1 09:54
module(英:模块)用来定义一个模块(废话) 每个module必须有一个end与之对应 恩 满足条件
模块名必须大写字母开头 没问题
module可以嵌套 你这里就是一个Zero模块嵌套Pokedex模块 没问题
#开头的就是注释 没问题
大写字母开头的一般是常量 用的很对 常量用=赋值 没问题 语法完全正确 新手长错的数组也用的很好
我唯一比较好奇的是 09、18、19行 既然说了是开关 为什么用的是真伪……好吧语法上没问题
另外在游戏中这段脚本的作用不会体现出来 因为你只是定义了而已
作者: david_ng223    时间: 2014-2-1 13:57
提示: 作者被禁止或删除 内容自动屏蔽
作者: taroxd    时间: 2014-2-1 14:08
 本帖最后由 taroxd 于 2014-2-1 14:40 编辑 
david_ng223 发表于 2014-2-1 13:57 
@余烬之中 
這段改自敌人图鉴 VA-核心脚本-第61-83行
應該是讀取數據庫-敵人(我改成主角)-註釋內的東西?? ...
以下[建议]可以让你的代码更加美观易读。
       [问题]就是代码有bug,需要修改
[建议]if语句在单行且不长的情况下使用这样的形式:把if用作修饰符。即 return $1 if ...
[??]关于你的注释,请参阅任意正则表达式教程。 楼下的介绍就不错。
[问题]30、38行中$1是字符串,需要转化成数值类型
[问题]29、37行的正则表达式无法读取浮点数
[建议]多行的block请使用do...end的形式
[建议]在不需要的时候不用显式地写上return
[建议]String#each_line 可以代替 split 那些东西。不过在这里的代码完全不需要分行处理。
[建议]给一个修改意见吧:
- def pokedex_height      #我想在數據庫-主角-註釋用[pkdh 7.4]之後在窗口顯示數值7.4(pokemon的身高) 
-   @note =~ /\[pkdh\s*(\d+(?:\.\d+)?)\]/ ? $1.to_f : 0.0 
- end 
- # 像这样,一行就可以解决的为什么要写这么长呢? 
- # 如果觉得很难理解,请参阅F1文档和正则表达式的教程 
- # 正则表达式看样子很可怕,其实是非常简单易用的,请务必学会 
- def pokedex_height      #我想在數據庫-主角-註釋用[pkdh 7.4]之後在窗口顯示數值7.4(pokemon的身高) 
 
-   @note =~ /\[pkdh\s*(\d+(?:\.\d+)?)\]/ ? $1.to_f : 0.0 
 
- end 
 
- # 像这样,一行就可以解决的为什么要写这么长呢? 
 
- # 如果觉得很难理解,请参阅F1文档和正则表达式的教程 
 
- # 正则表达式看样子很可怕,其实是非常简单易用的,请务必学会 
 
作者: 余烬之中    时间: 2014-2-1 14:22
david_ng223 发表于 2014-2-1 13:57 
@余烬之中 
這段改自敌人图鉴 VA-核心脚本-第61-83行
應該是讀取數據庫-敵人(我改成主角)-註釋內的東西?? ...
这些你需要了解一下正则表达式
直接解释的话 是这样:- line =~ /\[(?:pkdp) (\S+)\]/ 
- line =~ /\[(?:pkdp) (\S+)\]/ 
 
你应该知道 line是一个字符串(String类的实例)变量   字符串常量用英文半角双引号""括起来
而后面的/\[(?:pkdp) (\S+)\]/是一个正则表达式(Regexp类的实例)常量   正则式常量用一对斜杠//括起来
字符串 =~ 正则式
将正则式与字符串进行匹配,匹配的结果存储在全局变量$~、$&和$1、$2、$3....中
$~存储所有匹配信息 $&是匹配成功的字符串 $1之类(后位引用)是分别匹配成功的字符串
这里有点难懂 给几个例子
- "hello!" =~ /he/ 
- # $~.to_a    ["he"] 
- # $&            "he" 
- # $1            nil 
- "hello!" =~ /he/ 
 
- # $~.to_a    ["he"] 
 
- # $&            "he" 
 
- # $1            nil 
 
匹配成功 但未分群 所以无法后位引用 分群使用一对英文括号
- "Nice to meet you!" =~ /(nice).*(meet)/ 
- # $~.to_a   [] 
- # $&           nil 
- # $1           nil 
- "Nice to meet you!" =~ /(nice).*(meet)/ 
 
- # $~.to_a   [] 
 
- # $&           nil 
 
- # $1           nil 
 
匹配失败 分了群 但无匹配 大小敏感
- "Nice to meet you!" =~ /(nice).*(meet)/i 
- # $~.to_a   ["Nice to meet", "Nice", "meet"] 
- # $&           "Nice to meet" 
- # $1           "Nice" 
- # $2           "meet" 
- # $3           nil 
- "Nice to meet you!" =~ /(nice).*(meet)/i 
 
- # $~.to_a   ["Nice to meet", "Nice", "meet"] 
 
- # $&           "Nice to meet" 
 
- # $1           "Nice" 
 
- # $2           "meet" 
 
- # $3           nil 
 
匹配成功 且分了两个群 前面的存在$1 后面的$2 如果更多 以此类推
这一个能成功匹配 因为在正则式后面加了i 大小写不敏感
作者: david_ng223    时间: 2014-2-1 15:12
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-1 15:27
 本帖最后由 余烬之中 于 2014-2-1 16:47 编辑 
david_ng223 发表于 2014-2-1 15:12 
\s
匹配任意的空白符
点评累死了……
==================================================================编辑↓
你的错误在这句话没有错误
- @note =~ /\[pkdh\s*(\d+(?:\.\d+)?)\]/ ? $1.to_f : 0.0 
- @note =~ /\[pkdh\s*(\d+(?:\.\d+)?)\]/ ? $1.to_f : 0.0 
 
================ 补充:问号表示匹配一次或零次 如果所有数据强制要求0.0的形式不用问号 如果允许写整数就加上问号 ================
进行匹配
- "[pkdh 99.98]" =~ /\[pkdh\s*(\d+(?:\.\d+))\]/ 
- # $1  "99" 
- # $2  nil 
- "[pkdh 99.98]" =~ /\[pkdh\s*(\d+(?:\.\d+))\]/ 
 
- # $1  "99" 
 
- # $2  nil 
 
(感谢@taroxd 指出的Bug 这段解说↑有误 正确的如下)
- "[pkdh 99.98]" =~ /\[pkdh\s*(\d+(?:\.\d+))\]/ 
- # $1  "99.98" 
- # $2  nil 
- "[pkdh 99.98]" =~ /\[pkdh\s*(\d+(?:\.\d+))\]/ 
 
- # $1  "99.98" 
 
- # $2  nil 
 
==================================================================编辑↑
因为(?:)是 无后位引用功能的分群 不能被$2引用
你可以这样
- "[pkdh 99.98]" =~ /\[pkdh\s*(\d+)\.(\d+)\]/ 
- # $1  "99" 
- # $2  "98" 
- "[pkdh 99.98]" =~ /\[pkdh\s*(\d+)\.(\d+)\]/ 
 
- # $1  "99" 
 
- # $2  "98" 
 
- "[pkdh 99.98]" =~ /\[pkdh\s*(\d+\.\d+)\]/ 
- # $1  "99.98" 
- # $2  nil 
- "[pkdh 99.98]" =~ /\[pkdh\s*(\d+\.\d+)\]/ 
 
- # $1  "99.98" 
 
- # $2  nil 
 
- "[pkdh 99.98]" =~ /\[pkdh\s*(.+\..+)\]/ 
- # $1  "99.98" 
- # $2  nil 
- "[pkdh 99.98]" =~ /\[pkdh\s*(.+\..+)\]/ 
 
- # $1  "99.98" 
 
- # $2  nil 
 
所以 最后就是这样
- @note =~ /\[pkdh\s*(.+\..+)\]/ ? $1.to_f : 0.0 
- @note =~ /\[pkdh\s*(.+\..+)\]/ ? $1.to_f : 0.0 
 
作者: david_ng223    时间: 2014-2-1 16:09
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-1 16:24
david_ng223 发表于 2014-2-1 16:09 
分拆完應該是
@note =~ /       #這些不明白.......這個是a
a
这代表将字符串与正则式进行匹配 失败则返回nil 成功返回未匹配的字符个数
等价于- if 表达式1 
 
-    表达式2 
 
- else 
 
-    表达式3 
 
- end 
 
如果表达式1为false或者nil则条件伪 执行3 否则条件真 执行2
所以
如果匹配了 就使用匹配信息 否则就用默认值
b与c
(不带反斜杠的)括号表示分群 只有分群后才能后位引用
- "ruby 1.9" =~ /ruby\s*\d+\.\d+/ 
- # $&  "ruby 1.9" 
- # $1   nil 
-   
- "ruby 1.9" =~ /ruby\s*(\d+\.\d+)/ 
- # $&  "ruby 1.9" 
- # $1   "1.9" 
- "ruby 1.9" =~ /ruby\s*\d+\.\d+/ 
 
- # $&  "ruby 1.9" 
 
- # $1   nil 
 
-   
 
- "ruby 1.9" =~ /ruby\s*(\d+\.\d+)/ 
 
- # $&  "ruby 1.9" 
 
- # $1   "1.9" 
 
作者: taroxd    时间: 2014-2-1 16:30
 本帖最后由 taroxd 于 2014-2-1 16:31 编辑 
余烬之中 发表于 2014-2-1 15:27 
点评累死了……
你的错误在这里
1. 第二个问号不需要,那我打一个整数怎么办?我为什么一定要打小数?我就打 [pkdh 8]呢?
2.  "[pkdh 99.98]" =~ /\[pkdh\s*(\d+(?:\.\d+)?)\]/
# $1  "99.98"
# $2  nil
不测试不要瞎说,我在Ruby、RGSS上测试出来都是99.98
作者: taroxd    时间: 2014-2-1 16:35
余烬之中 发表于 2014-2-1 15:27 
点评累死了……
你的错误在这里
我的意思是你的表达式无法匹配 [pkdh 8]
/\[pkdh\s*(\d+(?:\.\d+)?)\]/ 没有任何问题,问号是必要的,$1引用的是整个数(可以是整数、可以是小数)
作者: taroxd    时间: 2014-2-1 16:49
 本帖最后由 taroxd 于 2014-2-1 17:00 编辑 
To LZ
连贴这么多不好意思,但是点评实在不舒服,而且写不下
/\[pkdh\s*(\d+(?:\.\d+)?)\]/ 你写小数(比如13.0)当然也是没问题的,效果和写13一样。最后 $1.to_f 终究是转成浮点数。
这样的话备注 [pkdh 13] 和 [pkdh 13.0] 是相同的效果,用这样的正则表达式具有更好的兼容性。
?: 倒是可有可无的,但是写上可以禁止后位引用,防止数错括号以及提高性能。
至于原因,请你自己解读一下这个正则表达式,我相信你可以解读出来的。
不懂或者忘了,可以参考F1文档,是有正则表达式的字典的
重要:请努力学习基本的ruby语法。 论坛里找本教程吧,应该不少呢。a ? b : c 和 =~ 算是很基本的符号的说。
To 余烬之中
说实话我不喜欢把 \d 写成 . ,并且喜欢在不出错的时候尽可能具有兼容性。所以我自己写的时候通常是大小写不敏感,如果要转成浮点数的话是小数与整数皆可读取的。
而且我自己写的时候不喜欢用[]、比较喜欢用<>,这样就不用斜杠转义了,这里就按照LZ的符号用了
这个是代码风格问题,请不要在意
作者: david_ng223    时间: 2014-2-1 17:16
提示: 作者被禁止或删除 内容自动屏蔽
作者: taroxd    时间: 2014-2-1 17:21
david_ng223 发表于 2014-2-1 17:16 
斜杠转义即是/\/的紅色符号??
是的話,那麼可以改成\么??
/\[pkdh\s*(\d+(?:\.\d+)?)\]/ 
- /<pkdh\s*(\d+(?:\.\d+)?)>/i 
- /<pkdh\s*(\d+(?:\.\d+)?)>/i 
 
/regexp/ 是表示两根斜杠中间是正则表达式
作者: david_ng223    时间: 2014-2-1 18:15
提示: 作者被禁止或删除 内容自动屏蔽
作者: david_ng223    时间: 2014-2-1 19:24
提示: 作者被禁止或删除 内容自动屏蔽
作者: taroxd    时间: 2014-2-1 20:22
 本帖最后由 taroxd 于 2014-2-1 20:43 编辑 
david_ng223 发表于 2014-2-1 19:24 
@余烬之中 @taroxd 
我剛吃完晚飯了,你們吃完沒XD
[建议]
36~38行可改为
- def pokedex_type_pokemon? 
-   @note =~ /<pkdtpkm>/i # 三目运算符是多余的。 
-   # 如果一定要返回true或false,可改为 /<pkdtpkm>/i === @note 或 !!(@note =~ /<pkdtpkm>/i) 或 !(@note !~ /<pkdtpkm>/i) 
- end 
- def pokedex_type_pokemon? 
 
-   @note =~ /<pkdtpkm>/i # 三目运算符是多余的。 
 
-   # 如果一定要返回true或false,可改为 /<pkdtpkm>/i === @note 或 !!(@note =~ /<pkdtpkm>/i) 或 !(@note !~ /<pkdtpkm>/i) 
 
- end 
 
[错误]
41行的正则表达式中没有后位引用,$1一定为nil
[建议]
注意 module Zero 的缩进。 RPG::Actor的缩进是正确的。
[建议]
注释方法可参考RGSS默认脚本,不建议用 #a #b ... 的方式。用上面定义常量的那种方式注释也可以。
[建议]
有弹出错误窗口的话请自己根据错误信息调试。
如果不跳错误窗口,但是达不到满意的效果的话,可以使用方法 p 或 msgbox 追踪,看看哪里没有得到预期的值
作者: david_ng223    时间: 2014-2-1 21:49
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-2 09:22
 本帖最后由 余烬之中 于 2014-2-2 09:23 编辑 
好吧 新手杀手alias 我还是举例子吧 先是super
一个父类- class Base 
-    def meet 
-       say "Hello!" 
-    end 
-    def say *args 
-       print *args 
-    end 
- end 
- class Base 
 
-    def meet 
 
-       say "Hello!" 
 
-    end 
 
-    def say *args 
 
-       print *args 
 
-    end 
 
- end 
 
一个子类- class Derive < Base 
-    def meet 
-       super 
-       say "How are you going?" 
-    end 
- end 
- class Derive < Base 
 
-    def meet 
 
-       super 
 
-       say "How are you going?" 
 
-    end 
 
- end 
 
父类的实例和子类的实例- b = Base.new 
- d = Derive.new 
-   
- b.meet #=> Hello! 
- d.meet #=> Hello!How are you going? 
- b = Base.new 
 
- d = Derive.new 
 
-   
 
- b.meet #=> Hello! 
 
- d.meet #=> Hello!How are you going? 
 
大概你已经能理解super了 现在是alias 既然上面有了一个Base类 我们就用它举例
分别考虑两种情况
===============================================不使用alias的情况
- class Base 
-    def say *args 
-       print "AAAAAAA" 
-    end 
- end 
-   
- Base.new.meet #=> "AAAAAAA" 
- class Base 
 
-    def say *args 
 
-       print "AAAAAAA" 
 
-    end 
 
- end 
 
-   
 
- Base.new.meet #=> "AAAAAAA" 
 
- class Base 
-    alias old_say say 
-    def say 
-       old_say 
-       print "AAAAAAA" 
-    end 
- end 
-   
- Base.new.meet #=> "Hello!AAAAAAA" 
- class Base 
 
-    alias old_say say 
 
-    def say 
 
-       old_say 
 
-       print "AAAAAAA" 
 
-    end 
 
- end 
 
-   
 
- Base.new.meet #=> "Hello!AAAAAAA" 
 
总结如下
1.已知方法a 如果之后再定义def a .... end 那么新的内容会覆盖旧的内容
2.alias可以保存某方法(不仅是方法)在某时刻的状态(理解用),相当于拍个照片,或者类比成保存一个副本
3.alias的语法为 【alias 副本名 原名】
4.之后可以在任何地方调用此副本 副本不随源的变化而变化
5.这种手段一般用于给方法新增内容 新的say其实已经覆盖了旧的say 但是old_say还在 可以被调用
6.新增内容时,优先采用alias追加定义
7.注意!如果出现了alias重名,常常出现“Stack Level Too Deep”错误,例子:- # 小A与小B都在写脚本 对已有的脚本进行修改 
- #已有脚本 
- class Player < Role 
-   def talk *args 
-      say *args 
-   end 
-   def say *args 
-     puts *args 
-   end 
- end 
-   
- #小A的脚本 
- class  Player 
-   alias old_talk talk 
-   def talk *args 
-     old_talk  
-     puts "小A" 
-   end 
- end 
-   
- #小B的脚本 
- class Player 
-   alias old_talk talk 
-   def talk *args 
-      old_talk 
-      puts "小B" 
-   end 
- end 
-   
- #运行 
- p = Player.new 
- p.talk "Hello!" 
- # Stack Level Too Deep 
- # 小A与小B都在写脚本 对已有的脚本进行修改 
 
- #已有脚本 
 
- class Player < Role 
 
-   def talk *args 
 
-      say *args 
 
-   end 
 
-   def say *args 
 
-     puts *args 
 
-   end 
 
- end 
 
-   
 
- #小A的脚本 
 
- class  Player 
 
-   alias old_talk talk 
 
-   def talk *args 
 
-     old_talk  
 
-     puts "小A" 
 
-   end 
 
- end 
 
-   
 
- #小B的脚本 
 
- class Player 
 
-   alias old_talk talk 
 
-   def talk *args 
 
-      old_talk 
 
-      puts "小B" 
 
-   end 
 
- end 
 
-   
 
- #运行 
 
- p = Player.new 
 
- p.talk "Hello!" 
 
- # Stack Level Too Deep 
 
但这样就没有错误- #小A的脚本 
- class  Player 
-   alias old_talk_of_A talk 
-   def talk *args 
-     old_talk_of_A   
-     puts "小A" 
-   end 
- end 
-   
- #小B的脚本 
- class Player 
-   alias old_talk_of_B talk 
-   def talk *args 
-      old_talk_of_B  
-      puts "小B" 
-   end 
- end 
-   
- #运行 
- p = Player.new 
- p.talk "Hello!" 
- #=> "Hello!小A小B" 
- #小A的脚本 
 
- class  Player 
 
-   alias old_talk_of_A talk 
 
-   def talk *args 
 
-     old_talk_of_A   
 
-     puts "小A" 
 
-   end 
 
- end 
 
-   
 
- #小B的脚本 
 
- class Player 
 
-   alias old_talk_of_B talk 
 
-   def talk *args 
 
-      old_talk_of_B  
 
-      puts "小B" 
 
-   end 
 
- end 
 
-   
 
- #运行 
 
- p = Player.new 
 
- p.talk "Hello!" 
 
- #=> "Hello!小A小B" 
 
常见的alias(别名)方式有几种要特别注意 常常与别人重复
·old_原名(say=>old_say)
·old_原名开头几个字母(initialize=>old_init)
推荐的别名方式
·当前脚本名略缩_方法(或方法略缩)
·当前脚本名略缩_方法(或方法略缩)_当前年月日
·自己英文名略缩_当前脚本名略缩_方法(或方法略缩)
·自己英文名略缩_当前脚本名略缩_方法(或方法略缩)_当前年月日
比如我常常这样
update=>mo_vtpb_upt
【另外提一点 alias一般有两种写法:
1.alias old_a a
2.alias :old_a :a
在这里这没什么区别 喜好问题 以后遇到alias_method时只能用后者】 
作者: taroxd    时间: 2014-2-2 09:31
顺便打个广告
http://rpg.blue/thread-347871-1-1.html
要在原方法后追加可以用这个
作者: david_ng223    时间: 2014-2-2 13:08
提示: 作者被禁止或删除 内容自动屏蔽
作者: taroxd    时间: 2014-2-2 14:56
 本帖最后由 taroxd 于 2014-2-2 15:04 编辑 
david_ng223 发表于 2014-2-2 13:08 
剛才看了2小時的Ruby使用手冊,
看完=沒看,沒有什么是我看得明白的......
看了一下你给的链接
那个根本不是教程,是使用手册。没学过看不懂是正常的。
这里有几本吧,自己选着看。
http://rpg.blue/thread-344661-1-1.html # 最后几页不用看懂
http://rpg.blue/thread-159895-1-1.html # 初级篇部分
http://rpg.blue/thread-200795-1-1.html
比较正规的Ruby教程 (不是我的网盘,不保证分享不会断)
至少学到第一部分前9章
任选一本学得差不多,就能大致理解脚本这货是怎么玩的了。Ruby算是挺容易上手的。
作者: david_ng223    时间: 2014-2-2 15:31
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-2 15:53
david_ng223 发表于 2014-2-2 15:31 
\t 输出一个制表符,自动对齐文本到Tab 值(一
般4)的整数倍处
执行下列程序段 其中\n是回车换行
- puts "==begin==\n\n=======" 
- puts "perform \\a\n\a\nend perform\n=======" 
- puts "perform \\x??\n\\x01=>\x01\n\\x02=>\x02\nend perform\n=======" 
- puts "perform \\t\nabcdT\tTefgh\nend perform\n=======" 
- puts "perform \\r\n\r\nend perform" 
- puts "=======\n\n==end==" 
- puts "==begin==\n\n=======" 
 
- puts "perform \\a\n\a\nend perform\n=======" 
 
- puts "perform \\x??\n\\x01=>\x01\n\\x02=>\x02\nend perform\n=======" 
 
- puts "perform \\t\nabcdT\tTefgh\nend perform\n=======" 
 
- puts "perform \\r\n\r\nend perform" 
 
- puts "=======\n\n==end==" 
 
其中\r在windows环境没必要了解
作者: david_ng223    时间: 2014-2-2 16:53
提示: 作者被禁止或删除 内容自动屏蔽
作者: david_ng223    时间: 2014-2-2 17:56
提示: 作者被禁止或删除 内容自动屏蔽
作者: david_ng223    时间: 2014-2-2 18:22
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-2 18:25
david_ng223 发表于 2014-2-2 17:56 
需要注意的是,Ruby 里面的除法和取余数和C 什
么的不一样,它是对   -無限(原本沒有"無限"這兩個字,是橫型 ...
print 输出对象 输出结果为字符串 如果对象不是字符串 转换为字符串再输出 调用的是to_s
假设有语句- print 1,"Hello",[3,4,"ok"],:symbol,Actor.new 
- print 1,"Hello",[3,4,"ok"],:symbol,Actor.new 
 
就相当于- print 1.to_s,"Hello".to_s, [3,4,"ok"].to_s,:symbol.to_s,Actor.new.to_s 
- print 1.to_s,"Hello".to_s, [3,4,"ok"].to_s,:symbol.to_s,Actor.new.to_s 
 
有个例外就是 当参数为nil时 输出"nil"
print的结果看不到双引号
puts 输出参数中的对象以及一个换行符,如果没有参数则输出一个换行符  如果参数是一个数组,那么数组中的元素会按照顺序进行输出,如果是一个数组和字符串以外类型的对象,函数会先用to_ary方法转换为数组,然后用to_s方法转换为字符串再进行输出,如果最终所得的是nil,那么它也会输出nil
假设有语句- puts 1,"Hello",[3,4,"ok"],:symbol,Actor.new 
- puts 1,"Hello",[3,4,"ok"],:symbol,Actor.new 
 
就相当于- print 1.to_s+"\n"+"Hello".to_s+"\n"+[3,4,"ok"].to_s+"\n"+:symbol.to_s+"\n"+Actor.new.to_s+"\n" 
- print 1.to_s+"\n"+"Hello".to_s+"\n"+[3,4,"ok"].to_s+"\n"+:symbol.to_s+"\n"+Actor.new.to_s+"\n" 
 
p 将参数以人类可读的形式输出 调用的是inspect
假设有语句- p 1,"Hello",[3,4,"ok"],:symbol,Actor.new 
- p 1,"Hello",[3,4,"ok"],:symbol,Actor.new 
 
就相当于- print 1.inspect+"\n"+"Hello".inspect+"\n"+[3,4,"ok"].inspect+"\n"+:symbol.inspect+"\n"+Actor.new.inspect+"\n" 
- print 1.inspect+"\n"+"Hello".inspect+"\n"+[3,4,"ok"].inspect+"\n"+:symbol.inspect+"\n"+Actor.new.inspect+"\n" 
 
作者: 余烬之中    时间: 2014-2-2 18:30
david_ng223 发表于 2014-2-2 18:22 
-7 % 3 = (7 / 3) * 3 - 7
-7 % 3 = 7 - 7
-7 % 3 = 0
上面因为点评长度限制我就简写了一下 实际是这样
-7 = int(-7/3) * 3 + -7 % 3 #这是理解用的 其中的int(X)意为向负无穷取整
现在是比较严格的写法
-7 % 3 = - ( int(-7/3) * 3 ) - 7
-7 % 3 = - ( -3 * 3 ) - 7
-7 % 3 = - ( -9 ) - 7
-7 % 3 = 9 -7
-7 % 3 = 2
作者: david_ng223    时间: 2014-2-2 18:57
提示: 作者被禁止或删除 内容自动屏蔽
作者: taroxd    时间: 2014-2-2 19:15
 本帖最后由 taroxd 于 2014-2-2 20:56 编辑 
david_ng223 发表于 2014-2-2 18:57 
实践:Hello world!          明白了
关于msgbox函数             明白了
字串                            ...
抱歉才看到
----------------------------------------------------------
关于 / 与 %
简单地说,/ 向负无穷取整,% 结果的正负号和除数相同
 
上表可以参考。注:modulo是%的别名
另外提一句,负无穷作为一个常量在Ruby中是存在的。不过你还是不用知道了。
----------------------------------------------------------
关于常量,你一楼写得那堆东西就叫常量。
使用常量可以让你要修改的时候方便许多。
一是方便查找,二是不需要改动已经写好的代码。
你需要知道常量的作用域,知道 Zero::Pokedex::POKEDEX_TYPE 是怎么回事(这个词见你的1L)
-----------------------------------------------------------
关于print、p和puts
简单地说,print和puts给使用者看,p给程序员调试看。在RGSS中,其中的区别不重要,反正玩游戏的人看不到输出=。=
所以在RGSS中,这三个方法都是供你自己调试程序用的。一般用p
------------------------------------------------------------
关于比较运算
不用深究,暂时按照符号本身的意思理解就好。但是记得 == 千万不能写成 =
------------------------------------------------------------
作为一个综合以上内容的小练习,你可以试试已知一天内的第x秒(如x=10000秒),利用/和%把它拆成当天时间:a小时b分钟c秒(如2小时46分40秒)
然后输出 “a:b:c” (如02:46:40)  如果数字只有一位的话在前方补0(如前面小时数为2,则补为02)
代码越简单越好,写完用下面的代码测试。
- loop do 
-   t = Time.now 
-   x = t.hour * 3600 + t.min * 60 + t.sec 
-   # 在这里填上你的代码。x已经代入了当前的秒数 
-   # 然后把代码放在脚本编辑器的Main之前 
-   # 如果代码正确的话,应该能看到控制台中不断输出当前时间 
-   # 注意把焦点放在游戏窗口上 
-   # 测试完了别忘把这段代码删掉 
-   Graphics.wait(60) 
- end 
- loop do 
 
-   t = Time.now 
 
-   x = t.hour * 3600 + t.min * 60 + t.sec 
 
-   # 在这里填上你的代码。x已经代入了当前的秒数 
 
-   # 然后把代码放在脚本编辑器的Main之前 
 
-   # 如果代码正确的话,应该能看到控制台中不断输出当前时间 
 
-   # 注意把焦点放在游戏窗口上 
 
-   # 测试完了别忘把这段代码删掉 
 
-   Graphics.wait(60) 
 
- end 
 
提示:可以用 < 10 来判断是否要补0。
注:有比较高级的方法,参见 Game_System#playtime_s 。暂时不需要掌握。
--------------------------------------------------------------
参考:
- h = x / 60 / 60 
- m = x / 60 % 60 
- s = x % 60 
-   
- h = h < 10 ? "0#{h}" : h.to_s 
- m = m < 10 ? "0#{m}" : m.to_s 
- s = s < 10 ? "0#{s}" : s.to_s 
-   
- p "#{h}:#{m}:#{s}" 
-   
- # 下面的两种方法现在不能理解没有关系 
- # p [h, m, s].collect {|num| num < 10 ? "0#{num}" : num.to_s }.join(':') 
- # p sprintf("%02d:%02d:%02d", h, m, s) 
- h = x / 60 / 60 
 
- m = x / 60 % 60 
 
- s = x % 60 
 
-   
 
- h = h < 10 ? "0#{h}" : h.to_s 
 
- m = m < 10 ? "0#{m}" : m.to_s 
 
- s = s < 10 ? "0#{s}" : s.to_s 
 
-   
 
- p "#{h}:#{m}:#{s}" 
 
-   
 
- # 下面的两种方法现在不能理解没有关系 
 
- # p [h, m, s].collect {|num| num < 10 ? "0#{num}" : num.to_s }.join(':') 
 
- # p sprintf("%02d:%02d:%02d", h, m, s) 
 
作者: david_ng223    时间: 2014-2-2 20:25
提示: 作者被禁止或删除 内容自动屏蔽
作者: david_ng223    时间: 2014-2-2 20:55
提示: 作者被禁止或删除 内容自动屏蔽
作者: taroxd    时间: 2014-2-2 21:04
 本帖最后由 taroxd 于 2014-2-2 21:30 编辑 
david_ng223 发表于 2014-2-2 20:55 
@taroxd
条件语句的正确缩进,以及各种用法
- if some_condition # 这里加 then 是不好的 
-   do_something_if_some_condition 
- elsif another_condition 
-   do_something_if_another_condition 
- else 
-   do_something_else 
- end 
-   
- # unless...else...end 是不好的 
-   
- do_something if some_condition 
- some_condition and do_something  # 这句话句意和上面一句相同,暂时可以不用理解。 
- # if some_condition then do_something end 是不好的 
- # unless !some_condition 是不好的 
-   
- do_something_else unless some_condition  # do_something if !some_condition 是不好的 
- some_condition or do_something_else # 这句话句意和上面一句相同,暂时可以不用理解。 
- # unless condition1 && condition2 是不好的 
-   
- some_condition ? do_something : do_something_else 
- # if some_condition then do_something else do_something_else end 是不好的 
-   
- case expression 
- when condition1 then do1 
- when condition2 # 这里加 then 是不好的 
-   do2_line1 
-   do2_line2 
- # when condition3: do3 #这样写是不好的,并且在Ruby后期版本已经不支持。请务必不要用这样的写法。 
- else do_else # do_else 内容较长时建议换行 
- end 
- # 判断条件成立是用 condition === expression 
-   
- # 以上“是不好的”仅仅是不建议这么写,写了也不会有任何问题。 
- # 但事实上,以上不建议的写法在默认脚本中一次都没有出现过。 
- if some_condition # 这里加 then 是不好的 
 
-   do_something_if_some_condition 
 
- elsif another_condition 
 
-   do_something_if_another_condition 
 
- else 
 
-   do_something_else 
 
- end 
 
-   
 
- # unless...else...end 是不好的 
 
-   
 
- do_something if some_condition 
 
- some_condition and do_something  # 这句话句意和上面一句相同,暂时可以不用理解。 
 
- # if some_condition then do_something end 是不好的 
 
- # unless !some_condition 是不好的 
 
-   
 
- do_something_else unless some_condition  # do_something if !some_condition 是不好的 
 
- some_condition or do_something_else # 这句话句意和上面一句相同,暂时可以不用理解。 
 
- # unless condition1 && condition2 是不好的 
 
-   
 
- some_condition ? do_something : do_something_else 
 
- # if some_condition then do_something else do_something_else end 是不好的 
 
-   
 
- case expression 
 
- when condition1 then do1 
 
- when condition2 # 这里加 then 是不好的 
 
-   do2_line1 
 
-   do2_line2 
 
- # when condition3: do3 #这样写是不好的,并且在Ruby后期版本已经不支持。请务必不要用这样的写法。 
 
- else do_else # do_else 内容较长时建议换行 
 
- end 
 
- # 判断条件成立是用 condition === expression 
 
-   
 
- # 以上“是不好的”仅仅是不建议这么写,写了也不会有任何问题。 
 
- # 但事实上,以上不建议的写法在默认脚本中一次都没有出现过。 
 
作者: david_ng223    时间: 2014-2-2 23:53
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-3 08:37
 本帖最后由 余烬之中 于 2014-2-3 20:44 编辑 
david_ng223 发表于 2014-2-2 23:53 
A_B_C和B_C_D是标识符
a和b是變量
兩者都是輸出234,即是兩者沒有分別??
首先 【标识符】并不是常量专属的名称 凡是任何用于指代某对象 由使用者自定义的字符序列都是标识符
比如  local_var = 3   其中local_var就是标识符   @ins_var = 0   @ins_var是    $glo_var = 9    $glo_var是   CON = "Hi"   CON是   甚至【module AMOD】AMOD也是    【class CLS】CLS也是
常量和变量都可以提前操作 至于这句话:说的是不能动态的改变
看两个例子
=======================================================- CON = 100 
- p CON 
- #=>100 
- CON += 50 
- #warning: already initialized constant CON 
- p CON 
- #=>150 
- another_var = CON 
- p another_var #=> 150 
- CON = 100 
 
- p CON 
 
- #=>100 
 
- CON += 50 
 
- #warning: already initialized constant CON 
 
- p CON 
 
- #=>150 
 
- another_var = CON 
 
- p another_var #=> 150 
 
现在加上这样一段- def met 
-   CON += 3 
-   p CON 
- end #SyntaxError:dynamic constant assignment 
-   
- met 
- def met 
 
-   CON += 3 
 
-   p CON 
 
- end #SyntaxError:dynamic constant assignment 
 
-   
 
- met 
 
=======================================================
=======================================================- loc = 100 
- p loc 
- #=>100 
- loc += 50 
- p loc 
- #=>150 
- another_var = loc 
- p another_var #=> 150 
-   
- def met 
-   loc += 3 
-   p loc 
- end 
-   
- met 
- #undefined method '+' for nil:NilClass 
- loc = 100 
 
- p loc 
 
- #=>100 
 
- loc += 50 
 
- p loc 
 
- #=>150 
 
- another_var = loc 
 
- p another_var #=> 150 
 
-   
 
- def met 
 
-   loc += 3 
 
-   p loc 
 
- end 
 
-   
 
- met 
 
- #undefined method '+' for nil:NilClass 
 
而且这里也没有出现警报
我们换成实例变量试试
- [url=home.php?mod=space&uid=77065]@ins[/url] = 100 # 坑人神句 下面不加井号之间的就是这样的结果 
- @ins#-=-=-=-=-=-=-=-=-=-=-=-=# = 100  #←把井号及之间的删掉 
- p @ins 
- #=>100 
- @ins#-=-=-=-=-=-=-=-=-=-=-=-=# += 50  #←把井号及之间的删掉 
- p @ins 
- #=>150 
- another_var = @ins 
- p another_var #=> 150 
-   
- def met 
-   [url=home.php?mod=space&uid=77065]@ins[/url] += 3 
-   p @ins 
- end 
-   
- met 
- #=>153 
- [url=home.php?mod=space&uid=77065]@ins[/url] = 100 # 坑人神句 下面不加井号之间的就是这样的结果 
 
- @ins#-=-=-=-=-=-=-=-=-=-=-=-=# = 100  #←把井号及之间的删掉 
 
- p @ins 
 
- #=>100 
 
- @ins#-=-=-=-=-=-=-=-=-=-=-=-=# += 50  #←把井号及之间的删掉 
 
- p @ins 
 
- #=>150 
 
- another_var = @ins 
 
- p another_var #=> 150 
 
-   
 
- def met 
 
-   [url=home.php?mod=space&uid=77065]@ins[/url] += 3 
 
-   p @ins 
 
- end 
 
-   
 
- met 
 
- #=>153 
 
全局变量 类变量等结果一样 不过你暂时不用去管 记得是变量就行了
=======================================================
总结就是 常量的值不能被动态改变(方法中) 连语法都不允许 如果在方法外重新赋值 会出现警报 但是赋值本身还是成功的
变量的值能够被动态改变 只要方法能够获得该变量 就允许对他进行操作     
作者: david_ng223    时间: 2014-2-4 14:53
提示: 作者被禁止或删除 内容自动屏蔽
作者: taroxd    时间: 2014-2-4 14:58
 本帖最后由 taroxd 于 2014-2-4 15:11 编辑 
任何一个方法都有一个返回值。若没有显式指定返回值,那么方法会返回最后一次计算的结果。
其实p也是一个方法,它返回的是p所带的参数(或构成的数组)
于是 p @loc,也就是 self.p(@loc) 返回了100
而met方法返回了最后一次计算的结果,也就是p的返回值100
然后 p met 也就变成了 p 100
另外,puts的返回值是nil,你不要met返回100的话,把第3行改成puts就可以了
--------------------------------------------------
关于返回值
- def one 
-   return 1  # 1是该方法的返回值 
- end 
-   
- p one # 输出1 
- def one 
 
-   return 1  # 1是该方法的返回值 
 
- end 
 
-   
 
- p one # 输出1 
 
- def add_one(n) 
-   return n + 1 
- end 
-   
- a = 1 
- b = add_one(a)  # => 2 
- p b             # 输出2 
- def add_one(n) 
 
-   return n + 1 
 
- end 
 
-   
 
- a = 1 
 
- b = add_one(a)  # => 2 
 
- p b             # 输出2 
 
方法的返回值就是类似于函数的值的感觉嗯。
另外上面两个例子只是写着演示的,没什么实际用处。
作者: 余烬之中    时间: 2014-2-4 15:27
david_ng223 发表于 2014-2-4 14:53 
請問
def met
当你使用def...end的时候 你就定义了一个方法
ruby中每个方法都有返回值 但是并不需要你【显式】的返回 多数情况下我们是【隐式】的
| def met1  # 什么都没有的方法end p met1#=>nil
def met1 
  # 什么都没有的方法 
end 
  
p met1 
#=>nil 
 | def met2  1314 # 只有一个 值 的方法end p met2#=> 1314
def met2 
  1314 # 只有一个 值 的方法 
end 
  
p met2 
#=> 1314 
 | def met3  loc_var = 3 #定义局部变量  loc_var + 5 #计算将局部变量与5的和end p met3#=> 8#注意 loc_var 已经被释放 不再存在#但是它的值一直是3
def met3 
  loc_var = 3 #定义局部变量 
  loc_var + 5 #计算将局部变量与5的和 
end 
  
p met3 
#=> 8 
#注意 loc_var 已经被释放 不再存在 
#但是它的值一直是3 
 | 
| @ins= 999def met4  @ins/ 3end p met4#=> 333p @ins#=> 999
@ins= 999 
def met4 
  @ins/ 3 
end 
  
p met4 
#=> 333 
p @ins 
#=> 999 
 | def met5  a = 12580  submet(a) #调用另一个方法 传递了参数end p met5#NameError:undefined local variable or method 'submet' def submet(x)  x * 100end p met5#=> 1258000
def met5 
  a = 12580 
  submet(a) #调用另一个方法 传递了参数 
end 
  
p met5 
#NameError:undefined local variable or method 'submet' 
  
def submet(x) 
  x * 100 
end 
  
p met5 
#=> 1258000 
 | def met6   9   return 100 #显式返回一个值的方法   1 #后面的内容根本不执行 包括本行和下一行   puts "dodododo"end p met6#=> 100
def met6 
   9 
   return 100 #显式返回一个值的方法 
   1 #后面的内容根本不执行 包括本行和下一行 
   puts "dodododo" 
end 
  
p met6 
#=> 100 
 | 
  
作者: david_ng223    时间: 2014-2-4 18:34
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-5 11:37
david_ng223 发表于 2014-2-4 18:34 
a = 0 # 把0 代入变量a
i = 1 # 把1 代入变量i
复杂的形式不建议用后缀表达式
而且一般来说较多的语句最好写成块
但是如果一定要写的话:
- a = 0 
- i = 1 
- [a += i, i += 1] while i <= 5 
- p a 
- a = 0 
 
- i = 1 
 
- [a += i, i += 1] while i <= 5 
 
- p a 
 
如果想坑爹点
- a = 0 
- i = 1 
- a += i += 1 while i <= 4; a + 1 
- p a 
- a = 0 
 
- i = 1 
 
- a += i += 1 while i <= 4; a + 1 
 
- p a 
 
或者换个思路 不用while- a = 0 
- 6.times{|i| a+=i} 
- p a 
- a = 0 
 
- 6.times{|i| a+=i} 
 
- p a 
 
作者: david_ng223    时间: 2014-2-5 12:25
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-5 12:28
david_ng223 发表于 2014-2-5 12:25 
a = 0
    i = 1
    a += i += 1 while i
我少打了一个等于号
这样- a += i += 1 while i <= 4 ; a += 1 
- a += i += 1 while i <= 4 ; a += 1 
 
事实上,用分号隔开的 就是两个语句
等价于- a += i += 1 while i <= 4 
-  a += 1 
- a += i += 1 while i <= 4 
 
-  a += 1 
 
输出15
作者: david_ng223    时间: 2014-2-5 12:47
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-5 12:51
david_ng223 发表于 2014-2-5 12:47 
41樓的第1,2段代碼都明白了,
仍然不明白第3段的
6.times{|i| a+=i}
times是整数的方法
times {|n| ... } 
依次迭代执行 self 次,从 0 至 self-1。若 self 为负数,则什么都不做。
返回 self。
- 7.times{|i| p i} 
- #=>0 1 2 3 4 5 6 
- 7.times{|i| p i} 
 
- #=>0 1 2 3 4 5 6 
 
until等价于 while not
- a  = 0 
- i = 1 
- [a += i, i += 1] until i > 5 
- p a 
- a  = 0 
 
- i = 1 
 
- [a += i, i += 1] until i > 5 
 
- p a 
 
和之前第一段是一样的
作者: taroxd    时间: 2014-2-5 13:56
 本帖最后由 taroxd 于 2014-2-5 14:06 编辑 
david_ng223 发表于 2014-2-5 12:47 
41樓的第1,2段代碼都明白了,
仍然不明白第3段的
6.times{|i| a+=i}
until 的例子
(选自RGSS3) update until scene_changing?
scene_changing? 是一个方法,如果场景变化就返回true
所以直到场景变化前,游戏场景会不断update,不断update
求和的话可以 p (1..5).inject(:+) 省事,省心~ while 神马的都是浮云
另外说一下,我没有被@到……
作者: 无脑之人    时间: 2014-2-5 16:46
好神奇的版聊帖,过来围观学习等待扣分【大雾
作者: david_ng223    时间: 2014-2-5 17:42
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-5 17:58
david_ng223 发表于 2014-2-5 17:42 
引用12樓第8行
可是我在94頁的教程中找不到一個=~,
表示我只知道=,==,+=,-=,*=,/=,%=,**=,!=,=的用法
恩……self === other 
此方法多是是用于 case 判断句中。预设情况下与 Object#== 相同。在子类中进行归属检查时,可以根据情况重新定义。
- a = 0 
- puts "Instance variables a is a " + 
- case a 
- when :hello 
-   "symbol hello" 
- when "hi" 
-   "string hi" 
- when 1 
-   "Integer 1" 
- when 0 
-   "Integer 0" 
- else 
-   "Something else" 
- end 
- #=>Instance variables a is a Integer 0 
-   
- #依次调用===比较a与case后面的元素 
- #如果true 执行子句 
- a = 0 
 
- puts "Instance variables a is a " + 
 
- case a 
 
- when :hello 
 
-   "symbol hello" 
 
- when "hi" 
 
-   "string hi" 
 
- when 1 
 
-   "Integer 1" 
 
- when 0 
 
-   "Integer 0" 
 
- else 
 
-   "Something else" 
 
- end 
 
- #=>Instance variables a is a Integer 0 
 
-   
 
- #依次调用===比较a与case后面的元素 
 
- #如果true 执行子句 
 
有时候我们的比较更特殊
有一个类- class I_AM_A_CLASS 
-   attr_accessor :m, :n 
- end 
- class I_AM_A_CLASS 
 
-   attr_accessor :m, :n 
 
- end 
 
- a = I_AM_A_CLASS.new 
-   
- puts a == I_AM_A_CLASS.new 
- #=> false 
- a = I_AM_A_CLASS.new 
 
-   
 
- puts a == I_AM_A_CLASS.new 
 
- #=> false 
 
- class I_AM_A_CLASS 
-   def ===(other) 
-     return false if self.class != other.class 
-     self.m === other.m && self.n  === other.n 
-   end 
- end 
- class I_AM_A_CLASS 
 
-   def ===(other) 
 
-     return false if self.class != other.class 
 
-     self.m === other.m && self.n  === other.n 
 
-   end 
 
- end 
 
有这个比较- a = I_AM_A_CLASS.new 
-   
- puts a == I_AM_A_CLASS.new 
- #=> false 
-   
- puts a === I_AM_A_CLASS.new 
- #=> true 
- a = I_AM_A_CLASS.new 
 
-   
 
- puts a == I_AM_A_CLASS.new 
 
- #=> false 
 
-   
 
- puts a === I_AM_A_CLASS.new 
 
- #=> true 
 
作者: taroxd    时间: 2014-2-5 18:14
 本帖最后由 taroxd 于 2014-2-5 18:29 编辑 
首先参见34楼,有对case的简单介绍
case中用的是 === 来判定相等
- def balabala(something) 
-   case something 
-   when 'string' then puts 'something is "string"' 
-   when /string/ then puts 'something is a string that includes "string"' 
-   when String then puts 'something is a string' 
-   else puts 'something is not a string' 
-   end 
- end 
-   
- balabala('string') 
- balabala('i am a string') 
- balabala('balabala') 
- balabala(/string/) 
- balabala(String) 
- def balabala(something) 
 
-   case something 
 
-   when 'string' then puts 'something is "string"' 
 
-   when /string/ then puts 'something is a string that includes "string"' 
 
-   when String then puts 'something is a string' 
 
-   else puts 'something is not a string' 
 
-   end 
 
- end 
 
-   
 
- balabala('string') 
 
- balabala('i am a string') 
 
- balabala('balabala') 
 
- balabala(/string/) 
 
- balabala(String) 
 
输出结果:
something is "string"
something is a string that includes "string"
something is a string
something is not a string
something is not a string
这说明,
regexp === string 的结果是匹配是否成功。
class === instance 的结果是 instance 是否是 class 或其子类的实例。
这两者都与原来的 == 意义无关了
当然 === 不一定要用在case语句里,你也可以拿出来单独用,比如17L代码第三行的注释里面
作者: david_ng223    时间: 2014-2-5 23:35
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-6 08:30
david_ng223 发表于 2014-2-5 23:35 
經過這4天學習ruby的日子,
雖然余烬之中和taroxd都說ruby很簡單,
再加上兩位悉心的教導,
学习算不上……因为都只是走马观花 看了VB C/C++ Java 算是明白基础语法 但不能说会……
比较起来ruby还算是很容易的
如果以脚本为目的的话 现在你可以尝试着去写了
当然 根据你想要的功能你常常要翻一下RGSS3游戏内建类  或者参考一下自带脚本 这是很正常的
作者: david_ng223    时间: 2014-2-6 20:27
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-6 21:29
david_ng223 发表于 2014-2-6 20:27 
請問@viewport是什么來的??
@taroxd @余烬之中
 
 
简单地说 比如一个游戏  窗口是544*416的 现在我要显示两个精灵 不想让A遮挡或影响到B 或者有好多精灵想要分组管理 就使用viewport
一般情况下viewport不需要指定
作者: david_ng223    时间: 2014-2-6 22:34
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-6 22:51
david_ng223 发表于 2014-2-6 22:34 
#--------------------------------------------------------------------------
  # ● 创建敌人类型 ...
因为涉及到各种类的新定义方法 所以解释起来很复杂
但是关键的一点
找到方法所述的实例 找到实例所述的类 找到类中关于方法的定义- @category_window.item_window = @list_window 
- @category_window.item_window = @list_window 
 
item_window 是@category_window的方法 而@category_window = Window_EnemyType.new(0, 0)
所以你到class Window_EnemyType中寻找item_window 的定义就OK
不过貌似你的脚本不是自带脚本 所以我找不到……新定义的类在定义中寻找 这是脚本作者定义的方法
@list_window.info_window = @detail_window同理
作者: 余烬之中    时间: 2014-2-6 23:07
可以找到
- def item_window=(item_window) 
-     @item_window = item_window 
-     update 
-   end 
- def item_window=(item_window) 
 
-     @item_window = item_window 
 
-     update 
 
-   end 
 
所以在Window_EnemyType 这个类中寻找有关@item_window的操作
- def update 
-     super 
-     @item_window.category = current_symbol if @item_window 
-   end 
- def update 
 
-     super 
 
-     @item_window.category = current_symbol if @item_window 
 
-   end 
 
基本上就是这样
那么 现在关注@item_window.category = current_symbol
我们知道 这个@item_window实际上是- @category_window.item_window = @list_window 
- @category_window.item_window = @list_window 
 
于是找 @list_window- @list_window = Window_EnemyList.new(0, 48, 160, Graphics.height-48) 
- @list_window = Window_EnemyList.new(0, 48, 160, Graphics.height-48) 
 
现在又找Window_EnemyList- class Window_EnemyList < Window_ItemList 
- class Window_EnemyList < Window_ItemList 
 
并且class Window_EnemyList中并没有category方法 所以我们找他的父类 这个父类在内部类中
 
就这样 一层一层找下去 会发现这个category会在下级窗口中显示指定类别的物品(普通、防具、武器、贵重)【为什么我知道 这只不过是用得多了自然记住 不需要特别的记
另外一个@list_window.info_window = @detail_window也是一样
info_window 方法是新的方法 @detail_window属于Window_EnemyDetail 是新的类 我今晚时间不够 就只说这么多了
作者: david_ng223    时间: 2014-2-7 08:35
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-7 09:01
david_ng223 发表于 2014-2-7 08:35 
那么即是說:
@category_window的下级窗口會显示指定类别的物品,
而這個會显示指定类别物品的窗口就是@lis ...
是的 我再举个例子
比如我们要实现一个场景Scene_Review  这个场景目的是显示已经经历过的情节
那么场景的左边是一个窗口 用来选择事件(比如【哈斯顿战役】)  右边是另一个窗口 显示详细的描述(XX年XX月XX日  哈斯顿城…………)
假设左边的窗口有这样的部分定义- class Widow_ReviewList < Window_Base 
-   def info_window=(iw) 
-      @info_window = iw 
-   end 
-   
-   def update 
-      # update self 
-      update_info if @info_window 
-   end 
-   
-   def update_info 
-     @info_window.set_text(INFORMATION[@index]) 
-   end 
- end 
- class Widow_ReviewList < Window_Base 
 
-   def info_window=(iw) 
 
-      @info_window = iw 
 
-   end 
 
-   
 
-   def update 
 
-      # update self 
 
-      update_info if @info_window 
 
-   end 
 
-   
 
-   def update_info 
 
-     @info_window.set_text(INFORMATION[@index]) 
 
-   end 
 
- end 
 
右边的窗口有这样的定义- class Window_ReviewDetail < Window_Base 
-   def set_text(text) 
-      contents.clear 
-      draw_text_ex(0,0,100,100,text) 
-   end 
- end 
- class Window_ReviewDetail < Window_Base 
 
-   def set_text(text) 
 
-      contents.clear 
 
-      draw_text_ex(0,0,100,100,text) 
 
-   end 
 
- end 
 
很显然   左边的List需要一个下属机构    List会把详细内容告诉下属机构   下属机构负责描绘出来    其中INFORMATION是一个数组   INFORMATION[@index]获取指定序号的事件的详细信息*
那么 我们可以在场景中这样
- class Scene_Review < Scene_Base 
-   def start 
-     super 
-     create_detail_window 
-     create_list_window 
-   end 
-   
-   def create_detail_window 
-     @detail_window = Window_ReviewDetail.new 
-     # do something or not 
-   end 
-   
-   def create_list_window 
-       @list_window = Window_ReviewList.new 
-       @list_window.info_window = @detail_window 
-       # do sth. or not 
-   end 
- end 
- class Scene_Review < Scene_Base 
 
-   def start 
 
-     super 
 
-     create_detail_window 
 
-     create_list_window 
 
-   end 
 
-   
 
-   def create_detail_window 
 
-     @detail_window = Window_ReviewDetail.new 
 
-     # do something or not 
 
-   end 
 
-   
 
-   def create_list_window 
 
-       @list_window = Window_ReviewList.new 
 
-       @list_window.info_window = @detail_window 
 
-       # do sth. or not 
 
-   end 
 
- end 
 
* 获取指定序号的详细信息并不安全  因为随着游戏进程  各种事件的序号会改变  但这里只是举个例子
作者: david_ng223    时间: 2014-2-7 09:28
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-7 09:37
david_ng223 发表于 2014-2-7 09:28 
為什麼@category_window的下级窗口需要显示指定类别的物品???
我怎不見敌人图鉴 VA在遊戲裡面,
有任何關 ...
这里的【物品】 实际上是item 也就是项目
每一个怪物都是一个项目 而怪物有分类
所以 从属级别是这样:
有很多分类 每个分类下有很多怪物  每个怪物有很多细节信息
 
作者: david_ng223    时间: 2014-2-7 10:37
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-7 10:55
david_ng223 发表于 2014-2-7 10:37 
圖片是我想要的圖鑑,有四個窗口,分別是左上,左下,右上,右下(屬性,身高體重,說明,图片,No.,能力)
左上的 ...
大致是这样 问题应该没有 我只是粗略的看了一遍 细节方面的调试应该在实际运行中检测
作者: david_ng223    时间: 2014-2-7 14:14
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-7 15:17
david_ng223 发表于 2014-2-7 14:14 
class Window_Pokedex < Window_Base
  include Dream::Pokedex
  def draw_pokedex_icon(icon_index,  ...
我们知道class 类名  end 可以定义一个类
我们知道类名.new可以生成一个实例
但是当我们new时 应该使用参数吗?应该使用几个参数?Class 类类
类的类。更准确的说,每个类都有一个无名的「元类」,而此类就是那些元类的类。这种关系有点复杂,但是对于使用 Ruby 并非特别需要了解这种关系。 
与模块相比,类:
可以生成实例 
无法使用 include 进行混合 
除此之外,几乎所有的功能都是继承自 Module 模块类。
new( ... ) 
生成一个类的实例并返回该实例。这个方法的参数,包括区块参数,都会传递给 initialize 。
于是 注意initialize Object 物件类
所有类的超类,定义了一般对象的行为。
initialize 
用户定义的类所使用的初始化方法。此方法是由 Class#new 调用来初始化新生成的物件。预设情况下,没有任何动作;假定此方法会在子类中依照需求重新定义。若是向  Class#new 传递了任何参数,则会原封不动的传递给 initialize。
好 现在我们看到一般的WindowWindow 窗口类
游戏窗口的类。在内部由多重的精灵所组成。
Window.new([x, y, width, height])  
创建一个窗口,并可以用参数来指定位置与大小。
- class Window_Base < Window 
-   #-------------------------------------------------------------------------- 
-   # ● 初始化对象 
-   #-------------------------------------------------------------------------- 
-   def initialize(x, y, width, height) 
- class Window_Base < Window 
 
-   #-------------------------------------------------------------------------- 
 
-   # ● 初始化对象 
 
-   #-------------------------------------------------------------------------- 
 
-   def initialize(x, y, width, height) 
 
所以一般的窗口类是四个参数 x y 宽 高
但是注意你出错的地方  参数错误 4 for 2的意思就是 只需要两个参数 你却用了四个
于是往下翻
- @pokemon_window = Window_Pokemon.new(0, 0, 408, 52) 
- @pokemon_window = Window_Pokemon.new(0, 0, 408, 52) 
 
- class Window_Pokemon < Window_HorzCommand 
- class Window_Pokemon < Window_HorzCommand 
 
- class Window_HorzCommand < Window_Command 
- class Window_HorzCommand < Window_Command 
 
- class Window_Command < Window_Selectable 
-   #-------------------------------------------------------------------------- 
-   # ● 初始化对象 
-   #-------------------------------------------------------------------------- 
-   def initialize(x, y) 
- class Window_Command < Window_Selectable 
 
-   #-------------------------------------------------------------------------- 
 
-   # ● 初始化对象 
 
-   #-------------------------------------------------------------------------- 
 
-   def initialize(x, y) 
 
就是这样
作者: david_ng223    时间: 2014-2-7 15:54
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-7 16:08
david_ng223 发表于 2014-2-7 15:54 
這樣就 参数错误 4 for 2這樣就 
@pokemon_window = Window_Pokemon.new(136, 0)[/pre]
现在你需要改的是宽度
但是很明显 new没有提供改宽度的方法
但是一个Window需要宽度 这个宽度从哪里来呢?- class Window_Command < Window_Selectable 
-   #-------------------------------------------------------------------------- 
-   # ● 初始化对象 
-   #-------------------------------------------------------------------------- 
-   def initialize(x, y) 
-     clear_command_list 
-     make_command_list 
-     super(x, y, window_width, window_height) 
-     refresh 
-     select(0) 
-     activate 
-   end 
- class Window_Command < Window_Selectable 
 
-   #-------------------------------------------------------------------------- 
 
-   # ● 初始化对象 
 
-   #-------------------------------------------------------------------------- 
 
-   def initialize(x, y) 
 
-     clear_command_list 
 
-     make_command_list 
 
-     super(x, y, window_width, window_height) 
 
-     refresh 
 
-     select(0) 
 
-     activate 
 
-   end 
 
- class Window_Selectable < Window_Base 
-   #-------------------------------------------------------------------------- 
-   # ● 初始化对象 
-   #------------------------------------------------------------------------- 
-   def initialize(x, y, width, height) 
- class Window_Selectable < Window_Base 
 
-   #-------------------------------------------------------------------------- 
 
-   # ● 初始化对象 
 
-   #------------------------------------------------------------------------- 
 
-   def initialize(x, y, width, height) 
 
于是再次集中注意力到super(x, y, window_width, window_height)
很明显x y是你传进去的(def initialize(x, y))但是window_width, window_height是什么呢- #-------------------------------------------------------------------------- 
-   # ● 获取窗口的宽度 
-   #-------------------------------------------------------------------------- 
-   def window_width 
-     return 160 
-   end 
-   #-------------------------------------------------------------------------- 
-   # ● 获取窗口的高度 
-   #-------------------------------------------------------------------------- 
-   def window_height 
-     fitting_height(visible_line_number) 
-   end 
- #-------------------------------------------------------------------------- 
 
-   # ● 获取窗口的宽度 
 
-   #-------------------------------------------------------------------------- 
 
-   def window_width 
 
-     return 160 
 
-   end 
 
-   #-------------------------------------------------------------------------- 
 
-   # ● 获取窗口的高度 
 
-   #-------------------------------------------------------------------------- 
 
-   def window_height 
 
-     fitting_height(visible_line_number) 
 
-   end 
 
当然 我们不能直接在Window_Command里面改  我们只需要在Window_Pokemon中覆盖这个方法就可以了
在Window_Pokemon类中 加入如下代码段- def window_width 
-     return 408 
-   end 
- def window_width 
 
-     return 408 
 
-   end 
 
作者: taroxd    时间: 2014-2-7 16:30
 本帖最后由 taroxd 于 2014-2-7 16:47 编辑 
余烬之中 发表于 2014-2-7 16:08 
现在你需要改的是宽度
但是很明显 new没有提供改宽度的方法
但是一个Window需要宽度 这个宽度从哪里来呢 ...
以下内容未经测试,写错勿怪
1. 正是因为不会自适应(还有继承之类的关系),定义方法window_width这样的方法才是有意义的,便于调试。否则一个常量就解决了
一种方法是不断修改这个方法的返回的值,直到改出合适的值为止。
例子楼上已给
2. 另一种方法是通过计算完成。(简单举例:内容宽度 + 边框 * 2 )
计算过程可以写在window_width这样的方法里,便于之后的理解调试。(这正是用方法不用常量的原因)
如果在计算窗口宽度时需要其他窗口的数据,那么计算可以在场景中完成。
举例:
- # 这是一个场景的创建窗口的方法 
- def create_window1 
-   @window1 = Window_One.new(...) 
-   @window1.x = @window2.x + @window2.width       # window2 是一个已经被创建好的窗口 
-   @window1.width = Graphics.width - @window1.x   # 这使得window1紧靠window2右边,并延伸至画面右端 
- end 
- # 这是一个场景的创建窗口的方法 
 
- def create_window1 
 
-   @window1 = Window_One.new(...) 
 
-   @window1.x = @window2.x + @window2.width       # window2 是一个已经被创建好的窗口 
 
-   @window1.width = Graphics.width - @window1.x   # 这使得window1紧靠window2右边,并延伸至画面右端 
 
- end 
 
或者参考实际一点的,Scene_Menu的这个方法
- def create_gold_window 
-   @gold_window = Window_Gold.new 
-   @gold_window.x = 0  # 使得显示金钱的窗口在左方 
-   @gold_window.y = Graphics.height - @gold_window.height  # 使得显示金钱的窗口在底部 
- end 
- def create_gold_window 
 
-   @gold_window = Window_Gold.new 
 
-   @gold_window.x = 0  # 使得显示金钱的窗口在左方 
 
-   @gold_window.y = Graphics.height - @gold_window.height  # 使得显示金钱的窗口在底部 
 
- end 
 
作者: david_ng223    时间: 2014-2-7 20:25
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-7 20:32
david_ng223 发表于 2014-2-7 20:25 
class Window_Pokedex < Window_Base
  include Dream::Pokedex
  #----------------------------------- ...
你有调用draw_pokedex_text这两个方法吗?
作者: david_ng223    时间: 2014-2-7 21:09
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-7 21:35
david_ng223 发表于 2014-2-7 21:09 
#--------------------------------------------------------------------------
  # ● 绘制敌人名称
 ...
为什么你要找draw_enemy_name啊  Window_Base里有这方法吗…………
如果你需要一个可以选择的列表,那么最好使用<Window_Selectable【可选择的窗口】
如果不是  Window_Base就可以了
需要了解的:
窗体类的update方法 一般是每一帧都调用一次 特殊情况以后再了解 【更新 update
refresh方法 一般用于描绘文字图像之类的 因为描绘比较耗费时间 所以只有当内容改变的时候才应该调用 (内容是否改变在update里判定) 【刷新 refresh
所以 你可以这样- def refresh
 
-   super
 
-   draw_pokedex_icon
 
-   draw_pokedex_text
 
- end
作者: david_ng223    时间: 2014-2-7 22:01
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-7 22:14
david_ng223 发表于 2014-2-7 22:01 
啊啊啊啊啊, ,為什麼只是1個icon和7只英文字都要這麼多步驟的..........
表示用了下面的代碼仍 ...
那么这样
- def initialize(x,y,width,height) 
-   super(x,y,width,height) 
-   refresh 
- end 
-   
- def refresh 
-   contents.clear 
-   draw_pokedex_icon 
-   draw_pokedex_text 
- end 
- def initialize(x,y,width,height) 
 
-   super(x,y,width,height) 
 
-   refresh 
 
- end 
 
-   
 
- def refresh 
 
-   contents.clear 
 
-   draw_pokedex_icon 
 
-   draw_pokedex_text 
 
- end 
 
另外- draw_icon(POKEDEX_ICON, 0, 0, enabled) 
- draw_icon(POKEDEX_ICON, 0, 0, enabled) 
 
直接这样- draw_icon(POKEDEX_ICON, 0, 0) 
- draw_icon(POKEDEX_ICON, 0, 0) 
 
作者: david_ng223    时间: 2014-2-7 22:58
提示: 作者被禁止或删除 内容自动屏蔽
作者: taroxd    时间: 2014-2-8 09:30
david_ng223 发表于 2014-2-7 22:01 
啊啊啊啊啊, ,為什麼只是1個icon和7只英文字都要這麼多步驟的..........
表示用了下面的代碼仍 ...
我觉得,这东西没必要刷新(因为不会变)
干脆就在initialize画完就好了
另外我觉得你还需要更好的理解Ruby。这里写方法并不是要模仿其他类的方法,而是要真正自己写。
- class Window_Pokedex < Window_Base 
-   include Dream::Pokedex 
-   #-------------------------------------------------------------------------- 
-   # ● 初始化 
-   #-------------------------------------------------------------------------- 
-   def initialize(x, y, width, height)  # 这是在新建窗口的时候要做的事情 
-     super   # 用相同的参数调用父类方法 
-     draw_pokedex_icon   # 新建窗口的时候就画上图标 
-     draw_pokedex_text   # 新建窗口的时候就画上文字 
-   end 
-   #-------------------------------------------------------------------------- 
-   # ● 繪制图鉴圖標 
-   #     enabled : 有效的標志。false 的時候使用半透明效果繪制 
-   #-------------------------------------------------------------------------- 
-   def draw_pokedex_icon 
-     draw_icon(POKEDEX_ICON, 0, 0, enabled) 
-   end   
-   #-------------------------------------------------------------------------- 
-   # ● 绘制图鉴名称 
-   #-------------------------------------------------------------------------- 
-   def draw_pokedex_text 
-     draw_text(0, 0, 136, 52, POKEDEX_VOCAB) 
-   end 
- end 
- class Window_Pokedex < Window_Base 
 
-   include Dream::Pokedex 
 
-   #-------------------------------------------------------------------------- 
 
-   # ● 初始化 
 
-   #-------------------------------------------------------------------------- 
 
-   def initialize(x, y, width, height)  # 这是在新建窗口的时候要做的事情 
 
-     super   # 用相同的参数调用父类方法 
 
-     draw_pokedex_icon   # 新建窗口的时候就画上图标 
 
-     draw_pokedex_text   # 新建窗口的时候就画上文字 
 
-   end 
 
-   #-------------------------------------------------------------------------- 
 
-   # ● 繪制图鉴圖標 
 
-   #     enabled : 有效的標志。false 的時候使用半透明效果繪制 
 
-   #-------------------------------------------------------------------------- 
 
-   def draw_pokedex_icon 
 
-     draw_icon(POKEDEX_ICON, 0, 0, enabled) 
 
-   end   
 
-   #-------------------------------------------------------------------------- 
 
-   # ● 绘制图鉴名称 
 
-   #-------------------------------------------------------------------------- 
 
-   def draw_pokedex_text 
 
-     draw_text(0, 0, 136, 52, POKEDEX_VOCAB) 
 
-   end 
 
- end 
 
如果内容需要变化的话,就要调用refresh方法重绘内容(refresh只是一个名字,没有实际意义,但一般都用这方法。另外update这个名字是有实际意义的)
举个栗子
- class Window_Something 
-   def refresh  # 刷新 
-     contents.clear 
-     draw_contents  # 这个按照自己的写 
-   end 
-   
-   def update # 这个方法在场景里会自动每帧调用一次 
-     super 
-     refresh if need_refresh?  # need_refresh 是个需要自己写的条件 
-   end 
- end 
- class Window_Something 
 
-   def refresh  # 刷新 
 
-     contents.clear 
 
-     draw_contents  # 这个按照自己的写 
 
-   end 
 
-   
 
-   def update # 这个方法在场景里会自动每帧调用一次 
 
-     super 
 
-     refresh if need_refresh?  # need_refresh 是个需要自己写的条件 
 
-   end 
 
- end 
 
或者
- class Window_Something 
-   def refresh  # 刷新 
-     contents.clear 
-     draw_contents  # 这个按照自己的写 
-   end 
-   
-   def change_contents 
-     something is changed 
-     refresh 
-   end 
- end 
- class Window_Something 
 
-   def refresh  # 刷新 
 
-     contents.clear 
 
-     draw_contents  # 这个按照自己的写 
 
-   end 
 
-   
 
-   def change_contents 
 
-     something is changed 
 
-     refresh 
 
-   end 
 
- end 
 
作者: 无脑之人    时间: 2014-2-8 10:13
理解有困难的话,就直接用draw_text和blt之类的来画,没必要继承Window_Base的那些逗方法,如果需要包装一些固定的功能自己写几个方法也行
绘图过程放在refresh,在update里判定是否需要refresh,initialize里面根据需要来决定是否refresh,Window_Selectable一般都不refresh的,Window_Base往往是要的
Window系列的类继承时要小心,进行必要的super就可以了,Window_Base的update基本上就是不需要继承的,而Window_Selectable的update因为包括了按键判定就是需要继承的,如果继承了不必要的东西可能会出现一些难以觉察的错误
Window类要多写多熟悉,对于理解类的使用有帮助【以后理解了Sprite就可以把Window扔掉了【PIA
另外窗口分得很多,或者占满屏幕这样并不美观,建议好好设计一下,做成浮动窗口就更好了
作者: 余烬之中    时间: 2014-2-8 11:41
我尝试着看了一下 因为不知道你想要怎样的实现 所以简略的改了一下
真的很简略 主要是时间不够了
 Project1.rar
(1.91 MB, 下载次数: 44)
Project1.rar
(1.91 MB, 下载次数: 44)
作者: david_ng223    时间: 2014-2-8 13:54
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-8 15:26
david_ng223 发表于 2014-2-8 13:54 
為什麼我明明將顯示行數返回了5,可是遊戲中仍然會是11行的??
class Window_Category < Window_Command
正常情况下 visible_line_number的调用者是window_height 你这里覆盖了调用者 所以没有调用
而且 这个显示行数的原理是 调整窗口高度 把下面的遮起来
所以 只要窗口足够高  就能够显示指定行数
除非你的窗口刚好够显示五行 否则他就会铺满窗口
作者: david_ng223    时间: 2014-2-8 20:20
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-8 20:34
david_ng223 发表于 2014-2-8 20:20 
我把     class Window_Category < Window_Command     改回做     class Window_Category < Window_Item ...
你并不一定要跟着他来 方法是人写的 注意接口一致就可以了
def initialize中间一定要有super
def update中间一定要有super
这两个方法也可以省略不写 如果没有必要的话
但是如果想简易化处理 建议class Window_Category < Window_ItemCategory
作者: david_ng223    时间: 2014-2-8 21:16
提示: 作者被禁止或删除 内容自动屏蔽
| 欢迎光临 Project1 (https://rpg.blue/) | Powered by Discuz! X3.1 |