查看: 5966|回复: 8

[已经解决] 怎样在Window里调用self.dispose呢???

[复制链接]
梦石
0
星屑
29901
在线时间
5734 小时
注册时间
2016-3-8
回帖
1653
发表于 2021-3-9 10:40:45 | 显示全部楼层 |阅读模式
悬赏77星屑已解决
本帖最后由 alexncf125 于 2021-3-9 10:48 编辑

这个显示弹幕的脚本可以在149行当@over为true时调用close(self.dispose)
显示弹幕的脚本[pre lang="ruby"]=begin
    #==============================================================================
    # ■ 显示弹幕 V1.1
    #------------------------------------------------------------------------------
    #  在任意场景显示弹幕。
    #==============================================================================
      #----------------------------------------------------------------------------
      # ● 作者
      #----------------------------------------------------------------------------
      rpg-sheep(小优)
      #----------------------------------------------------------------------------
      # ● 原创度
      #----------------------------------------------------------------------------
      100%
      #----------------------------------------------------------------------------
      # ● 使用方法
      #----------------------------------------------------------------------------
      RS::Biu.start(speed) 以每帧speed个像素向左移动的速度开启弹幕。
        注意:重复调用会导致上一个start的弹幕立即消失,没有什么太大影响。
        参数:speed:移动速度,单位为像素,即每帧(1/60)秒移动speed个像素。
        例子:RS::Biu.start(5) # 以每秒5 * 60 = 300像素的速度移动。
      RS::Biu.send(text, up, down, y)在已经start的情况下立即输出一段弹幕。
        注意:如果没有正在start的弹幕,什么都不会发生。
        参数:text:要输出的文字,允许使用\\C[9]这样的代码。
              up:上边距。如不填默认为50。
              down:下边距。如不填默认为50。
              y:弹幕显示的y坐标。如不填则根据up和down随机取值,如填则为定值。
        例子:RS::Biu.send("小优很萌") # 随机在上边距50~下边距50内输出“小优很萌”。
      RS::Biu.send_b(index, up, down, y) 同上,只是从数据库里调用。index是数据库的第几个。
      RS::Biu.over 结束弹幕的滚动以释放内存。调用这个方法后会等待弹幕移动结束再关闭。
        注意:调用over后就不可以使用send方法了。除非新start。
                  弹幕的运行不会耗费太大的内存。所以不用每次发完弹幕后都调用over。
      #----------------------------------------------------------------------------
      # ● 使用条例
      #----------------------------------------------------------------------------
      作为rpg-sheep的100%原创脚本:
      可以在非商业作品中自由使用及修改。(遵守FSL协议)
      禁止在商业作品中使用,禁止修改本脚本后发布。
     
=end
     
    #==============================================================================
    # ■ RS
    #------------------------------------------------------------------------------
    #  rpg-sheep的超类
    #==============================================================================
    module RS
    end
    $window_biu = []
    #==============================================================================
    # ■ Biu
    #------------------------------------------------------------------------------
    #  弹幕类
    #==============================================================================
    module RS::Biu
      #--------------------------------------------------------------------------
      # ● 开始
      #--------------------------------------------------------------------------
      def self.start(speed)
        $window_biu[0].close if $window_biu[0] && !$window_biu[0].disposed?
        $window_biu[1].close if $window_biu[1] && !$window_biu[1].disposed?
        $window_biu[2].close if $window_biu[2] && !$window_biu[2].disposed?
        $window_biu[0] = Window_Biu.new(speed)
        $window_biu[1] = Window_Biu.new(speed)
        $window_biu[2] = Window_Biu.new(speed)
      end
      #--------------------------------------------------------------------------
      # ● 发送
      #--------------------------------------------------------------------------
      def self.send(text, up = 50, down = 50, y = rand(Graphics.height - up - down - 24) + up)
        $window_biu[0].add(text, y) if $window_biu[0] && !$window_biu[0].disposed? && $window_biu[0].x > 0
        $window_biu[1].add(text, y) if $window_biu[1] && !$window_biu[1].disposed? && $window_biu[1].x > 0 && $window_biu[0].update?
        $window_biu[2].add(text, y) if $window_biu[2] && !$window_biu[2].disposed? && $window_biu[2].x > 0 && $window_biu[1].update?
      end
      #--------------------------------------------------------------------------
      # ● 发送(从数据库)
      #--------------------------------------------------------------------------
      def self.send_b(index, up = 50, down = 50, y = rand(Graphics.height - up - down - 24) + up)
        $window_biu[0].add(biulist(index), y) if $window_biu[0] && !$window_biu[0].disposed? && $window_biu[0].x > 0
        $window_biu[1].add(biulist(index), y) if $window_biu[1] && !$window_biu[1].disposed? && $window_biu[1].x > 0 && $window_biu[0].update?
        $window_biu[2].add(biulist(index), y) if $window_biu[2] && !$window_biu[2].disposed? && $window_biu[2].x > 0 && $window_biu[1].update?
      end
      #--------------------------------------------------------------------------
      # ● 结束
      #--------------------------------------------------------------------------
      def self.over
        $window_biu[0].over
        $window_biu[1].over
        $window_biu[2].over
      end
      #--------------------------------------------------------------------------
      # ● 弹幕列表
      #   (index, 内容)
      #   index: 随便写,主要是为了当弹幕多的时候,可以分清需要哪一个。我建议每个10个空一行什么的
      #--------------------------------------------------------------------------
      def self.biulist(index)
        @biu_list = [
          [0, "为啥小优最\\{萌\\}"], # 前面要加逗号
          [1, "\\C[6]Yoooooooooooooooooo~"] # 最后一行可以不加逗号
        ]
        index < @biu_list.size ? temp = index : temp = @biu_list.size
        return @biu_list[temp][1]
      end
    end
    #==============================================================================
    # ■ Window_Biu
    #------------------------------------------------------------------------------
    #  显示弹幕的窗口
    #==============================================================================
    class Window_Biu < Window_Base
      #----------------------------------------------------------------------------
      # ● 初始化
      #----------------------------------------------------------------------------
      def initialize(speed)
        @update = false
        @over = false
        @speed = speed
                    super(0, 0, 2 * Graphics.width, Graphics.height)
        self.opacity = 0
        self.x = Graphics.width
        self.z = 1000
        create_contents
      end
      #--------------------------------------------------------------------------
      # ● 获取标准的边距尺寸
      #--------------------------------------------------------------------------
      def standard_padding
        return 0
      end
      #--------------------------------------------------------------------------
      # ● 更新?
      #--------------------------------------------------------------------------
      def update?
        @update
      end
      #--------------------------------------------------------------------------
      # ● 更新内容
      #--------------------------------------------------------------------------
      def update
        super
        self.x -= @speed
        if self.x <= 0
          @update = true
        end
        if self.x <= (0 - (2 * Graphics.width))
          self.x = Graphics.width
          clear
          if @over
            close
          end
        end
      end
      #--------------------------------------------------------------------------
      # ● 清除
      #--------------------------------------------------------------------------
      def clear
        contents.clear
      end
      #--------------------------------------------------------------------------
      # ● 增加内容
      #--------------------------------------------------------------------------
      def add(text, y)
        draw_text_ex(Graphics.width - self.x, y, text)
      end
      #--------------------------------------------------------------------------
      # ● 结束
      #--------------------------------------------------------------------------
      def over
        @over = true
      end
      #--------------------------------------------------------------------------
      # ● 关闭
      #--------------------------------------------------------------------------
      def close
        self.dispose
        @over = false
      end
     
    end
     
    class Scene_Base
      #--------------------------------------------------------------------------
      # ● 更新画面
      #--------------------------------------------------------------------------
      alias old_update update
      def update
        old_update
        if $window_biu
          $window_biu[0].update if $window_biu[0] && !$window_biu[0].disposed?
          $window_biu[1].update if $window_biu[1] && $window_biu[0].update? && !$window_biu[1].disposed?
          $window_biu[2].update if $window_biu[2] && $window_biu[1].update? && !$window_biu[2].disposed?
        end
      end
     
    end[/pre]

那为什么下方这个脚本不能在77-78行或81-82行间插句self.dispose if @show_count == 0呢,
插了的话, 123号变量为1时, 会在场所移动后一两秒(应该是@show_count == 0)时报错disposed window[pre lang="ruby"]# encoding: utf-8
#==============================================================================
# ** Window_MapNamePlus
#------------------------------------------------------------------------------
#  This window displays the map name.
#------------------------------------------------------------------------------
#  使用方法:
#    新建脚本页,复制粘贴
#    在“Scene_Map”中找到“Window_MapName.new”,改成"Window_MapNamePlus.new"(大概在
#     159行左右)
#    在地图属性的设置窗口,“显示名称”中的地图名格式:“中文名@EnglishName”,即用“@”分割中文
#     和英文地图名
#==============================================================================

class Window_MapNamePlus < Window_Base
  #--------------------------------------------------------------------------
  # * Settings
  #--------------------------------------------------------------------------
  FONT_NAME_CH = ["PMingLiU", "FangSong"]       # Chinese Font Name
  FONT_SIZE_CH = 42                             # Chinese Font Size
  FONT_NAME_EN = ["Monotype Corsiva"]           # English Font Name
  FONT_SIZE_EN = 28                             # English Font Size
  FONT_BOLD    = false                          # True if Font in Bold
  FONT_COLOR   = Color.new(255, 255, 255, 255)  # Color of Font
  FONT_OUT     = true                           # True if Font Has Outline
  OUT_COLOR    = Color.new(0, 0, 0, 200)        # Color of Outline Color of Font
  FONT_SHADOW  = false                          # True if Text Drops Shadow
  MODIFIER     = "~"                            # Modifier Added beside Map Name
  PADDING      = 8                              # Padding between Window's Frame and Contents
  LINE_HEIGHT  = 6                              # Height of Split Line
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_reader :map_name_ch                      # Chinese Map Name
  attr_reader :map_name_en                      # English Map Name
  attr_reader :line_x                           # Split Line X Coordinate
  attr_reader :line_y                           # Split Line Y Coordinate
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    #----------------------------------------------------------------------
    # * Set the window in the middle of screen.
    #----------------------------------------------------------------------
    super(((Graphics.width - window_width) / 2),
      ((Graphics.height - (FONT_SIZE_CH + FONT_SIZE_EN + PADDING * 4 + LINE_HEIGHT)) / 2),
      window_width, FONT_SIZE_CH + FONT_SIZE_EN + PADDING * 4 + LINE_HEIGHT)
    #----------------------------------------------------------------------
    # * Custom font and style.
    #----------------------------------------------------------------------
    contents.font.bold      = FONT_BOLD
    contents.font.color     = FONT_COLOR
    contents.font.outline   = FONT_OUT
    contents.font.out_color = OUT_COLOR
    contents.font.shadow    = FONT_SHADOW
    #----------------------------------------------------------------------
    # * Set Window Opacity
    #----------------------------------------------------------------------
    self.opacity = 0
    self.contents_opacity = 0
    @show_count = 0
    refresh
  end
  #--------------------------------------------------------------------------
  # * Get Window Width
  #--------------------------------------------------------------------------
  def window_width
    return Graphics.width
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    if @show_count > 0 && $game_map.name_display
      update_fadein
      @show_count -= 1
    else
      update_fadeout
    end
    @show_count = 0 unless $game_map.name_display##########
  end
  #--------------------------------------------------------------------------
  # * Update Fadein
  #--------------------------------------------------------------------------
  def update_fadein
    self.contents_opacity += 16
  end
  #--------------------------------------------------------------------------
  # * Update Fadeout
  #--------------------------------------------------------------------------
  def update_fadeout
    self.contents_opacity -= 16
  end
  #--------------------------------------------------------------------------
  # * Open Window
  #--------------------------------------------------------------------------
  def open
    refresh
    @show_count = 150
    self.contents_opacity = 0
    self
  end
  #--------------------------------------------------------------------------
  # * Close Window
  #--------------------------------------------------------------------------
  def close
    @show_count = 0
    self
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    contents.clear
    set_map_name
    unless $game_map.display_name.empty?
      draw_map_name
    end
  end
  #--------------------------------------------------------------------------
  # * Draw Line
  #--------------------------------------------------------------------------
  def draw_line(rect)
    temp_rect = rect.clone
    temp_rect.height = LINE_HEIGHT
    temp_rect.width /= 4
    contents.gradient_fill_rect(temp_rect, color2, color1)
    temp_rect.x += temp_rect.width
    temp_rect.width *= 2
    contents.fill_rect(temp_rect, color1)
    temp_rect.x += temp_rect.width
    temp_rect.width /= 2
    contents.gradient_fill_rect(temp_rect, color1, color2)
  end
  #--------------------------------------------------------------------------
  # * Set Map Name
  #--------------------------------------------------------------------------
  def set_map_name
#~     temp_map_name = $game_map.display_name.split("@")
#~     @map_name_ch  = temp_map_name[0].to_s
#~     @map_name_en  = MODIFIER + " " + temp_map_name[1].to_s + " " + MODIFIER
    ##########
    @map_name_ch  = nil ; @map_name_en  = nil
    $game_map.note.scan(/<第一行:(.*)>/){|matched|@map_name_cn = matched[0]}
    @map_name_ch  = @map_name_cn || $game_map.display_name
    $game_map.note.scan(/<第二行:(.*)>/){|matched|@map_name_en = matched[0]}
    @map_name_en  = MODIFIER + " " + (@map_name_en || "作者未填写地图简介") + " " + MODIFIER
    ##########
  end
  #--------------------------------------------------------------------------
  # * Draw Map Name
  #--------------------------------------------------------------------------
  def draw_map_name
    set_line_position
    set_line_width
    temp_line_rect = Rect.new(@line_x, @line_y, set_line_width, LINE_HEIGHT)
    draw_line(temp_line_rect)
    temp_name_rect_ch = Rect.new(0, 0, contents.width, FONT_SIZE_CH)
    contents.font.name = FONT_NAME_CH
    contents.font.size = FONT_SIZE_CH
    draw_text(temp_name_rect_ch, @map_name_ch, 1)
    temp_name_rect_en = Rect.new(0, FONT_SIZE_CH, contents.width, FONT_SIZE_EN)
    contents.font.size = FONT_SIZE_EN
    contents.font.name = FONT_NAME_EN
    draw_text(temp_name_rect_en, @map_name_en, 1)
  end
  #--------------------------------------------------------------------------
  # * Set Line Width
  #--------------------------------------------------------------------------
  def set_line_width
    text_width_ch = text_size(@map_name_ch).width * 1.5
    text_width_en = text_size(@map_name_en).width * 1.5
    (text_width_ch >= text_width_en) ?
      (text_width_ch) : (text_width_en)
  end
  #--------------------------------------------------------------------------
  # * Set Line Position
  #--------------------------------------------------------------------------
  def set_line_position
    @line_x = (contents.width - set_line_width) / 2
    @line_y = (contents.height - LINE_HEIGHT) / 2
  end
  #--------------------------------------------------------------------------
  # * Get Color 1
  #--------------------------------------------------------------------------
  def color1
    Color.new(255, 255, 255, 255)
  end
  #--------------------------------------------------------------------------
  # * Get Color 2
  #--------------------------------------------------------------------------
  def color2
    Color.new(255, 255, 255, 0)
  end
end

##########
module MAPNAMEPLUS
  VAR_ID = 123##########變量
end

#==============================================================================
# ** Game_Map
#------------------------------------------------------------------------------
#  This class handles maps. It includes scrolling and passage determination
# functions. The instance of this class is referenced by $game_map.
#==============================================================================

class Game_Map
  #--------------------------------------------------------------------------
  # * New method: note
  #--------------------------------------------------------------------------
  def note
    @map ? @map.note : ""
  end
end

#encoding:utf-8
#==============================================================================
# ■ Window_MapName
#------------------------------------------------------------------------------
#  顯示地圖名稱的窗口。
#==============================================================================

class Window_MapName < Window_Base
  #--------------------------------------------------------------------------
  # ● 打開窗口
  #--------------------------------------------------------------------------
  alias :window_mapname_open_map_name_plus :open
  def open
    return if $game_variables[MAPNAMEPLUS::VAR_ID] >= 2
    window_mapname_open_map_name_plus
  end
  #--------------------------------------------------------------------------
  # ● 關閉窗口
  #--------------------------------------------------------------------------
  alias :window_mapname_close_map_name_plus :close
  def close
    return if $game_variables[MAPNAMEPLUS::VAR_ID] >= 2
    window_mapname_close_map_name_plus
  end
end

#encoding:utf-8
#==============================================================================
# ■ Scene_Map
#------------------------------------------------------------------------------
#  地圖畫面
#==============================================================================

class Scene_Map < Scene_Base
  #--------------------------------------------------------------------------
  # ● 結束前處理
  #--------------------------------------------------------------------------
  alias :scene_map_pre_terminate_map_name_plus :pre_terminate
  def pre_terminate
    scene_map_pre_terminate_map_name_plus
    @map_name_plus_window.dispose if @map_name_plus_window && !@map_name_plus_window.disposed?
    @map_name_plus_window = nil
  end
  #--------------------------------------------------------------------------
  # ● 場所移動前的處理
  #--------------------------------------------------------------------------
  alias :scene_map_pre_transfer_map_name_plus :pre_transfer
  def pre_transfer
    @map_name_plus_window.close if @map_name_plus_window
    scene_map_pre_transfer_map_name_plus
  end
  #--------------------------------------------------------------------------
  # ● 場所移動后的處理
  #--------------------------------------------------------------------------
  alias :scene_map_post_transfer_map_name_plus :post_transfer
  def post_transfer
    scene_map_post_transfer_map_name_plus
    var_value = $game_variables[MAPNAMEPLUS::VAR_ID]
    case var_value
    when 1, 2
      @map_name_plus_window = Window_MapNamePlus.new unless @map_name_plus_window
    end
    @map_name_plus_window.open if @map_name_plus_window
  end
end
##########[/pre]

最佳答案

查看完整内容

不好意思,其实我忘了看第二个脚本( 你这个窗口是绑定在Scene里面的一个实例变量,不需要自己释放了 因为Scene_Base里面会统一更新、释放是窗口的实例变量 具体可以看类里面的 dispose_windows 这是一种元编程模式,默认的那些窗口也都没有再写额外的更新和释放 以及如果只是单纯想让它不再显示,推荐用 window 类继承下来的 hide 和 show 方法 如果想刷新内容,推荐不要用生成、释放的模式,而是用它的 refresh ...

老鹰

梦石
40
星屑
37812
在线时间
7091 小时
注册时间
2012-5-26
回帖
3297

极短24评委极短23参与极短22参与极短21评委老司机慢点开短篇十吟唱者组别冠军开拓者剧作品鉴家

发表于 2021-3-9 10:40:46 | 显示全部楼层
本帖最后由 百里_飞柳 于 2021-3-9 12:59 编辑
alexncf125 发表于 2021-3-9 11:43
============================================================

这句是指, 在Scene_Map的def update內加 ...


不好意思,其实我忘了看第二个脚本(

你这个窗口是绑定在Scene里面的一个实例变量,不需要自己释放了
因为Scene_Base里面会统一更新、释放是窗口的实例变量
具体可以看类里面的 dispose_windows

这是一种元编程模式,默认的那些窗口也都没有再写额外的更新和释放

以及如果只是单纯想让它不再显示,推荐用 window 类继承下来的 hide 和 show 方法
如果想刷新内容,推荐不要用生成、释放的模式,而是用它的 refresh
回复

使用道具 举报

老鹰

梦石
40
星屑
37812
在线时间
7091 小时
注册时间
2012-5-26
回帖
3297

极短24评委极短23参与极短22参与极短21评委老司机慢点开短篇十吟唱者组别冠军开拓者剧作品鉴家

发表于 2021-3-9 11:18:02 | 显示全部楼层
这个弹幕脚本吓到我了,怎会有如此暴力的直接指定只能生成三个数目的更新方式(

因为它在窗口更新前判断了下窗口是否被释放
如果被释放了,就不再更新,因此没有报错,即189行
  1. $window_biu[0].update if $window_biu[0] && !$window_biu[0].disposed?
复制代码


你也可以在你的窗口的update前面判断下是否被释放
要么在
  1. window.update if !window.disposed?
复制代码

要么在
  1. def update
  2.   return if disposed?
  3.   super
  4. end
复制代码

回复

使用道具 举报

梦石
0
星屑
29901
在线时间
5734 小时
注册时间
2016-3-8
回帖
1653
 楼主| 发表于 2021-3-9 11:43:36 | 显示全部楼层
本帖最后由 alexncf125 于 2021-3-9 11:45 编辑
百里_飞柳 发表于 2021-3-9 11:18
这个弹幕脚本吓到我了,怎会有如此暴力的直接指定只能生成三个数目的更新方式(

因为它在窗口更新前判断了 ...

============================================================
window.update if !window.disposed?

这句是指, 在Scene_Map的def update內加句
@map_name_plus_window.update if !@map_name_plus_window.disposed?么
好像没效喔
============================================================
    def update
      return if disposed?
      super
    end

这段是指, 把Window_MapNamePlus的def update改成这样子么
  1.   def update
  2.     return if disposed?##########
  3.     super
  4.     if @show_count > 0 && $game_map.name_display
  5.       update_fadein
  6.       @show_count -= 1
  7.       self.dispose if @show_count == 0##########
  8.     else
  9.       update_fadeout
  10.     end
  11.     @show_count = 0 unless $game_map.name_display##########
  12.   end
复制代码


不过这样子改会变成117行报错disposed window喔
如果在117行前加句return if disposed?又会到103行报错
难不成是得在每个方法前都得return if disposed?
回复

使用道具 举报

梦石
0
星屑
39236
在线时间
11155 小时
注册时间
2009-3-15
回帖
4768
发表于 2021-3-9 12:27:28 | 显示全部楼层
77-78

[pre lang="ruby"]self.dispose if @map_name_plus_window[/pre]
回复

使用道具 举报

梦石
0
星屑
29901
在线时间
5734 小时
注册时间
2016-3-8
回帖
1653
 楼主| 发表于 2021-3-9 12:37:03 | 显示全部楼层
soulsaga 发表于 2021-3-9 12:27
77-78

self.dispose if @map_name_plus_window[/pre]


別开玩笑吧....
77-78行的位置在class Window_MapNamePlus, 哪有@map_name_plus_window
@map_name_plus_window是class Scene_Map中, Window_MapNamePlus的实例

点评

哦..没留意..  发表于 2021-3-9 13:29
回复

使用道具 举报

梦石
0
星屑
29901
在线时间
5734 小时
注册时间
2016-3-8
回帖
1653
 楼主| 发表于 2021-3-9 13:17:36 | 显示全部楼层
百里_飞柳 发表于 2021-3-9 12:57
不好意思,其实我忘了看第二个脚本(

你这个窗口是绑定在Scene里面的一个实例变量,不需要自己释放了


好吧...总括而言,
即是不能在class Window_MapNamePlus的def update写self.dispose
只能在class Scene_Map的def update写@map_name_plus_window.dispose
就是这样没错吧...那我还是乖乖去Scene_Map写好了...谢谢大佬

点评

因为scene会自动更新它里面的全部窗口,即 @window_xxx 这样形式的变量,如果是窗口类的对象,它自动帮你更新、释放,所以你再释放,就会出现报错  发表于 2021-3-9 14:06
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部