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 那些东西。不过在这里的代码完全不需要分行处理。

[建议]给一个修改意见吧:
RUBY 代码复制
  1. def pokedex_height      #我想在數據庫-主角-註釋用[pkdh 7.4]之後在窗口顯示數值7.4(pokemon的身高)
  2.   @note =~ /\[pkdh\s*(\d+(?:\.\d+)?)\]/ ? $1.to_f : 0.0
  3. end
  4. # 像这样,一行就可以解决的为什么要写这么长呢?
  5. # 如果觉得很难理解,请参阅F1文档和正则表达式的教程
  6. # 正则表达式看样子很可怕,其实是非常简单易用的,请务必学会

作者: 余烬之中    时间: 2014-2-1 14:22
david_ng223 发表于 2014-2-1 13:57
@余烬之中
這段改自敌人图鉴 VA-核心脚本-第61-83行
應該是讀取數據庫-敵人(我改成主角)-註釋內的東西?? ...
#為什麼上面用d+這裡用S+??
#什麼是$1??

这些你需要了解一下正则表达式
直接解释的话 是这样:
RUBY 代码复制
  1. line =~ /\[(?:pkdp) (\S+)\]/

你应该知道 line是一个字符串(String类的实例)变量   字符串常量用英文半角双引号""括起来
而后面的/\[(?:pkdp) (\S+)\]/是一个正则表达式(Regexp类的实例)常量   正则式常量用一对斜杠//括起来
字符串 =~ 正则式
将正则式与字符串进行匹配,匹配的结果存储在全局变量$~、$&和$1、$2、$3....中
$~存储所有匹配信息 $&是匹配成功的字符串 $1之类(后位引用)是分别匹配成功的字符串
这里有点难懂 给几个例子
RUBY 代码复制
  1. "hello!" =~ /he/
  2. # $~.to_a    ["he"]
  3. # $&            "he"
  4. # $1            nil

匹配成功 但未分群 所以无法后位引用 分群使用一对英文括号
RUBY 代码复制
  1. "Nice to meet you!" =~ /(nice).*(meet)/
  2. # $~.to_a   []
  3. # $&           nil
  4. # $1           nil

匹配失败 分了群 但无匹配 大小敏感
RUBY 代码复制
  1. "Nice to meet you!" =~ /(nice).*(meet)/i
  2. # $~.to_a   ["Nice to meet", "Nice", "meet"]
  3. # $&           "Nice to meet"
  4. # $1           "Nice"
  5. # $2           "meet"
  6. # $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
匹配任意的空白符

点评累死了……
==================================================================编辑↓
你的错误在这句话没有错误
RUBY 代码复制
  1. @note =~ /\[pkdh\s*(\d+(?:\.\d+)?)\]/ ? $1.to_f : 0.0
(第二个问号不需要 但是也不会出错 既然是冗余我就删了)
================ 补充:问号表示匹配一次或零次 如果所有数据强制要求0.0的形式不用问号 如果允许写整数就加上问号 ================
进行匹配
RUBY 代码复制
  1. "[pkdh 99.98]" =~ /\[pkdh\s*(\d+(?:\.\d+))\]/
  2. # $1  "99"
  3. # $2  nil

(感谢@taroxd 指出的Bug 这段解说↑有误 正确的如下)
RUBY 代码复制
  1. "[pkdh 99.98]" =~ /\[pkdh\s*(\d+(?:\.\d+))\]/
  2. # $1  "99.98"
  3. # $2  nil

==================================================================编辑↑
因为(?:)是 无后位引用功能的分群 不能被$2引用
你可以这样
RUBY 代码复制
  1. "[pkdh 99.98]" =~ /\[pkdh\s*(\d+)\.(\d+)\]/
  2. # $1  "99"
  3. # $2  "98"
还可以这样
RUBY 代码复制
  1. "[pkdh 99.98]" =~ /\[pkdh\s*(\d+\.\d+)\]/
  2. # $1  "99.98"
  3. # $2  nil
还可以这样
RUBY 代码复制
  1. "[pkdh 99.98]" =~ /\[pkdh\s*(.+\..+)\]/
  2. # $1  "99.98"
  3. # $2  nil

所以 最后就是这样
RUBY 代码复制
  1. @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

RUBY 代码复制
  1. 字符串 =~ 正则式
这代表将字符串与正则式进行匹配 失败则返回nil 成功返回未匹配的字符个数
RUBY 代码复制
  1. 表达式1 ? 表达式2 : 表达式3
等价于
RUBY 代码复制
  1. if 表达式1
  2.    表达式2
  3. else
  4.    表达式3
  5. end

如果表达式1为false或者nil则条件伪 执行3 否则条件真 执行2
所以
RUBY 代码复制
  1. 字符串 =~ 正则式 ? 使用$1 : 默认值

如果匹配了 就使用匹配信息 否则就用默认值

b与c

(不带反斜杠的)括号表示分群 只有分群后才能后位引用
RUBY 代码复制
  1. "ruby 1.9" =~ /ruby\s*\d+\.\d+/
  2. # $&  "ruby 1.9"
  3. # $1   nil
  4.  
  5. "ruby 1.9" =~ /ruby\s*(\d+\.\d+)/
  6. # $&  "ruby 1.9"
  7. # $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+)?)\]/

RUBY 代码复制
  1. /<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行可改为
RUBY 代码复制
  1. def pokedex_type_pokemon?
  2.   @note =~ /<pkdtpkm>/i # 三目运算符是多余的。
  3.   # 如果一定要返回true或false,可改为 /<pkdtpkm>/i === @note 或 !!(@note =~ /<pkdtpkm>/i) 或 !(@note !~ /<pkdtpkm>/i)
  4. 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 编辑
david_ng223 发表于 2014-2-1 21:49
@余烬之中 @taroxd

接著應該就是初始化了,


好吧 新手杀手alias 我还是举例子吧 先是super
一个父类
RUBY 代码复制
  1. class Base
  2.    def meet
  3.       say "Hello!"
  4.    end
  5.    def say *args
  6.       print *args
  7.    end
  8. end

一个子类
RUBY 代码复制
  1. class Derive < Base
  2.    def meet
  3.       super
  4.       say "How are you going?"
  5.    end
  6. end

父类的实例和子类的实例
RUBY 代码复制
  1. b = Base.new
  2. d = Derive.new
  3.  
  4. b.meet #=> Hello!
  5. d.meet #=> Hello!How are you going?

大概你已经能理解super了 现在是alias 既然上面有了一个Base类 我们就用它举例
分别考虑两种情况
===============================================不使用alias的情况
RUBY 代码复制
  1. class Base
  2.    def say *args
  3.       print "AAAAAAA"
  4.    end
  5. end
  6.  
  7. Base.new.meet #=> "AAAAAAA"
===============================================使用alias的情况
RUBY 代码复制
  1. class Base
  2.    alias old_say say
  3.    def say
  4.       old_say
  5.       print "AAAAAAA"
  6.    end
  7. end
  8.  
  9. 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”错误,例子:
RUBY 代码复制
  1. # 小A与小B都在写脚本 对已有的脚本进行修改
  2. #已有脚本
  3. class Player < Role
  4.   def talk *args
  5.      say *args
  6.   end
  7.   def say *args
  8.     puts *args
  9.   end
  10. end
  11.  
  12. #小A的脚本
  13. class  Player
  14.   alias old_talk talk
  15.   def talk *args
  16.     old_talk
  17.     puts "小A"
  18.   end
  19. end
  20.  
  21. #小B的脚本
  22. class Player
  23.   alias old_talk talk
  24.   def talk *args
  25.      old_talk
  26.      puts "小B"
  27.   end
  28. end
  29.  
  30. #运行
  31. p = Player.new
  32. p.talk "Hello!"
  33. # Stack Level Too Deep

但这样就没有错误
RUBY 代码复制
  1. #小A的脚本
  2. class  Player
  3.   alias old_talk_of_A talk
  4.   def talk *args
  5.     old_talk_of_A  
  6.     puts "小A"
  7.   end
  8. end
  9.  
  10. #小B的脚本
  11. class Player
  12.   alias old_talk_of_B talk
  13.   def talk *args
  14.      old_talk_of_B
  15.      puts "小B"
  16.   end
  17. end
  18.  
  19. #运行
  20. p = Player.new
  21. p.talk "Hello!"
  22. #=> "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是回车换行
RUBY 代码复制
  1. puts "==begin==\n\n======="
  2. puts "perform \\a\n\a\nend perform\n======="
  3. puts "perform \\x??\n\\x01=>\x01\n\\x02=>\x02\nend perform\n======="
  4. puts "perform \\t\nabcdT\tTefgh\nend perform\n======="
  5. puts "perform \\r\n\r\nend perform"
  6. 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
假设有语句
RUBY 代码复制
  1. print 1,"Hello",[3,4,"ok"],:symbol,Actor.new

就相当于
RUBY 代码复制
  1. 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
假设有语句
RUBY 代码复制
  1. puts 1,"Hello",[3,4,"ok"],:symbol,Actor.new

就相当于
RUBY 代码复制
  1. 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
假设有语句
RUBY 代码复制
  1. p 1,"Hello",[3,4,"ok"],:symbol,Actor.new

就相当于
RUBY 代码复制
  1. 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)
代码越简单越好,写完用下面的代码测试。

RUBY 代码复制
  1. loop do
  2.   t = Time.now
  3.   x = t.hour * 3600 + t.min * 60 + t.sec
  4.   # 在这里填上你的代码。x已经代入了当前的秒数
  5.   # 然后把代码放在脚本编辑器的Main之前
  6.   # 如果代码正确的话,应该能看到控制台中不断输出当前时间
  7.   # 注意把焦点放在游戏窗口上
  8.   # 测试完了别忘把这段代码删掉
  9.   Graphics.wait(60)
  10. end


提示:可以用 < 10 来判断是否要补0。

注:有比较高级的方法,参见 Game_System#playtime_s 。暂时不需要掌握。

--------------------------------------------------------------

参考:
RUBY 代码复制
  1. h = x / 60 / 60
  2. m = x / 60 % 60
  3. s = x % 60
  4.  
  5. h = h < 10 ? "0#{h}" : h.to_s
  6. m = m < 10 ? "0#{m}" : m.to_s
  7. s = s < 10 ? "0#{s}" : s.to_s
  8.  
  9. p "#{h}:#{m}:#{s}"
  10.  
  11. # 下面的两种方法现在不能理解没有关系
  12. # p [h, m, s].collect {|num| num < 10 ? "0#{num}" : num.to_s }.join(':')
  13. # 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


条件语句的正确缩进,以及各种用法

RUBY 代码复制
  1. if some_condition # 这里加 then 是不好的
  2.   do_something_if_some_condition
  3. elsif another_condition
  4.   do_something_if_another_condition
  5. else
  6.   do_something_else
  7. end
  8.  
  9. # unless...else...end 是不好的
  10.  
  11. do_something if some_condition
  12. some_condition and do_something  # 这句话句意和上面一句相同,暂时可以不用理解。
  13. # if some_condition then do_something end 是不好的
  14. # unless !some_condition 是不好的
  15.  
  16. do_something_else unless some_condition  # do_something if !some_condition 是不好的
  17. some_condition or do_something_else # 这句话句意和上面一句相同,暂时可以不用理解。
  18. # unless condition1 && condition2 是不好的
  19.  
  20. some_condition ? do_something : do_something_else
  21. # if some_condition then do_something else do_something_else end 是不好的
  22.  
  23. case expression
  24. when condition1 then do1
  25. when condition2 # 这里加 then 是不好的
  26.   do2_line1
  27.   do2_line2
  28. # when condition3: do3 #这样写是不好的,并且在Ruby后期版本已经不支持。请务必不要用这样的写法。
  29. else do_else # do_else 内容较长时建议换行
  30. end
  31. # 判断条件成立是用 condition === expression
  32.  
  33. # 以上“是不好的”仅仅是不建议这么写,写了也不会有任何问题。
  34. # 但事实上,以上不建议的写法在默认脚本中一次都没有出现过。

作者: 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也是

常量和变量都可以提前操作 至于这句话:
常量无法改变,只能赋值给别人。
说的是不能动态的改变
看两个例子
=======================================================
RUBY 代码复制
  1. CON = 100
  2. p CON
  3. #=>100
  4. CON += 50
  5. #warning: already initialized constant CON
  6. p CON
  7. #=>150
  8. another_var = CON
  9. p another_var #=> 150
在给常量第一次赋值以后 再对其赋值就会出现警告 但是不出错 继续执行 所以赋值还是能够成功
现在加上这样一段
RUBY 代码复制
  1. def met
  2.   CON += 3
  3.   p CON
  4. end #SyntaxError:dynamic constant assignment
  5.  
  6. met
这样的话这段代码无法通过语法检查 一句都不会执行 包括上面的100 150等
=======================================================
=======================================================
RUBY 代码复制
  1. loc = 100
  2. p loc
  3. #=>100
  4. loc += 50
  5. p loc
  6. #=>150
  7. another_var = loc
  8. p another_var #=> 150
  9.  
  10. def met
  11.   loc += 3
  12.   p loc
  13. end
  14.  
  15. met
  16. #undefined method '+' for nil:NilClass
这里也会出错 但是语法是正确的 它会输出100 150 150 然后报错 这里出错的原因是loc是局部变量 无法被met方法获取 但是其他变量可以
而且这里也没有出现警报
我们换成实例变量试试
RUBY 代码复制
  1. [url=home.php?mod=space&uid=77065]@ins[/url] = 100 # 坑人神句 下面不加井号之间的就是这样的结果
  2. @ins#-=-=-=-=-=-=-=-=-=-=-=-=# = 100  #←把井号及之间的删掉
  3. p @ins
  4. #=>100
  5. @ins#-=-=-=-=-=-=-=-=-=-=-=-=# += 50  #←把井号及之间的删掉
  6. p @ins
  7. #=>150
  8. another_var = @ins
  9. p another_var #=> 150
  10.  
  11. def met
  12.   [url=home.php?mod=space&uid=77065]@ins[/url] += 3
  13.   p @ins
  14. end
  15.  
  16. met
  17. #=>153
总体输出结果是 100 150 150 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就可以了

--------------------------------------------------

关于返回值

RUBY 代码复制
  1. def one
  2.   return 1  # 1是该方法的返回值
  3. end
  4.  
  5. p one # 输出1


RUBY 代码复制
  1. def add_one(n)
  2.   return n + 1
  3. end
  4.  
  5. a = 1
  6. b = add_one(a)  # => 2
  7. p b             # 输出2


方法的返回值就是类似于函数的值的感觉嗯。
另外上面两个例子只是写着演示的,没什么实际用处。
作者: 余烬之中    时间: 2014-2-4 15:27
david_ng223 发表于 2014-2-4 14:53
請問

def met


当你使用def...end的时候 你就定义了一个方法
ruby中每个方法都有返回值 但是并不需要你【显式】的返回 多数情况下我们是【隐式】的
RUBY 代码复制
  1. def met1
  2.   # 什么都没有的方法
  3. end
  4.  
  5. p met1
  6. #=>nil
RUBY 代码复制
  1. def met2
  2.   1314 # 只有一个 值 的方法
  3. end
  4.  
  5. p met2
  6. #=> 1314
RUBY 代码复制
  1. def met3
  2.   loc_var = 3 #定义局部变量
  3.   loc_var + 5 #计算将局部变量与5的和
  4. end
  5.  
  6. p met3
  7. #=> 8
  8. #注意 loc_var 已经被释放 不再存在
  9. #但是它的值一直是3
RUBY 代码复制
  1. @ins= 999
  2. def met4
  3.   @ins/ 3
  4. end
  5.  
  6. p met4
  7. #=> 333
  8. p @ins
  9. #=> 999
RUBY 代码复制
  1. def met5
  2.   a = 12580
  3.   submet(a) #调用另一个方法 传递了参数
  4. end
  5.  
  6. p met5
  7. #NameError:undefined local variable or method 'submet'
  8.  
  9. def submet(x)
  10.   x * 100
  11. end
  12.  
  13. p met5
  14. #=> 1258000
RUBY 代码复制
  1. def met6
  2.    9
  3.    return 100 #显式返回一个值的方法
  4.    1 #后面的内容根本不执行 包括本行和下一行
  5.    puts "dodododo"
  6. end
  7.  
  8. p met6
  9. #=> 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

复杂的形式不建议用后缀表达式
而且一般来说较多的语句最好写成块
但是如果一定要写的话:
RUBY 代码复制
  1. a = 0
  2. i = 1
  3. [a += i, i += 1] while i <= 5
  4. p a

如果想坑爹点
RUBY 代码复制
  1. a = 0
  2. i = 1
  3. a += i += 1 while i <= 4; a + 1
  4. p a

或者换个思路 不用while
RUBY 代码复制
  1. a = 0
  2. 6.times{|i| a+=i}
  3. 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

我少打了一个等于号
这样
RUBY 代码复制
  1. a += i += 1 while i <= 4 ; a += 1

事实上,用分号隔开的 就是两个语句
等价于
RUBY 代码复制
  1. a += i += 1 while i <= 4
  2. 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。

RUBY 代码复制
  1. 7.times{|i| p i}
  2. #=>0 1 2 3 4 5 6

until等价于 while not
RUBY 代码复制
  1. a  = 0
  2. i = 1
  3. [a += i, i += 1] until i > 5
  4. 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#== 相同。在子类中进行归属检查时,可以根据情况重新定义。


RUBY 代码复制
  1. a = 0
  2. puts "Instance variables a is a " +
  3. case a
  4. when :hello
  5.   "symbol hello"
  6. when "hi"
  7.   "string hi"
  8. when 1
  9.   "Integer 1"
  10. when 0
  11.   "Integer 0"
  12. else
  13.   "Something else"
  14. end
  15. #=>Instance variables a is a Integer 0
  16.  
  17. #依次调用===比较a与case后面的元素
  18. #如果true 执行子句



有时候我们的比较更特殊
有一个类
RUBY 代码复制
  1. class I_AM_A_CLASS
  2.   attr_accessor :m, :n
  3. end
如果有下列比较 返回值是false
RUBY 代码复制
  1. a = I_AM_A_CLASS.new
  2.  
  3. puts a == I_AM_A_CLASS.new
  4. #=> false
于是我们这样
RUBY 代码复制
  1. class I_AM_A_CLASS
  2.   def ===(other)
  3.     return false if self.class != other.class
  4.     self.m === other.m && self.n  === other.n
  5.   end
  6. end

有这个比较
RUBY 代码复制
  1. a = I_AM_A_CLASS.new
  2.  
  3. puts a == I_AM_A_CLASS.new
  4. #=> false
  5.  
  6. puts a === I_AM_A_CLASS.new
  7. #=> true

作者: taroxd    时间: 2014-2-5 18:14
本帖最后由 taroxd 于 2014-2-5 18:29 编辑

首先参见34楼,有对case的简单介绍
case中用的是 === 来判定相等

RUBY 代码复制
  1. def balabala(something)
  2.   case something
  3.   when 'string' then puts 'something is "string"'
  4.   when /string/ then puts 'something is a string that includes "string"'
  5.   when String then puts 'something is a string'
  6.   else puts 'something is not a string'
  7.   end
  8. end
  9.  
  10. balabala('string')
  11. balabala('i am a string')
  12. balabala('balabala')
  13. balabala(/string/)
  14. 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
#--------------------------------------------------------------------------
  # ● 创建敌人类型 ...

因为涉及到各种类的新定义方法 所以解释起来很复杂
但是关键的一点
找到方法所述的实例 找到实例所述的类 找到类中关于方法的定义
RUBY 代码复制
  1. @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
可以找到
RUBY 代码复制
  1. def item_window=(item_window)
  2.     @item_window = item_window
  3.     update
  4.   end

所以在Window_EnemyType 这个类中寻找有关@item_window的操作
RUBY 代码复制
  1. def update
  2.     super
  3.     @item_window.category = current_symbol if @item_window
  4.   end

基本上就是这样
那么 现在关注@item_window.category = current_symbol
我们知道 这个@item_window实际上是
RUBY 代码复制
  1. @category_window.item_window = @list_window

于是找 @list_window
RUBY 代码复制
  1. @list_window = Window_EnemyList.new(0, 48, 160, Graphics.height-48)

现在又找Window_EnemyList
RUBY 代码复制
  1. 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日  哈斯顿城…………)
假设左边的窗口有这样的部分定义
RUBY 代码复制
  1. class Widow_ReviewList < Window_Base
  2.   def info_window=(iw)
  3.      @info_window = iw
  4.   end
  5.  
  6.   def update
  7.      # update self
  8.      update_info if @info_window
  9.   end
  10.  
  11.   def update_info
  12.     @info_window.set_text(INFORMATION[@index])
  13.   end
  14. end

右边的窗口有这样的定义
RUBY 代码复制
  1. class Window_ReviewDetail < Window_Base
  2.   def set_text(text)
  3.      contents.clear
  4.      draw_text_ex(0,0,100,100,text)
  5.   end
  6. end

很显然   左边的List需要一个下属机构    List会把详细内容告诉下属机构   下属机构负责描绘出来    其中INFORMATION是一个数组   INFORMATION[@index]获取指定序号的事件的详细信息*

那么 我们可以在场景中这样
RUBY 代码复制
  1. class Scene_Review < Scene_Base
  2.   def start
  3.     super
  4.     create_detail_window
  5.     create_list_window
  6.   end
  7.  
  8.   def create_detail_window
  9.     @detail_window = Window_ReviewDetail.new
  10.     # do something or not
  11.   end
  12.  
  13.   def create_list_window
  14.       @list_window = Window_ReviewList.new
  15.       @list_window.info_window = @detail_window
  16.       # do sth. or not
  17.   end
  18. 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。

好 现在我们看到一般的Window
Window 窗口类
游戏窗口的类。在内部由多重的精灵所组成。
Window.new([x, y, width, height])  
创建一个窗口,并可以用参数来指定位置与大小。
RUBY 代码复制
  1. class Window_Base < Window
  2.   #--------------------------------------------------------------------------
  3.   # ● 初始化对象
  4.   #--------------------------------------------------------------------------
  5.   def initialize(x, y, width, height)

所以一般的窗口类是四个参数 x y 宽 高
但是注意你出错的地方  参数错误 4 for 2的意思就是 只需要两个参数 你却用了四个
于是往下翻
RUBY 代码复制
  1. @pokemon_window = Window_Pokemon.new(0, 0, 408, 52)
RUBY 代码复制
  1. class Window_Pokemon < Window_HorzCommand
RUBY 代码复制
  1. class Window_HorzCommand < Window_Command
RUBY 代码复制
  1. class Window_Command < Window_Selectable
  2.   #--------------------------------------------------------------------------
  3.   # ● 初始化对象
  4.   #--------------------------------------------------------------------------
  5.   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需要宽度 这个宽度从哪里来呢?
RUBY 代码复制
  1. class Window_Command < Window_Selectable
  2.   #--------------------------------------------------------------------------
  3.   # ● 初始化对象
  4.   #--------------------------------------------------------------------------
  5.   def initialize(x, y)
  6.     clear_command_list
  7.     make_command_list
  8.     super(x, y, window_width, window_height)
  9.     refresh
  10.     select(0)
  11.     activate
  12.   end
注意  这个super(x, y, window_width, window_height)就是呼叫父类中的同名方法 也就是Window_Selectablenew
RUBY 代码复制
  1. class Window_Selectable < Window_Base
  2.   #--------------------------------------------------------------------------
  3.   # ● 初始化对象
  4.   #-------------------------------------------------------------------------
  5.   def initialize(x, y, width, height)
看来Window_SelectablenewWindow_Base一样都是四个参数 x y 宽 高
于是再次集中注意力到super(x, y, window_width, window_height)
很明显x y是你传进去的(def initialize(x, y))但是window_width, window_height是什么呢
RUBY 代码复制
  1. #--------------------------------------------------------------------------
  2.   # ● 获取窗口的宽度
  3.   #--------------------------------------------------------------------------
  4.   def window_width
  5.     return 160
  6.   end
  7.   #--------------------------------------------------------------------------
  8.   # ● 获取窗口的高度
  9.   #--------------------------------------------------------------------------
  10.   def window_height
  11.     fitting_height(visible_line_number)
  12.   end
其中fitting_height(visible_line_number)获取合适的高度(自适应) 所以不用管它 我们需要调整window_width
当然 我们不能直接在Window_Command里面改  我们只需要在Window_Pokemon中覆盖这个方法就可以了

Window_Pokemon类中 加入如下代码段
RUBY 代码复制
  1. def window_width
  2.     return 408
  3.   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这样的方法里,便于之后的理解调试。(这正是用方法不用常量的原因)

如果在计算窗口宽度时需要其他窗口的数据,那么计算可以在场景中完成。

举例:
RUBY 代码复制
  1. # 这是一个场景的创建窗口的方法
  2. def create_window1
  3.   @window1 = Window_One.new(...)
  4.   @window1.x = @window2.x + @window2.width       # window2 是一个已经被创建好的窗口
  5.   @window1.width = Graphics.width - @window1.x   # 这使得window1紧靠window2右边,并延伸至画面右端
  6. end


或者参考实际一点的,Scene_Menu的这个方法

RUBY 代码复制
  1. def create_gold_window
  2.   @gold_window = Window_Gold.new
  3.   @gold_window.x = 0  # 使得显示金钱的窗口在左方
  4.   @gold_window.y = Graphics.height - @gold_window.height  # 使得显示金钱的窗口在底部
  5. 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

所以 你可以这样
  1. def refresh
  2.   super
  3.   draw_pokedex_icon
  4.   draw_pokedex_text
  5. end
复制代码

作者: david_ng223    时间: 2014-2-7 22:01
提示: 作者被禁止或删除 内容自动屏蔽
作者: 余烬之中    时间: 2014-2-7 22:14
david_ng223 发表于 2014-2-7 22:01
啊啊啊啊啊, ,為什麼只是1個icon和7只英文字都要這麼多步驟的..........
表示用了下面的代碼仍 ...

那么这样
RUBY 代码复制
  1. def initialize(x,y,width,height)
  2.   super(x,y,width,height)
  3.   refresh
  4. end
  5.  
  6. def refresh
  7.   contents.clear
  8.   draw_pokedex_icon
  9.   draw_pokedex_text
  10. end
因为父类没有调用refresh 自然什么都没有
另外
RUBY 代码复制
  1. draw_icon(POKEDEX_ICON, 0, 0, enabled)
后面的enabled是个没有值的变量  不要用它 因为会描绘成半透明
直接这样
RUBY 代码复制
  1. 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。这里写方法并不是要模仿其他类的方法,而是要真正自己写。

RUBY 代码复制
  1. class Window_Pokedex < Window_Base
  2.   include Dream::Pokedex
  3.   #--------------------------------------------------------------------------
  4.   # ● 初始化
  5.   #--------------------------------------------------------------------------
  6.   def initialize(x, y, width, height)  # 这是在新建窗口的时候要做的事情
  7.     super   # 用相同的参数调用父类方法
  8.     draw_pokedex_icon   # 新建窗口的时候就画上图标
  9.     draw_pokedex_text   # 新建窗口的时候就画上文字
  10.   end
  11.   #--------------------------------------------------------------------------
  12.   # ● 繪制图鉴圖標
  13.   #     enabled : 有效的標志。false 的時候使用半透明效果繪制
  14.   #--------------------------------------------------------------------------
  15.   def draw_pokedex_icon
  16.     draw_icon(POKEDEX_ICON, 0, 0, enabled)
  17.   end  
  18.   #--------------------------------------------------------------------------
  19.   # ● 绘制图鉴名称
  20.   #--------------------------------------------------------------------------
  21.   def draw_pokedex_text
  22.     draw_text(0, 0, 136, 52, POKEDEX_VOCAB)
  23.   end
  24. end


如果内容需要变化的话,就要调用refresh方法重绘内容(refresh只是一个名字,没有实际意义,但一般都用这方法。另外update这个名字是有实际意义的)
举个栗子
RUBY 代码复制
  1. class Window_Something
  2.   def refresh  # 刷新
  3.     contents.clear
  4.     draw_contents  # 这个按照自己的写
  5.   end
  6.  
  7.   def update # 这个方法在场景里会自动每帧调用一次
  8.     super
  9.     refresh if need_refresh?  # need_refresh 是个需要自己写的条件
  10.   end
  11. end


或者
RUBY 代码复制
  1. class Window_Something
  2.   def refresh  # 刷新
  3.     contents.clear
  4.     draw_contents  # 这个按照自己的写
  5.   end
  6.  
  7.   def change_contents
  8.     something is changed
  9.     refresh
  10.   end
  11. 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)
作者: 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