Project1

标题: 一个无脑的问题,余烬之中的这个脚本怎么知道窗口编号? [打印本页]

作者: c123r123    时间: 2016-9-9 19:25
标题: 一个无脑的问题,余烬之中的这个脚本怎么知道窗口编号?
什么叫"新建窗口的时候生成一个编号 然后返回给【新增文本窗口】"?难道是执行那个方法,然后直接return编号?
RUBY 代码复制
  1. # 如何显示一个显示指定文字的窗口?要求文字能够在游戏中修改。
  2.  
  3. # 这个问题有点诡异啊:到底是在哪里显示呢?菜单?标题?存档界面?GameOver?……
  4. # (再唧唧歪歪就把你送给楼主做女仆)
  5. # 咳咳,我们假设这是要显示在地图上的 很显然 我们至少需要了解:
  6. #  位置(x, y)
  7. #  文本(text)
  8. # 鉴于默认窗口太丑,我们需要一个作为补充的图片背景功能:
  9. #  背景(background)
  10. # 允许设定的项 除了文本外 还有窗口的不透明度(opacity)
  11. # 窗口的大小就自适应文字吧 有背景图的话就固定为背景图的大小
  12.  
  13. # 我们的设想中 可以通过事件脚本来更改某窗口的文字
  14. # 还可以新建窗口 用两个窗口来显示文字 甚至三个四个好多个
  15.  
  16. # 因为各项参数都用事件脚本 所以我们不需要用模块进行设置了好可惜
  17.  
  18. # 一般而言 事件脚本调用的环境是Game_Interpreter内部 不要问我环境是什么
  19. # 反正保护环境 人人有责(我在说什么)
  20. #==============================================================================
  21. # ** Game_Interpreter
  22. #==============================================================================
  23. class Game_Interpreter
  24.   def 新增文本窗口(文本, 横坐标 = 0, 纵坐标 = 0, 背景图片 = "", 不透明度 = 255)
  25.     # 各种默认值就在上面设置完成 不需要玩家如何如何地设置
  26.     # 乖乖调用【新增文本窗口(...)】就可以了
  27.     SceneManager.scene.新增文本窗口(文本, 横坐标, 纵坐标, 背景图片, 不透明度)
  28.     # SceneManager.scene获取当前场景 一般是地图场景
  29.     # 后面这个方法 我们还没有在地图场景里面实现
  30.     # 但是不要紧了 反正后面会实现的
  31.   end
  32.   def 更改窗口文本(窗口编号, 文本 = "")
  33.     # 我怎么知道窗口编号?
  34.     # 很简单 新建窗口的时候生成一个编号 然后返回给【新增文本窗口】
  35.     # 让用户截取这个编号并保存 那不关我们的事
  36.     SceneManager.scene.更改窗口文本(窗口编号, 文本)
  37.   end
  38.   def 更改窗口位置(窗口编号, 横坐标 = 0, 纵坐标 = 0)
  39.     SceneManager.scene.更改窗口位置(窗口编号, 横坐标, 纵坐标)
  40.   end
  41.   def 更改窗口背景图片(窗口编号, 背景图片 = "")
  42.     SceneManager.scene.更改窗口背景图片(窗口编号, 背景图片)
  43.   end
  44.   def 更改窗口不透明度(窗口编号, 不透明度 = 255)
  45.     SceneManager.scene.更改窗口不透明度(窗口编号, 不透明度)
  46.   end
  47.   def 获取窗口信息(窗口编号)
  48.     # 应该返回一个数组:[文本, 背景图片, 不透明度]
  49.     SceneManager.scene.获取窗口信息(窗口编号)
  50.   end
  51.   def 删除窗口(窗口编号)
  52.     SceneManager.scene.删除窗口(窗口编号)
  53.   end
  54.   def 暂时关闭窗口(窗口编号)
  55.     SceneManager.scene.暂时关闭窗口(窗口编号)
  56.   end
  57.   def 暂时打开窗口(窗口编号)
  58.     SceneManager.scene.暂时打开窗口(窗口编号)
  59.   end
  60. end
  61.  
  62. # 但是我们的窗口连影子都没有
  63. # 开工了伙计们
  64. class Window_ShowTextOnMap < Window_Base # 果然还是继承Base吧
  65.   def initialize(text, x, y, back, opa)
  66.     @text, @back, @opa = text, back, opa
  67.     if @back == ""
  68.       super(x, y, *get_width_and_height) #不使用背景图片 自适应文字
  69.       self.opacity = @opa
  70.     else
  71.       pic = Cache.picture(@back) # Cache.picture访问的是Graphics/Picture文件夹
  72.       super(x, y, pic.width, pic.height) # 使用背景图片 根据图片来
  73.       self.back_opacity = 0
  74.       self.contents_opacity = @opa
  75.     end
  76.     # get_width_and_height是一个不存在的方法 我们将要实现它
  77.     # 使它返回文本合适的宽与高(以数组的形式)
  78.     # 前面加一个*号 目的是将数组展开 因为super呼叫父类方法 在这里要四个参数
  79.     refresh
  80.     # 描绘文字
  81.   end
  82.  
  83.   # 获取合适的宽与高 允许使用控制符 比如\I[3] \n \V[6]
  84.   # 原理: 新建一个临时窗口 画一遍 观测绘制的范围 就知道合适的宽与高了
  85.   def get_width_and_height
  86.     tmp = Window_Base.new(Graphics.width, 0, Graphics.width, 1)
  87.     # 新建临时窗口
  88.     tmp.reset_font_settings
  89.     # 重置字体设置
  90.     width = 0
  91.     # 记录宽度
  92.     pos = {x: 0, y: 0, height: tmp.calc_line_height(@text)}
  93.     # 当前描绘的位置
  94.     @text.each_line do |s| # 逐行描绘
  95.       # s.gsub!(/[\n]/){""} # 去除尾部的换行符 理论上可以用chomp!代替
  96.       s.chomp! # 我想我们还是用更拉风的chomp!吧
  97.       tmp.process_character(s.slice!(0, 1), s, pos) until s.empty? # 逐字描绘
  98.       width = [pos[:x], width].max # 获取单行的宽度 记录最大值
  99.       pos[:x] = 0 # 换行
  100.       pos[:y] += pos[:height] # 换行
  101.       pos[:height] = tmp.calc_line_height s #确定合适高度
  102.       # 循环描绘下一行
  103.     end
  104.     # 没有手动对tmp进行dispose 因为它在窗口外 看不到 而且tmp作用域要消失了
  105.     #  很快就会被GC弄死 这里不需要理解
  106.     [width + standard_padding * 2, pos[:y] + standard_padding * 2] # 返回宽高
  107.   end
  108.  
  109.   # 进行实际的描绘
  110.   def refresh
  111.     contents.clear
  112.     pic = Cache.picture(@back)
  113.     contents.blt(0, 0, pic, Rect.new(0, 0, pic.width, pic.height))
  114.     draw_text_ex(0, 0, @text)
  115.   end
  116.  
  117.   # 改变文字
  118.   def set_text(text)
  119.     @text = text
  120.     refresh
  121.   end
  122.  
  123.   # 位置
  124.   def set_pos(x, y)
  125.     self.x, self.y = x, y
  126.   end
  127.  
  128.   # 背景图片
  129.   def set_back(back)
  130.     return if @back == back
  131.     @back = back
  132.     if @back == ""
  133.       self.move(self.x, self.y, *get_width_and_height)
  134.       self.opacity = @opa
  135.     else
  136.       pic = Cache.picture(@back)
  137.       self.move(self.x, self.y, pic.width, pic.height)
  138.       self.back_opacity = 0
  139.       self.contents_opacity = @opa
  140.     end
  141.     refresh
  142.   end
  143.  
  144.   # 不透明度
  145.   def set_opa(opa)
  146.     @opa = opa
  147.     if @back == ""
  148.       self.opacity = @opa
  149.     else
  150.       self.contents_opacity = @opa
  151.     end
  152.   end
  153.  
  154.   # 获取信息
  155.   def get_info
  156.     [@text, @back, @opa]
  157.   end
  158. end
  159.  
  160. # 好无聊 累死了 不想写了 就这样吧
  161. # ………………
  162. # 为了不做楼主女仆 我还是继续吧
  163.  
  164. # 我们已经完成了一个【入口】 可以接受事件脚本信息 但是还没有人来处理
  165. # 我们已经完成了一个【窗口】 可以在地图上显示文本 但是还没有人来管理
  166. # 所有的事实都指向一个结果 真相只有一个!
  167.  
  168. class Scene_Map
  169.   # 首先 在开始的时候地图场景会建立一系列窗口
  170.   # 我们把我们的窗口混进去一起建立…………不需要一次性建好 放个名单就行
  171.   # 在方法create_all_windows中
  172.   alias :我要往你里面塞一点东西哦_create_all_windows君 :create_all_windows
  173.   def create_all_windows
  174.     我要往你里面塞一点东西哦_create_all_windows君
  175.     我要塞的东西之一
  176.   end
  177.  
  178.   def 我要塞的东西之一
  179.     @显示文本的窗口们 = []
  180.   end
  181.  
  182.   def 新增文本窗口(text, x, y, back, opa)
  183.     @显示文本的窗口们.push(Window_ShowTextOnMap.new(text, x, y, back, opa))
  184.     @显示文本的窗口们.size - 1 # 这就是返回的窗口编号啦
  185.   end
  186.  
  187.   def 更改窗口文本(id, text)
  188.     @显示文本的窗口们[id].set_text(text)
  189.   end
  190.  
  191.   def 更改窗口位置(id, x, y)
  192.     @显示文本的窗口们[id].set_pos(x, y)
  193.   end
  194.  
  195.   def 更改窗口背景图片(id, back)
  196.     @显示文本的窗口们[id].set_back(back)
  197.   end
  198.  
  199.   def 更改窗口不透明度(id, opa = 255)
  200.     @显示文本的窗口们[id].set_opa(opa)
  201.   end
  202.  
  203.   def 获取窗口信息(id)
  204.     @显示文本的窗口们[id].get_info
  205.   end
  206.  
  207.   def 删除窗口(id)
  208.     @显示文本的窗口们[id].dispose
  209.   end
  210.  
  211.   def 暂时关闭窗口(id)
  212.     @显示文本的窗口们[id].close if @显示文本的窗口们[id].open?
  213.   end
  214.  
  215.   def 暂时打开窗口(id)
  216.     @显示文本的窗口们[id].open if @显示文本的窗口们[id].close?
  217.   end
  218.  
  219.   # 很好 虽然这种重复冗余令人难以置信 但是完成了不是吗?元编程去死吧!
  220.  
  221.   # 等等 我们是不是忘了什么?
  222.  
  223.   # 更新!update!释放!dispose!
  224.   alias :我也要往你里面塞一点东西哦_update_all_windows君 :update_all_windows
  225.   def update_all_windows
  226.     我也要往你里面塞一点东西哦_update_all_windows君
  227.     我要塞的东西之二
  228.   end
  229.  
  230.   def 我要塞的东西之二
  231.     @显示文本的窗口们.each{|x| x.update unless x.disposed?}
  232.   end
  233.  
  234.   alias :我还要往你里面塞一点东西哦_dispose_all_windows君 :dispose_all_windows
  235.   def dispose_all_windows
  236.     我还要往你里面塞一点东西哦_dispose_all_windows君
  237.     我要塞的东西之三
  238.   end
  239.  
  240.   def 我要塞的东西之三
  241.     @显示文本的窗口们.each{|x| x.dispose unless x.disposed?}
  242.   end
  243. end
  244. # 完美!
  245.  
  246. # 照例装逼化
  247.  
  248. __END__
  249.  
  250. #==============================================================================
  251. # ** Game_Interpreter
  252. #==============================================================================
  253. class Game_Interpreter
  254.   def new_text_window(text, x = 0, y = 0, back = "", opa = 255)
  255.     SceneManager.scene.new_text_window(text, x, y, back, opa)
  256.   end
  257.   def delete_text_window(id)
  258.     SceneManager.scene.delete_text_window(id)
  259.   end
  260.   def close_text_window(id)
  261.     SceneManager.scene.close_text_window(id)
  262.   end
  263.   def open_text_window(id)
  264.     SceneManager.scene.open_text_window(id)
  265.   end
  266.   def text_window_set_text(id, text = "")
  267.     SceneManager.scene.text_window_set_text(id, text)
  268.   end
  269.   def text_window_set_pos(id, x = 0, y = 0)
  270.     SceneManager.scene.text_window_set_pos(id, x, y)
  271.   end
  272.   def text_window_set_back(id, back = "")
  273.     SceneManager.scene.text_window_set_back(id, back)
  274.   end
  275.   def text_window_set_opa(id, opa = 255)
  276.     SceneManager.scene.text_window_set_opa(id, opa)
  277.   end
  278.   def text_window_get_info(id)
  279.     SceneManager.scene.text_window_get_info(id)
  280.   end
  281. end
  282. #==============================================================================
  283. # ** Window_ShowTextOnMap
  284. #==============================================================================
  285. class Window_ShowTextOnMap < Window_Base
  286.   def initialize(text, x, y, back, opa)
  287.     @text, @back, @opa = text, back, opa
  288.     if @back.empty?
  289.       super(x, y, *get_width_and_height)
  290.       self.opacity = @opa
  291.     else
  292.       pic = Cache.picture(@back)
  293.       super(x, y, pic.width, pic.height)
  294.       self.back_opacity = 0
  295.       self.contents_opacity = @opa
  296.     end
  297.     refresh
  298.   end
  299.  
  300.   def get_width_and_height
  301.     tmp = Window_Base.new(Graphics.width, 0, Graphics.width, 1)
  302.     tmp.reset_font_settings
  303.     width = 0
  304.     pos = {x: 0, y: 0, height: tmp.calc_line_height(@text)}
  305.     @text.each_line do |s|
  306.       s.chomp!
  307.       tmp.process_character(s.slice!(0, 1), s, pos) until s.empty?
  308.       width = [pos[:x], width].max
  309.       pos[:x] = 0
  310.       pos[:y] += pos[:height]
  311.       pos[:height] = tmp.calc_line_height s
  312.     end
  313.     [width + standard_padding * 2, pos[:y] + standard_padding * 2]
  314.   end
  315.  
  316.   def refresh
  317.     contents.clear
  318.     pic = Cache.picture(@back)
  319.     contents.blt(0, 0, pic, Rect.new(0, 0, pic.width, pic.height))
  320.     draw_text_ex(0, 0, @text)
  321.   end
  322.  
  323.   def set_text(text)
  324.     @text = text
  325.     refresh
  326.   end
  327.  
  328.   def set_pos(x, y)
  329.     self.x, self.y = x, y
  330.   end
  331.  
  332.   def set_back(back)
  333.     return if @back == back
  334.     @back = back
  335.     if @back.empty?
  336.       self.move(self.x, self.y, *get_width_and_height)
  337.       self.opacity = @opa
  338.     else
  339.       pic = Cache.picture(@back)
  340.       self.move(self.x, self.y, pic.width, pic.height)
  341.       self.back_opacity = 0
  342.       self.contents_opacity = @opa
  343.     end
  344.     refresh
  345.   end
  346.  
  347.   def set_opa(opa)
  348.     @opa = opa
  349.     if @back == ""
  350.       self.opacity = @opa
  351.     else
  352.       self.contents_opacity = @opa
  353.     end
  354.   end
  355.  
  356.   def get_info
  357.     [@text, @back, @opa]
  358.   end
  359. end
  360. #==============================================================================
  361. # ** Scene_Map
  362. #==============================================================================
  363. class Scene_Map
  364.   alias :text_window_create_all_windows :create_all_windows
  365.   def create_all_windows
  366.     text_window_create_all_windows
  367.     create_text_windows
  368.   end
  369.  
  370.   def create_text_windows
  371.     @text_windows = []
  372.   end
  373.  
  374.   alias :text_window_update_all_windows :update_all_windows
  375.   def update_all_windows
  376.     text_window_update_all_windows
  377.     update_text_windows
  378.   end
  379.  
  380.   def update_text_windows
  381.     @text_windows.each{|x| x.update unless x.disposed?}
  382.   end
  383.  
  384.   alias :text_window_dispose_all_windows :dispose_all_windows
  385.   def dispose_all_windows
  386.     text_window_dispose_all_windows
  387.     dispose_text_windows
  388.   end
  389.  
  390.   def dispose_text_windows
  391.     @text_windows.each{|x| x.dispose unless x.disposed?}
  392.   end
  393.  
  394.   def new_text_window(*args)
  395.     @text_windows.push Window_ShowTextOnMap.new(*args)
  396.     @text_windows.size - 1
  397.   end
  398.  
  399.   def delete_text_window(id)
  400.     @text_windows[id].dispose
  401.   end
  402.  
  403.   def close_text_window(id)
  404.     @text_windows[id].close if @text_windows[id].open?
  405.   end
  406.  
  407.   def open_text_window(id)
  408.     @text_windows[id].open if @text_windows[id].close?
  409.   end
  410.  
  411.   def text_window_set_text(id, text)
  412.     @text_windows[id].set_text(text)
  413.   end
  414.  
  415.   def text_window_set_pos(id, x, y)
  416.     @text_windows[id].set_pos(x, y)
  417.   end
  418.  
  419.   def text_window_set_back(id, back)
  420.     @text_windows[id].set_back(back)
  421.   end
  422.  
  423.   def text_window_set_opa(id, opa = 255)
  424.     @text_windows[id].set_opa(opa)
  425.   end
  426.  
  427.   def text_window_get_info(id)
  428.     @text_windows[id].get_info
  429.   end
  430. end

作者: 喵呜喵5    时间: 2016-9-9 20:09
执行 新增文本窗口 这个方法的时候返回值是该窗口的一个编号(ID、句柄……),用于在其他操作窗口的方法中调用这个窗口
作者: 喵呜喵5    时间: 2016-9-10 17:20
你创建窗口的时候的返回值就是一个编号,你可以直接
  1. $game_variables[1] = 新增文本窗口(参数)
复制代码

1 号变量就是窗口的变好了




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1