发个教程 在地图上创建时间窗口
准备就绪 首先先规划一下你的窗口要放在哪里、窗口要多大、要显示什么文字、时间的换算率是多少、会不会文件到玩家视线。因为是范例,所以我把窗口放在最上面,宽640,高55。 再来必须知道,要显示一个窗口,首先当然要有一个窗口类,再来一个场景调用窗口。我们要让窗口在地图上显示,而地图就是一个场景: $Scene_Map类 。而窗口是 $Window_Base的子类。 新建一个新的脚本,打上: class Scene_Map end
class Window_Time_Date < Window_Base end
这样就定义了两个类,第一个是地图画面,第二个是窗口,Window_Time_Date < Window_Base 表示我们创的窗口Window_Time_Date 是继承 Window_Base 里做有方法的子类。 接下来先来处理地图部分
第一节 地图画面脚本 地图部分先按照脚本内的$Scene_Map 写一段脚本,最好是全部自己打,才能知道你要打什么。 $Scene_Map 的脚本实在太长了,我们来挑选我们需要的地方。 $Scene_Map 脚本解析如下: 1. main 主处理 2. update 画面更新 3. call_battle 调用战斗 4. call shop 调用商店 5. call_name 调用名称输入 6. call_menu 调用菜单 7. call_save 调用存档 8. call_debug 调用Debug画面 9. transfer_player 角色移动
看了看,我们需要的只有 main 和 update。 Update 太长了,先跳过不看,把main的部分复制到我们的脚本里面,贴在 class Scene_Map 和 end 中间。 注意!! 养成一个好习惯,在每个end后面注释一下,因为end 用途太多,很容易忘了一个或多加一个。到时候出错了,要找出出错的部分会很难。所以我都在end 后面加一个注释, if 的end就加:# end if 条件 case 的end就加:# end case 条件 同理class 和def 的end 就加 # end class 类名称 和 # end def 方法名称 这样也有另一个好处,写教程的时候可以清楚表明在那个end 前后 本节相关脚本*下列脚本为了缩减篇幅,所以把中文部分注释删除了 class Scene_Map def main @spriteset = Spriteset_Map.new @message_window = Window_Message.new Graphics.transition loop do Graphics.update Input.update update if $scene != self break end # end if $scene != self end # end loop do Graphics.freeze @spriteset.dispose @message_window.dispose if $scene.is_a?(Scene_Title) Graphics.transition Graphics.freeze end # end if $scene.is_a?(Scene_Title) end # end def main end # end class Scene_Map 第二节 窗口部分(一)「窗口调用与显示文字」 注意:下面的坐标都是事先调整好的,如果要把窗口和文字方在你喜欢的地方,需要自己测试坐标。 不用说,当然是在 $Window_Time_Date 到 end 之间填写。 def initialize super(0, 0, 640, 55) self.contents = Bitmap.new(width - 32, height - 32) refresh end # end def initialize
def refresh end # end def refresh
def update end # end def update 这样就定义了一个最简单的窗口,super 是从Window_Base继承来的方法,定义窗口的X坐标、Y坐标、长与宽。self.contents = Bitmap.new(width -32, height - 32) 绘制一个文本框,由于窗口边缘与窗口背景并非一起绘制(可以从窗口素材看出),因此边缘会把文字挡住,这就是为何长宽要各减32的原因。
但是当我们进入游戏时,却没看到窗口出现。为什么呢? 因为我们在Scene_Map里面没有调用它。 来到Scene_Map 部分,在main里面 @message_window 下面一行加上 @time_date_window = Window_Time_Date.new 这行能调用出一个窗口。这时候我们再进入游戏,窗口已经出现了。
但是进入菜单,选择「离开游戏」之后会发现窗口竟然没消失!?(其实在菜单、物品等场景中也没消失,只是看不到而已。离开游戏的场景空白区域比较大,才会看的到。) 为了防止窗口在离开地图画面时没消失,在@message_window.dispose下面加上 @time_date_window.dispose 这行能将窗口dispose掉,dispose就是释放的意思。 但是为什么窗口里没东西呢?废话,我们什么都没加,当然什么也没有。
在 def refresh 下面加上 self.contents.draw_text(5, -5, 128, 32, “第一年”) 我们会发现在 ” ” 之间的字会变成紫色的,这就是会被显示在窗口中的文字。 进入游戏,就会看到窗口中多了「第一年」三个字 注意!!是contents 不是content 千万不要少打s(因为我经常会打错 囧)
皆下来在「第一年」的下面接上以下四行: self.contents.draw_text(80, -5, 128, 32, “一月”) self.contents.draw_text(125, -5, 128, 32, “一日”) self.contents.draw_text(185, -5, 128, 32, “子时”) self.contents.draw_text(230, -5, 128, 32, “初刻”) 进入游戏之后就会发现这些字都出现了。 但是全部都死死的不会动。不对啊?这是时间日期窗口,时间应该要会动才对。 所以接下来就是下一节:「时间计算」 本节相关脚本
class Window_Time_Date < Window_Base def initialize super(0, 0, 640, 55) self.contents = Bitmap.new(width - 32, height - 32) refresh end # end def initialize
def refresh self.contents.draw_text(5, -5, 128, 32,"第一年") self.contents.draw_text(80, -5, 128, 32, "一月") self.contents.draw_text(125, -5, 128, 32, "一日") self.contents.draw_text(185, -5, 128, 32, "子时") self.contents.draw_text(230, -5, 128, 32, "初刻") end # end def refresh def update end # end def update end 第三节 时间计算 首先先确定时间换算率。为了测试我们的时间系统,把刻的换算率定为2秒(40祯),时为2刻。一天2时,1月2天,一年2月。(一年32秒) 我们用变量来记录时间,这样可以从游戏中用条件分歧控制各种功能。 变量1、2、3、4、5:刻、时、日、月、年
在self.contents.draw_text(5, -5, 128, 32,"第一年")这行上面加上: @total_sec = Graphics.frame_count if @total_sec % 40 ==0 $game_variables[1] += 1 end
if $game_variables[1] >= 2 + 1 $game_variables[1] = 1 $game_variables[2] += 1 end
if $game_variables[2] >= 2 + 1 $game_variables[2] = 1 $game_variables[3] += 1 end
if $game_variables[3] >=2 + 1 $game_variables[3] = 1 $game_variables[4] += 1 end
if $game_variables[4] >= 2 + 1 $game_variables[4] = 1 $game_variables[5] += 1 end
第一段是说当祯数 = 40的倍数时,变量一 +1 第二段是说当变量一大于等于3时,变量二 + 1 ……依此类推 为什么用 2 + 1而不直接用3呢? 这是因为避免在算的时候搞错,所以直接用我们所定的2再加上1
好了,可以测试了。 打开游戏,上面窗口的文字却没变,这是因为我们文字现在是定死的,还要用变量控制才会变。先按F9打开debug画面,就能看到变量1、2、3、4、5在增加了。
怎么让窗口中的文字变化呢?用字符串数组。 先来修改「刻」 text_min = [“初刻”, “二刻”][$game_variables[1]] 然后把原本显示刻的文字 ”初刻” 改为 text_min变成这样 self.contents.draw_text(230, -5, 128, 32, text_min) 测试游戏,却发现两个问题: 1. 「刻」显示为「二刻」 2. 「刻」并没有跟着变量变化,而是停在「二刻」
第一个问题是因为「数组」的第一个「单元」是0, 而非1 所以我们在数组前面再加一个””, text_min = [“”, “初刻”, “二刻”][$game_variables[1]]
第二个问题是因为我们没有更新窗口文字的关系。 怎么更新呢?首先到Window_Time_Date中的update方法,在里面输入: super refresh 接着在Scene_Map中的update方法,输入 @time_date_window.update timedate_update 测试一下,成功了。「刻」在「初刻」「二刻」之间变换。 但是「刻」的文字却会便字却会变粗,而且「初刻」「二刻」会迭在一起。 这是因为我们没有清除原有文字的原因,在显示文字第一行,也就是 self.contents.draw_text(5, -5, 128, 32,"第一年")这行上面加上: self.contents.clear
皆下来用类似的方法改变其他时间变量,注意,是类似,不是完全一样。 text_min = [“”, “初刻”, “二刻”][$game_variables[1]] text_hour = [“”, “子时”, “丑时”][$game_variables[2]] text_day = [“”, “初一”, “初二”][$game_variables[3]] text_month = [“”, “一月”, “二月”][$game_variables[4]] text_year = [“”, “第一年”, “第二年”][$game_variables[5]]
self.contents.clear self.contents.draw_text(5, -5, 128, 32,text_year) self.contents.draw_text(80, -5, 128, 32, text_month) self.contents.draw_text(125, -5, 128, 32, text_day) self.contents.draw_text(185, -5, 128, 32, text_hour) self.contents.draw_text(230, -5, 128, 32, text_min)
下一节:窗口部分(二)「窗口文字初始化和排版」 第四节 窗口部分(二)「窗口文字初始化和排版」 上次在修改显示文字之后,会发现「刻」显示正常,「时」、「日」、「月」、「年」却一直到『轮到它们』的时候才出现。这是由于我们在脚本中没有初始化变量的原因,所以变量都从默认的0开始计算,而我们所设置的文字显示数组中,0显示为””。
要避面这种错误,就在initialize方法中初始化所有变量,在初始化的时候,你可以根据剧情把它们订为任何数字。本教程中把所有变量初始化为1。
在initialize中的refresh前面加上: $game_variables[1] = 1 $game_variables[2] = 1 $game_variables[3] = 1 $game_variables[4] = 1 $game_variables[5] = 1
现在变量的部分修改结束了,我们把时间换算率改正常一点。(不然一年32秒太快了吧?) 刻 = 40祯 时 = 6刻 日 = 12时 月 = 30日 年 = 12月 数组的地方也修改好。 @total_sec = Graphics.frame_count if @total_sec % 40 ==0 $game_variables[1] += 1 end # end if @total_sec % 40 ==0 if $game_variables[1] >= 6 + 1 $game_variables[1] = 1 $game_variables[2] += 1 end # end if $game_variables[1] >= 6 + 1 if $game_variables[2] >= 12 + 1 $game_variables[2] = 1 $game_variables[3] += 1 end # end if $game_variables[2] >= 12 + 1 if $game_variables[3] >= 30 + 1 $game_variables[3] = 1 $game_variables[4] += 1 end # end if $game_variables[3] >= 30 + 1 if $game_variables[4] >= 12 + 1 $game_variables[4] = 1 $game_variables[5] += 1 end # end if $game_variables[4] >= 12 + 1 text_min = ["", "初刻", "二刻", "三刻", "四刻", "五刻", "六刻"][$game_variables[1]] text_hour = ["", "子时", "丑时", "寅时", "卯时", "辰时", "巳时", "午时", "未时", "申时", "酉时", "戌时", "亥时"][$game_variables[2]] text_day = ["", "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十", "二十一", "二十二", "二十三", "二十四", "二十五", "二十六", "二十七", "二十八", "二十九", "三十"][$game_variables[3]] text_month = ["", "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"][$game_variables[4]] text_year = ["", "第一年", "第二年"][$game_variables[5]] 注意!!为了增加脚本的可视度和可修改度,我在 , 后面换行。
是不是这样就结束了呢?No!! 把月份初始化为11,再测试游戏。囧,为什么「月」字和「初」字会重迭呢? 因为「月」的文字坐标超过了「日」的坐标。其实解决方法有好几个,例如: 1. 把「十一」和「十二」打成半角的11和12。但是这样显的风格不协调。 2. 修改「日」的坐标,让它远离「月」。但是这样在正常的情况下会显的离得太远。 3. 修改「月」的文字宽度。但是这样显示起来不美观。 4. 「坐标加法排版法」,就是在一定情况下,把坐标加上一定数字。算法比较麻烦,而且也不适合我们现在用的字符串数组。用「坐标加法排版法」要用条件分歧比较好。 5. 「字符串加法排版法」,就是把一堆字符串全加在一起,最适合现在的情况。
字符串加法排版法就是把前面我们所定义的字符串通通加在一起,成为一个字符串。这个方法在全部的字符串都要横着排成一个长长的字符串的时候最有效的排版方法──譬如说现在。 怎么把字符串加起来呢?数字怎么加,字符串就怎么加。 在self.contents.clear前面加上 text_all = text_year + " " + text_month + " " + text_day + " " + text_hour + " " + text_min 注意中间的 ” “ 就是字符串间所留的空格。还有,记得把原来显示文字的脚本注释掉(如果不打算做更华丽的效果可以直接删掉。)再加上 self.contents.draw_text(5, -5, 640, 32, text_all) 好了,这样就算月份有十几个字也不会与日重迭(只是被挤到屏幕范围外而已=_=||) 到此为止,我们的时间系统已经略有小成。这个时间系统已经能显示游戏时间、显示时间窗口。但是从时间系统能衍生出更多的功能,像是昼夜、天气、星期。也可以在窗口上下功夫,例如隐藏窗口、窗口闪避、暂停时间、版面修改等。不需要那么多功能的人,到此就可以了。
下一节:窗口部分(三)「窗口文字──坐标加法排版」 |