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"
===============================================使用alias的情况
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
这样的话这段代码无法通过语法检查 一句都不会执行 包括上面的100 150等
=======================================================
=======================================================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
这里也会出错 但是语法是正确的 它会输出100 150 150 然后报错 这里出错的原因是loc是局部变量 无法被met方法获取 但是其他变量可以
而且这里也没有出现警报
我们换成实例变量试试
[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
总体输出结果是 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就可以了
--------------------------------------------------
关于返回值
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= 999 def met4 @ins/ 3 end p met4 #=> 333 p @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 * 100 end 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
或者换个思路 不用whilea = 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
如果有下列比较 返回值是false
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_EnemyListclass 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
注意 这个super(x, y, window_width, window_height)就是呼叫父类中的同名方法 也就是Window_Selectable的newclass Window_Selectable < Window_Base
#--------------------------------------------------------------------------
# ● 初始化对象
#-------------------------------------------------------------------------
def initialize(x, y, width, height)
class Window_Selectable < Window_Base
#--------------------------------------------------------------------------
# ● 初始化对象
#-------------------------------------------------------------------------
def initialize(x, y, width, height)
看来Window_Selectable的new和Window_Base一样都是四个参数 x y 宽 高
于是再次集中注意力到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
其中fitting_height(visible_line_number)获取合适的高度(自适应) 所以不用管它 我们需要调整window_width
当然 我们不能直接在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
因为父类没有调用refresh 自然什么都没有
另外draw_icon(POKEDEX_ICON, 0, 0, enabled)
draw_icon(POKEDEX_ICON, 0, 0, enabled)
后面的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)
作者: 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 |