查看: 2495|回复: 3

[有事请教] 请教关于此脚本的优化方案

[复制链接]
梦石
0
星屑
8498
在线时间
775 小时
注册时间
2017-11-10
回帖
1074
发表于 2019-5-1 11:48:36 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
[pre lang="ruby"]#==============================================================================
# ■ Angel_Skill_Ex
#==============================================================================
module Angel_Skill_Ex
  Use_Elements_Set = true #是否用屬性表示
  Show_Elements = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] #表示的屬性
  Elements_Icon = [0,2209, 2211, 2214, 2216, 2213, 2220, 2210, 2208,
                  104, 105, 106, 107, 108, 109, 110, 111,128,129,130,131] #屬性的圖標
end
#==============================================================================
# ■ Window_Skill_List
#==============================================================================
class Window_Skill_List < Window_Selectable
  #--------------------------------------------------------------------------
  # * 定義實例變量
  #--------------------------------------------------------------------------
  attr_accessor :info_window
  #--------------------------------------------------------------------------
  # ● 初始化對象
  #     actor  : 角色
  #--------------------------------------------------------------------------
  def initialize(actor, h=416-(WLH+32))
    super(0, WLH+56, 280, h-24)
    @actor = actor
    @column_max = 1
    self.index = 0
    @info_window = nil
    data_refresh
    update_cursor
  end
  #--------------------------------------------------------------------------
  # ● 獲取技能
  #--------------------------------------------------------------------------
  def skill
    return @data[self.index]
  end
  #--------------------------------------------------------------------------
  # ● 數據刷新
  #--------------------------------------------------------------------------
  def data_refresh
    @data = []
    for skill in @actor.skills
      @data.push(skill)
      if skill.id == @actor.last_skill_id
        self.index = @data.size - 1
      end
    end
    @item_max = @data.size
    create_contents
    refresh
  end
  #--------------------------------------------------------------------------
  # ● 刷新
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    for i in 0...@item_max
      draw_item(i, false)
    end
  end
  #--------------------------------------------------------------------------
  # ● 描繪技能
  #    index : 索引
  #--------------------------------------------------------------------------
  def draw_item(index, clear=true)
    rect = item_rect(index)
    self.contents.clear_rect(rect) if clear
    skill = @data[index]
    if skill != nil
      rect.width -= 4
      enabled = @actor.skill_can_use?(skill)
      draw_item_name(skill, rect.x, rect.y, enabled)
      if !enabled
      self.contents.font.color = knockout_color
      self.contents.draw_text(rect.x + 160, rect.y, 160, WLH, "無法使用")
      end
    end
  end
  #--------------------------------------------------------------------------
  # * 更新動態説明視窗內容資訊
  #--------------------------------------------------------------------------
  def update_help
    @help_window.set_text(skill == nil ? "無技能" : skill.description)
    @info_window.refresh(skill) unless @info_window.nil?
  end
end
#==============================================================================
# ■ Window_Skill_Info
#==============================================================================
class Window_Skill_Info < Window_Base
  #--------------------------------------------------------------------------
  # ● 初始化對象
  #--------------------------------------------------------------------------
  def initialize(y=WLH*5+96, h=416-(WLH*5+96))
    super(280, y, 264, h)
  end
  #--------------------------------------------------------------------------
  # ● 常量
  #--------------------------------------------------------------------------
  SCOPE = ["無", "敵單體", "敵全體", "敵單體連擊",
           "特別目標", "敵二體", "敵三體", "我方單體",
           "我方全體", "我方瀕死単體", "我方瀕死全體", "自身"]
  #--------------------------------------------------------------------------
  # ● 刷新
  #--------------------------------------------------------------------------
  def refresh(skill=nil)
    self.contents.clear
    return if skill.nil?
    self.contents.font.color = system_color
    self.contents.draw_text(0, WLH*0, 100, WLH, "類別")
    self.contents.draw_text(0, WLH*1, 100, WLH, "效果範圍")
    self.contents.draw_text(0, WLH*2, 100, WLH, "追加傷害")
    self.contents.draw_text(0, WLH*3, 100, WLH, "命中率")
    self.contents.draw_text(0, WLH*4, 100, WLH, "屬性") if Angel_Skill_Ex::Use_Elements_Set
    self.contents.draw_text(0, WLH*5, 100, WLH, "活力消耗")
    self.contents.draw_text(0, WLH*6, 100, WLH, "速度修正")
    self.contents.font.color = normal_color
    if skill.base_damage > 0
      txt = skill.physical_attack ? "物理攻撃" : "攻撃魔法"
    elsif skill.base_damage < 0
      txt = skill.physical_attack ? "回復技能" : "回復魔法"
    elsif skill.hit < 1
      txt = skill.physical_attack ? "被動技能" : "被動技能"
    else
      txt = skill.physical_attack ? "特殊技能" : "輔助魔法"
    end
    self.contents.draw_text(120, WLH*0, 160, WLH, txt)
    self.contents.draw_text(120, WLH*1, 216, WLH, SCOPE[skill.scope])
    self.contents.draw_text(120, WLH*2, 60, WLH, skill.base_damage.to_s+" 點", 2)
    self.contents.draw_text(120, WLH*3, 60, WLH, skill.hit.to_s+" %", 2)
    self.contents.draw_text(120, WLH*5, 60, WLH, skill.mp_cost.to_s+" 點", 2)
    self.contents.draw_text(120, WLH*6, 60, WLH, skill.speed.to_s+" %", 2)
    if Angel_Skill_Ex::Use_Elements_Set
      i = 0
      for element_id in skill.element_set
        next unless Angel_Skill_Ex::Show_Elements.include?(element_id)
        draw_element_icon(element_id, 120+i*24, WLH*4)
        i += 1
      end
    end
  end
  #--------------------------------------------------------------------------
  # ● 屬性圖標的描繪
  #--------------------------------------------------------------------------
  def draw_element_icon(element_id, x, y, enabled = true)
    draw_icon(Angel_Skill_Ex::Elements_Icon[element_id], x, y, enabled)
  end
end
#==============================================================================
# ■ Window_Skill_User
#==============================================================================
class Window_Skill_User < Window_Base
  #--------------------------------------------------------------------------
  # ● 初始化對象
  #    actor : 角色
  #--------------------------------------------------------------------------
  def initialize(actor)
    super(280, WLH+56, 264, WLH*6 - 8)
    @actor = actor
    refresh
  end
  #--------------------------------------------------------------------------
  # ● 刷新
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    draw_actor_face(@actor, 0, 0)
    draw_actor_graphic(@actor, 200, WLH*1+24)
    draw_actor_name(@actor, 104, 0)
    draw_actor_state(@actor, 104, WLH*1)
    draw_actor_hp(@actor, 104, WLH*2)
    draw_actor_mp(@actor, 104, WLH*3)
  end
end
#==============================================================================
# ■ Window_Skill_Help
#==============================================================================
class Window_Skill_Help < Window_Base
  Wait_time = 40
  Fade_out = Wait_time / 4
  def xx(w)
    return (544-w)/2
  end
  #--------------------------------------------------------------------------
  # * 初始化參數
  #--------------------------------------------------------------------------
  def initialize
    super(xx(240), 160, 240, WLH+32)
    @wait = 0
    self.z = 600
    self.visible = false
  end
  #--------------------------------------------------------------------------
  # * 設置文字
  #--------------------------------------------------------------------------
  def set_text(type)
    case type
    when 0
    text = "該技能魔法使用的時機不對哦。"
    when 1
    text = "該技能魔法暫時不能起效果。"
    when 2
    text = "該角色的活力值不夠了。"
    when 3
    text = "無效技能!"
    else
    return
    end
    w = self.contents.text_size(text).width
    self.width = w + 32
    self.x = xx(self.width)
    self.contents.dispose
    self.contents = Bitmap.new(w, WLH)
    self.contents.draw_text(0, 0, w, WLH, text)
    @wait = Wait_time
    self.visible = true
    self.opacity = self.contents_opacity = 255
  end
  #--------------------------------------------------------------------------
  # * 畫面更新
  #--------------------------------------------------------------------------
  def update
    super
    @wait -= 1
    if @wait < Fade_out
      self.opacity = self.contents_opacity = 255 / Fade_out * @wait
      self.visible = false if @wait == 0
    end
  end
end
#==============================================================================
# ■ Scene_Skill
#==============================================================================
class Scene_Skill < Scene_Base
  #--------------------------------------------------------------------------
  # ● 物件初始化
  #     actor_index : 主角編號
  #--------------------------------------------------------------------------
  def initialize(actor_index = 0)
    @actor_index = actor_index
  end
  #--------------------------------------------------------------------------
  # * 程序開始
  #--------------------------------------------------------------------------
  def start
    super
    create_menu_background
    @actor = $game_party.members[@actor_index]
    @viewport = Viewport.new(0, 0, 544, 416)
    @help_window = Window_Help.new
    @help_window.viewport = @viewport
    @status_window = Window_Skill_User.new(@actor)
    @status_window.viewport = @viewport
    @skill_info_window = Window_Skill_Info.new
    @skill_info_window.viewport = @viewport
    @skill_window = Window_Skill_List.new(@actor)
    @skill_window.viewport = @viewport
    @skill_window.info_window = @skill_info_window
    @skill_window.help_window = @help_window
    @target_window = Window_MenuStatus.new(0, 0)
    @message_window  = Window_Skill_Help.new
    hide_target_window
  end
  #--------------------------------------------------------------------------
  # * 程序終止
  #--------------------------------------------------------------------------
  def terminate
    super
    dispose_menu_background
    @help_window.dispose
    @status_window.dispose
    @skill_info_window.dispose
    @skill_window.dispose
    @target_window.dispose
    @message_window.dispose
  end
  #--------------------------------------------------------------------------
  # * 更新幀
  #--------------------------------------------------------------------------
  alias angel_skill_update update
  def update
  angel_skill_update
  if @message_window.visible
     @message_window.update
     return
  end
end
  #--------------------------------------------------------------------------
  # * 更新技能選擇指令輸入資訊
  #--------------------------------------------------------------------------
  def update_skill_selection
    if Input.trigger?(Input::B)
      Sound.play_cancel
      return_scene
    elsif Input.trigger?(Input::R)
      Sound.play_cursor
      next_actor
    elsif Input.trigger?(Input::L)
      Sound.play_cursor
      prev_actor
    elsif Input.trigger?(Input::C)
      @skill = @skill_window.skill
      if @skill != nil
        @actor.last_skill_id = @skill.id
      else
        Sound.play_buzzer
        @message_window.set_text(3)
       return
     end
     
      if @actor.skill_can_use?(@skill)
        Sound.play_decision
        determine_skill
      elsif @actor.calc_mp_cost(@skill) > @actor.mp
        Sound.play_buzzer
        @message_window.set_text(2)
      else
        Sound.play_buzzer
        @message_window.set_text(0)
      end
      
    end
  end
  #--------------------------------------------------------------------------
  # * 更新目標選擇指令輸入資訊
  #--------------------------------------------------------------------------
  def update_target_selection
    if Input.trigger?(Input::B)
      Sound.play_cancel
      hide_target_window
    elsif Input.trigger?(Input::C)
      if !@actor.skill_can_use?(@skill)
        Sound.play_buzzer
        @message_window.set_text(2)
      else
        determine_target
      end
    end
  end
  #--------------------------------------------------------------------------
  # * 判定技能是否可以施用於目標
  #    若無效(如施用增加HP的技能於瀕死者),播放“無效”SE。
  #--------------------------------------------------------------------------
  def determine_target
    used = false
    if @skill.for_all?
      for target in $game_party.members
        target.skill_effect(@actor, @skill)
        used = true unless target.skipped
      end
    elsif @skill.for_user?
      target = $game_party.members[@target_window.index - 100]
      target.skill_effect(@actor, @skill)
      used = true unless target.skipped
    else
      $game_party.last_target_index = @target_window.index
      target = $game_party.members[@target_window.index]
      target.skill_effect(@actor, @skill)
      used = true unless target.skipped
    end
    if used
      use_skill_nontarget
    else
      Sound.play_buzzer
      @message_window.set_text(1)
    end
  end
end
#==============================================================================
# ** Scene_Battle
#------------------------------------------------------------------------------
#  這個類用來執行顯示作戰畫面的程式。
#==============================================================================
class Scene_Battle < Scene_Base
  #--------------------------------------------------------------------------
  # ● 開始接收技能選擇的指令輸入資訊
  #--------------------------------------------------------------------------
  def start_skill_selection
    @help_window = Window_Help.new
    @skill_window = Window_Skill_List.new(@active_battler, 232)
    @skill_info_window = Window_Skill_Info.new(80, 208)
    @skill_window.info_window = @skill_info_window
    @skill_window.help_window = @help_window
    @actor_command_window.active = false
  end
  #--------------------------------------------------------------------------
  # ● 停止接收技能選擇的指令輸入資訊
  #--------------------------------------------------------------------------
  def end_skill_selection
   if @skill_window != nil
      @skill_window.dispose
      @skill_info_window.dispose
      @skill_window = @skill_info_window = nil
      @help_window.dispose
      @help_window = nil
    end
    @actor_command_window.active = true
  end
end[/pre]
请教为何描绘Window_Skill_Info里面的内容时会特别的卡顿
特别在技能很多的情况之下。
请教有没有其他描绘办法可以减少卡顿的现象?
一个只会简单事件的Rm新人,脚本完全不懂。只求做个简单的游戏完成自己的游戏之梦而已。
第一个游戏已经完成,等待各素材的完成和测试。
梦石
1
星屑
24088
在线时间
3339 小时
注册时间
2011-7-8
回帖
3862

开拓者

发表于 2019-5-1 14:29:35 | 显示全部楼层
有2点可以考虑:
1. 在技能不变的情况下跳过refresh,可以在scene里判定或者在window类里判定,这个是卡顿的主要原因
2. 对于一些位置和内容不变的文字内容,可以在window的initialize方法里建立一个sprite,其bitmap与contents等大的,把文字绘制在这里面。这样refresh时就无需重绘这部分文字。
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复

使用道具 举报

梦石
0
星屑
8498
在线时间
775 小时
注册时间
2017-11-10
回帖
1074
 楼主| 发表于 2019-5-2 19:32:37 | 显示全部楼层
guoxiaomi 发表于 2019-5-1 14:29
有2点可以考虑:
1. 在技能不变的情况下跳过refresh,可以在scene里判定或者在window类里判定,这个是卡顿的 ...

谢谢前辈
我采用了第一种。完美解决了卡顿的问题。
于是想问问第二种该怎么实现?
一个只会简单事件的Rm新人,脚本完全不懂。只求做个简单的游戏完成自己的游戏之梦而已。
第一个游戏已经完成,等待各素材的完成和测试。
回复

使用道具 举报

梦石
1
星屑
24088
在线时间
3339 小时
注册时间
2011-7-8
回帖
3862

开拓者

发表于 2019-5-2 20:51:19 | 显示全部楼层
本帖最后由 guoxiaomi 于 2019-5-2 20:53 编辑
文雅夕露 发表于 2019-5-2 19:32
谢谢前辈
我采用了第一种。完美解决了卡顿的问题。
于是想问问第二种该怎么实现?


VX不常用,大概类似这样的写法,不过一般没有明显的效率提升
[pre lang="ruby"]class Window_XXX < Window_Base
  def initialize
    # ...   
    bitmap = Bitmap.new(self.width - 32, self.height - 32)
    bitmap.draw_text( ... )
    bitmap.blt( ... )
    @sprite_static = Sprite.new
    @sprite_static.bitmap = bitmap
  end

  def dispose   
    @sprite_static.dispose
    # ...
  end
end
[/pre]
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部