🤔 Para Refletir :
"Refatorar o código é como usar inseticida: Elimina bugs."
- Mayleone

RESOLVIDO!(Dúvida rmxp) script gif player

KAI GAMES Masculino

Plebeu
Membro
Membro
Juntou-se
06 de Fevereiro de 2019
Postagens
24
Bravecoins
31
olá!, recentemente encontrei um script de gif player para RMXP.... créditos a Shakugan no Shana pela criação:

Ruby:
=begin

  脚本:【怨念产物 - GIF图片播放】
 
  功能:在游戏中播放GIF图片 ※ 表情优先。
 
  说明: 使用步骤:
 
        1、使用 @gs = GIFSprite.new([viewport,[x,[,y,[loop_counts]]]])
           创建GIF图片对象;
       
        2、然后使用 @gs.bitmap = "gif_filename" ※ 包含文件夹路径;
     
        3、可以 @gs.loop_counts = n
       
           设置循环次数,-1表示无限循环(默认的),0就释放图片。
       
        4、@gs.x = x,@gs.y = y,@gs.z = z 等设置各种坐标值。
 
  补充:1、由于考虑的效率问题,提供了生成临时文件技术,即第一运行之后以后每次运
 
        行会直接读取临时文件生成对象,可以使用 GIFSprite.TmpFileclear 清空临时
     
        文件。
     
        2、可以使用 GIFSprite.pre_load(filename_arr) 数组预加载一组图片。    
     
  版本:v1.0
     
  作者:灼眼的夏娜
 
=end


#==============================================================================
# ■ System
#------------------------------------------------------------------------------
#  处理系统相关的模块 。
#==============================================================================
module System
 
  #--------------------------------------------------------------------------
  # ● 模块函数
  #--------------------------------------------------------------------------
  module_function
 
  #--------------------------------------------------------------------------
  # ● API函数声明
  #--------------------------------------------------------------------------
  WinExec = Win32API.new("kernel32","WinExec",'pi','i')

  #--------------------------------------------------------------------------
  # ● 查看或修改文件及文件夹属性
  #  filename :文件或文件夹名字
  #
  #  +a -a    :添加、删除 存档 属性
  #  +r -r    :添加、删除 只读 属性
  #  +s -s    :添加、删除 系统 属性
  #  +h -h    :添加、删除 隐藏 属性
  #--------------------------------------------------------------------------
  def attrib(filename,*args)
    if args.empty?
      astr = `attrib #{filename}`
      attri_arr = Array.new
      astr = astr.split(/:/)[0]
      astr = astr[0,astr.size - 1]
      astr.gsub!(/ /,"")
      return astr.split(//)
    else
      cmdline = ""
      for cmdchar in args
        cmdchar.downcase!
        next if cmdline.include? cmdchar
        if ["+a","-a","+r","-r","+s","-s","+h","-h"].include? cmdchar
          cmdline += " " + cmdchar
        end
      end
      cmdline += " "
      result = WinExec.call("attrib #{cmdline}#{filename}",0)
      if result < 31
        return
      end
    end
  end
 
end

#==============================================================================
# ■ GIF
#------------------------------------------------------------------------------
#  分析处理GIF图片的核心模块 。
#==============================================================================
module GIF
 
  # 定义常量
  SIZE_GIFH = 6
 
  SIZE_GIFS = 7
 
  SIZE_GIFI = 9
 
  SIZE_GIFC = 6
 
  SIZE_GIFP = 13
 
  SIZE_GIFA = 12
 
  CODE_MASK = [0x0000,
               0x0001,0x0003,0x0007,0x000f,
               0x001f,0x003f,0x007f,0x00ff,
               0x01ff,0x03ff,0x07ff,0x0fff]
 
  INC_TABLE = [8,8,4,2,0]
 
  BGN_TABLE = [0,4,2,1,0]
 
  # 建立文件夹
  Dir.mkdir("GIF") unless Dir["*"].include?("GIF")
 
  # 函数定义
  module_function
 
  #--------------------------------------------------------------------------
  # ● 分解gif图片
  #--------------------------------------------------------------------------
  def analyze_gif
    @old_dir = Dir.pwd
    Dir.chdir("GIF")
    @total_gif = []
    for g in Dir["*"]
      suf = g.split(/\./)
      if suf[1].is_a?(String) and suf[1].downcase == "gif"
        @total_gif.push(g)
        Dir.mkdir(suf[0]) unless Dir["*"].include? suf[0]
      end
    end
    @total_gif.each{|file| self.readdata(file)}
    Dir.chdir(@old_dir)
    p '全部分解完毕,点击确定退出'
    exit
  end
 
  #--------------------------------------------------------------------------
  # ● 读取文件数据:成功返回@gif_infos,失败返回nil
  #--------------------------------------------------------------------------
  def readdata(filename)
    # 检查是否有临时记忆文件
    tmp_filename = File.basename(filename,".*")
    unless Dir["~TEMP/#{tmp_filename}_infos.fmd"].empty?
      begin
        giffr = open("~TEMP/#{tmp_filename}_infos.fmd","rb")
        tmp_infos = Marshal.load(giffr)
        giffr.close
        if Dir["~TEMP/#{tmp_filename}_*.png"].size == tmp_infos.total_frames
          return tmp_infos
        end
      rescue
      end
    end
    # 初始化数据
    self.initial_var(filename)
    # 打开文件
    begin
      @f = open(filename,"rb")
      # 读取文件头
      self.read_gifh
      # 读取逻辑屏幕描述块
      self.read_gifs
      # 读取下一个字节
      @temp = @f.read(1)[0]
      # 循环读取每个图象描述块
      while true
        if @temp == 0x2c
          # 读取图象描述块
          self.read_gifi
        end
        if @temp == 0x21
          # 读取图象扩展块
          self.read_gife
        end
        if @temp == 0x3b
          break
        end
        # 读取下一个字节
        @temp = @f.read(1)[0]
      end
      # ※ 设置图象帧数
      @gif_infos.total_frames = @frame_count
      # ※ 写入图象分解数据
      giffw = open("~TEMP/#{@filename}_infos.fmd","wb")
      Marshal.dump(@gif_infos,giffw)
      giffw.close
    rescue
      return nil
    ensure
      @f.close
    end
    return @gif_infos
  end
 
  #--------------------------------------------------------------------------
  # ● 初始化变量
  #--------------------------------------------------------------------------
  def initial_var(filename)
    # ※ 生成图象数据对象
    @gif_infos = GIFSprite::Infos.new
    # 帧数计数
    @frame_count = 0
    @f = nil
    @temp = nil
    # 获取文件名
    @filename = File.basename(filename,".*")
  end
 
  #--------------------------------------------------------------------------
  # ● 读取文件头
  #--------------------------------------------------------------------------
  def read_gifh
    @gifh = @f.read(SIZE_GIFH)
    if @gifh[0,3] != "GIF"
      raise "不是GIF文件!"
    end
    if @gifh[3,3] != "87a" and @gifh[3,3] != "89a"
      raise "不支持的版本!"
    end
  end
 
  #--------------------------------------------------------------------------
  # ● 读取逻辑屏幕描述块
  #--------------------------------------------------------------------------
  def read_gifs
    @gifs = @f.read(SIZE_GIFS).unpack("S2C3")
    # 获取调色板位数
    @_pal_bits = (@gifs[2] & 7) + 1
    # ※ 获取图象宽度
    @gif_infos.width = @gifs[0]
    # ※ 获取图象高度
    @gif_infos.height = @gifs[1]
    # 是否有全局调色板
    if @gifs[2] >> 7 == 1
      # 全局调色板大小
      @g_pal_size = 3 * (1 << @_pal_bits)
      # 读取全局调色板数据
      @g_pal = @f.read(@g_pal_size).unpack("C*")
    end
  end
 
  #--------------------------------------------------------------------------
  # ● 读取图象描述块
  #--------------------------------------------------------------------------
  def read_gifi
    # 读取图象描述块
    @gifi = @f.read(SIZE_GIFI).unpack("S4C")
    # ※ 生成临时帧数据对象
    @gif_fd = GIFSprite::Infos::FrameData.new if @gif_fd.nil?
    # ※ 获取帧偏移
    @gif_fd.offset_x = @gifi[0]
    @gif_fd.offset_y = @gifi[1]
    # 获取宽度和高度
    @_width = @gifi[2]
    @_height = @gifi[3]
    # 清空局部调色板
    @l_pal = nil
    # 是否有局部调色板
    if @gifi[4] >> 7 == 1
      # 获取调色板位数
      @_pal_bits = (@gifi[4] & 7) + 1
      # 局部调色板大小
      @l_pal_size = 3 * (1 << @_pal_bits)
      # 读取局部调色板数据
      @l_pal = @f.read(@l_pal_size).unpack("C*")
    end
    # 获取交错标记
    @_lace = (@gifi[4] >> 6) & 1
    # 修正调色板位数
    @_pal_bits = @_pal_bits == 1 ? 1 : (@_pal_bits <= 4 ? 4 : 8)
    # 获取行字节数
    @_width_bytes = (((@_width * @_pal_bits) + 31) >> 5) << 2
    # 读取图象压缩数据
    self.read_lzw_data
    # ※ 设置GIF帧数据
    @gif_infos.frame_data[@frame_count - 1] = @gif_fd
    # ※ 清除帧数据
    @gif_fd = nil
  end
 
  #--------------------------------------------------------------------------
  # ● 读取图象压缩数据
  #--------------------------------------------------------------------------
  def read_lzw_data
    # 解码用
    lzw_mincodelen = @f.read(1)[0]
    # 帧数加 1
    @frame_count += 1
    # 图象块数据
    image_data = ""
    # 块大小
    blocksize = @f.read(1)[0]
    while blocksize > 0
      image_data += @f.read(blocksize)
      blocksize = @f.read(1)[0]
    end
    # 导出图象
    self.dump_imgs(image_data,lzw_mincodelen)
  end
 
  #--------------------------------------------------------------------------
  # ● 读取扩充块
  #--------------------------------------------------------------------------
  def read_gife
    label = @f.read(1)[0]
    case label
    when 0xf9 # 图形控制扩展块
      @gifc = @f.read(SIZE_GIFC).unpack("C2SC2")
      # ※ 生成帧数据对象
      @gif_fd = GIFSprite::Infos::FrameData.new
      # ※ 获取帧数据 延迟时间
      @gif_fd.delay_time = @gifc[2]
      # ※ 获取下一帧的处理方法
      @gif_fd.disposal_method = (@gifc[1] & 28) >> 2
      # 获取透明颜色
      @_trans_index = nil
      if @gifc[1] & 1 > 0
        @_trans_index = @gifc[3]
      end
    when 0x01 # 图形说明扩展块
      @gifp = @f.read(SIZE_GIFP).unpack("CS4C4")
      blocksize = @f.read(1)[0]
      while blocksize > 0
        @f.read(blocksize)
        blocksize = @f.read(1)[0]
      end
    when 0xfe # 注解说明扩展块
      blocksize = @f.read(1)[0]
      while blocksize > 0
        @f.read(blocksize)
        blocksize = @f.read(1)[0]
      end
    when 0xff # 应用程序扩展块
      @gifa = @f.read(SIZE_GIFA).unpack("C*")
      blocksize = @f.read(1)[0]
      while blocksize > 0
        @f.read(blocksize)
        blocksize = @f.read(1)[0]
      end
    end
  end
 
  #--------------------------------------------------------------------------
  # ● 设置调色板
  #--------------------------------------------------------------------------
  def set_pal
    @_pal = []
    if @l_pal != nil
      @_pal = @l_pal
    elsif @g_pal != nil
      @_pal = @g_pal
    else
      for i in 0...1 << @_pal_bits
        @_pal.push i,i,i
      end
    end
  end
 
  #--------------------------------------------------------------------------
  # ● 解码图形数据
  #--------------------------------------------------------------------------
  def dump_imgs(image_data,lze_len)
    @image_data = image_data.unpack("C*")
 
    self.set_pal
 
    @png_data = []

    @stack = []
    @images = []
 
    @prefix = []
    @suffix = []
 
    @bitcount = @_pal_bits
    @widthcount = 0
 
    @left_bits = 0x00
    @current_bits = lze_len + 0x01
 
    @lzw_clear = 1 << lze_len
    @lzw_eoi = @lzw_clear + 1
    @nowtablendx = @lzw_clear + 2
    @toptablendx = 1 << @current_bits
 
    @wdata = 0
    @wcode = 0
    @oldcode = 0xffff
    @row_num = 0
    @tempchar = 0x00
    @pass = 0x00
    @firstchar = 0
    @tempndx = 0
    # 读取编码字符
    self.read_byte
    # 不是@lzw_eoi则循环
    while @wcode != @lzw_eoi
      # @lzw_clear码
      if @wcode == @lzw_clear
        for i in 0...@lzw_clear
          @prefix[i] = 0xffff
          @suffix[i] = i
        end
        for i in @nowtablendx...4096
          @prefix[i] = 0xffff
          @suffix[i] = 0x00
        end
        @current_bits = lze_len + 0x01
        @nowtablendx = @lzw_clear + 2
        @toptablendx = 1 << @current_bits
        @oldcode = 0xffff
        # 读取编码字符
        self.read_byte
        if @wcode != @lzw_eoi
          while @prefix[@wcode] != 0xffff
            @stack.push(@suffix[@wcode])
            @wcode = @prefix[@wcode]
          end
          @stack.push(@suffix[@wcode])
          @firstchar = @stack[-1]
          # 输出解码数据
          self.output_data
        end
      else
        if @wcode < @nowtablendx
          @tempndx = @wcode
        else
          @tempndx = @oldcode
          @stack.push(@firstchar)
        end
        while @prefix[@tempndx] != 0xffff
          @stack.push(@suffix[@tempndx])
          @tempndx = @prefix[@tempndx]
        end
        @stack.push(@suffix[@tempndx])
        @firstchar = @stack[-1]
        @prefix[@nowtablendx] = @oldcode
        @suffix[@nowtablendx] = @firstchar
        @nowtablendx += 1
        if @nowtablendx == @toptablendx and @current_bits < 12
          @current_bits += 1
          @toptablendx = 1 << @current_bits
        end
        # 输出解码数据
        self.output_data
      end
      @oldcode = @wcode
      # 读取编码字符
      self.read_byte
    end
    Graphics.update
    # 生成png图
    self.make_png
  end

  #--------------------------------------------------------------------------
  # ● 读取下一个字节
  #--------------------------------------------------------------------------
  def read_byte
    while @left_bits < @current_bits
      @next_char = @image_data.shift
      @wdata |= (@next_char << @left_bits)
      @left_bits += 0x08
    end
    @wcode = @wdata & CODE_MASK[@current_bits]
    @wdata >>= @current_bits
    @left_bits -= @current_bits
  end
 
  #--------------------------------------------------------------------------
  # ● 输出解码数据
  #--------------------------------------------------------------------------
  def output_data
    while !@stack.empty?
      @tempchar |= (@stack.pop << (8 - @bitcount))
      if @bitcount == 8
        @images.push(@tempchar)
        @tempchar = 0x00
        @bitcount = @_pal_bits
      else
        @bitcount += @_pal_bits
      end
      @widthcount += 1
      if @widthcount == @_width
        if @bitcount != @_pal_bits
          @images.push(@tempchar)
          @tempchar = 0x00
          @bitcount = @_pal_bits
        end
        @png_data[@row_num] = @images.clone
        @images.clear
        if @_lace > 0
          @row_num += INC_TABLE[@pass]
          if @row_num >= @_height
            @pass += 1
            @row_num = BGN_TABLE[@pass]
          end
        else
          @row_num += 1
        end
        @widthcount = 0
      end
    end
  end
 
  #--------------------------------------------------------------------------
  # ● 生成png图片
  #--------------------------------------------------------------------------
  def make_png
    fp = open("~TEMP/#@filename" + sprintf("_%02d",@frame_count)+".png","wb")
    fp.write(self.make_png_header)
    fp.write(self.make_png_ihdr)
    fp.write(self.make_png_plte) if @_trans_index.nil?
    fp.write(self.make_png_idat)
    fp.write(self.make_png_iend)
    fp.close
  end
 
  #--------------------------------------------------------------------------
  # ● png头文件
  #--------------------------------------------------------------------------
  def make_png_header
    return [0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a].pack("C*")
  end
 
  #--------------------------------------------------------------------------
  # ● png信息头块
  #--------------------------------------------------------------------------
  def make_png_ihdr
    ih_size = [13].pack("N")
    ih_sign = "IHDR"
    ih_width = [@_width].pack("N")
    ih_height = [@_height].pack("N")
    if @_trans_index != nil
      ih_bit_depth = [@_pal_bits > 8 ? 16 : 8].pack("C")
      ih_color_type = [6].pack("C")
    else
      ih_bit_depth = [@_pal_bits].pack("C")
      ih_color_type = [3].pack("C")
    end
    ih_compression_method = [0].pack("C")
    ih_filter_method = [0].pack("C")
    ih_interlace_method = [0].pack("C")
    string = ih_sign + ih_width + ih_height + ih_bit_depth + ih_color_type +
             ih_compression_method + ih_filter_method + ih_interlace_method
    ih_crc = [Zlib.crc32(string)].pack("N")
    return ih_size + string + ih_crc
  end
 
  #--------------------------------------------------------------------------
  # ● png调色板块
  #--------------------------------------------------------------------------
  def make_png_plte
    pl_size = [@_pal.size].pack("N")
    pl_sign = "PLTE"
    pl_data = @_pal.pack("C*")
    pl_crc = [Zlib.crc32(pl_sign + pl_data)].pack("N")
    return pl_size + pl_sign + pl_data + pl_crc
  end
 
  #--------------------------------------------------------------------------
  # ● png数据块
  #--------------------------------------------------------------------------
  def make_png_idat
    lz_data = []
    if @_trans_index != nil
      for i in 0...@png_data.size
        lz_data.push 0
        for j in @png_data[i]
          if j == @_trans_index
            lz_data.push @_pal[j*3],@_pal[j*3+1],@_pal[j*3+2],0
          else
            lz_data.push @_pal[j*3],@_pal[j*3+1],@_pal[j*3+2],255
          end
        end
      end
    else
      for i in 0...@png_data.size
        lz_data.push 0
        lz_data += @png_data[i]
      end
    end
    id_data = Zlib::Deflate.deflate(lz_data.pack("C*"),9)
    id_size = [id_data.size].pack("N")
    id_sign = "IDAT"
    id_crc = [Zlib.crc32(id_sign + id_data)].pack("N")
    return id_size + id_sign + id_data + id_crc
  end
 
  #--------------------------------------------------------------------------
  # ● png 结尾块
  #--------------------------------------------------------------------------
  def make_png_iend
    ie_size = [0].pack("N")
    ie_sign = "IEND"
    ie_crc = [Zlib.crc32(ie_sign)].pack("N")
    return ie_size + ie_sign + ie_crc
  end
 
end

#==============================================================================
# ■ Graphics
#------------------------------------------------------------------------------
#  处理画面的模块 。
#==============================================================================
class << Graphics

  #--------------------------------------------------------------------------
  # ● 添加别名、线程、临界区
  #--------------------------------------------------------------------------
  unless method_defined? :origin_update
    alias origin_update update
    def update_critical
      Thread.critical = true
      origin_update
      Thread.critical = false
    end
    Thread.new{loop{Graphics.update_critical;sleep(9)}}
  end
 
  #--------------------------------------------------------------------------
  # ● 定义类变量
  #--------------------------------------------------------------------------
  @@gif_sprites = Array.new
 
  #--------------------------------------------------------------------------
  # ● 添加GIF图片精灵
  #--------------------------------------------------------------------------
  def add(gs)
    @@gif_sprites << gs
  end
 
  #--------------------------------------------------------------------------
  # ● 删除GIF图片精灵
  #--------------------------------------------------------------------------
  def del(gs)
    @@gif_sprites.delete gs
  end

  #--------------------------------------------------------------------------
  # ● 更新画面
  #--------------------------------------------------------------------------
  def update
    update_critical
    @@gif_sprites.each{|gs| gs.update}
  end
 
end

#==============================================================================
# ■ GIFSprite
#------------------------------------------------------------------------------
#  GIF精灵的核心类 。
#==============================================================================
class GIFSprite
 
  #============================================================================
  # ● GIFSprite::Infos
  #----------------------------------------------------------------------------
  #  GIF图片信息类 。
  #============================================================================
  class Infos
 
    #------------------------------------------------------------------------
    # ● 定义实例变量
    #------------------------------------------------------------------------
    attr_accessor :total_frames
    attr_accessor :width
    attr_accessor :height
    attr_accessor :frame_data
 
    #------------------------------------------------------------------------
    # ● 初始化
    #------------------------------------------------------------------------
    def initialize
      @total_frames = 0
      @width = 0
      @height = 0
      @frame_data = Array.new
    end
 
    #==========================================================================
    # ● GIFSprite::Infos::FrameData
    #--------------------------------------------------------------------------
    #  GIF图片每帧信息类 。
    #==========================================================================
    class FrameData
   
      #----------------------------------------------------------------------
      # ● 定义实例变量
      #----------------------------------------------------------------------
      attr_accessor :offset_x
      attr_accessor :offset_y
      attr_accessor :delay_time
      attr_accessor :disposal_method
   
      #----------------------------------------------------------------------
      # ● 初始化
      #----------------------------------------------------------------------
      def initialize
        @offset_x = 0
        @offset_y = 0
        @delay_time = 0
        @disposal_method = 0
      end
   
    end
 
  end
 
  #--------------------------------------------------------------------------
  # ● 预处理:建立临时文件夹
  #--------------------------------------------------------------------------
  unless Dir["*"].include?("~TEMP")
    Dir.mkdir("~TEMP")
    System.attrib("~TEMP","+h","+s")
  end
 
  #--------------------------------------------------------------------------
  # ● 清空硬缓存
  #--------------------------------------------------------------------------
  def self.TmpFileclear
    begin
      Dir["~TEMP/*"].each{|filename| File.delete filename}
    rescue
    end
  end
 
  #--------------------------------------------------------------------------
  # ● 预加载图片
  #--------------------------------------------------------------------------
  def self.pre_load(filename_arr)
    filename_arr.each{|fn| GIF.readdata(fn)}
  end
 
  #--------------------------------------------------------------------------
  # ● 定义实例变量
  #--------------------------------------------------------------------------
  attr_accessor :x
  attr_accessor :y
  attr_reader   :z
  attr_accessor :loop_counts
  attr_accessor :viewport
 
  #--------------------------------------------------------------------------
  # ● 创建对象
  #--------------------------------------------------------------------------
  def self.new(viewport = nil,x = 0,y = 0,loop_counts = -1)
    obj = super()
    obj.viewport = viewport
    obj.x = x
    obj.y = y
    obj.loop_counts = loop_counts
    Graphics.add(obj)
    obj
  end
 
  #--------------------------------------------------------------------------
  # ● 获取图片信息
  #--------------------------------------------------------------------------
  def bitmap
    @gif_infos
  end
 
  #--------------------------------------------------------------------------
  # ● 设置图片文件名
  #--------------------------------------------------------------------------
  def bitmap=(filename)
    @gif_infos = GIF.readdata(filename)
    if @gif_infos != nil
      @sp_arr = Array.new
      basename = File.basename(filename,".*")
      for i in 0...@gif_infos.total_frames
        sp   = Sprite.new(@viewport)
        sp.bitmap = Bitmap.new(sprintf("~TEMP/#{basename}_%02d.png",i + 1))
        sp.visible = i == 0
        sp.x = @gif_infos.frame_data[i].offset_x
        sp.y = @gif_infos.frame_data[i].offset_y
        @sp_arr << sp
      end
      @update_frame_count = 0
      @current_show_frame = 0
      @next_frame_counts =
      (@gif_infos.frame_data[0].delay_time * Graphics.frame_rate / 100)
    end
  end
 
  #--------------------------------------------------------------------------
  # ● 定义x=
  #--------------------------------------------------------------------------
  def x=(x)
    if @gif_infos.nil?
      @x = 0
      return
    end
    @x = x
    for i in 0...@gif_infos.total_frames
      @sp_arr[i].x = @gif_infos.frame_data[i].offset_x + @x
    end
  end
 
  #--------------------------------------------------------------------------
  # ● 定义y=
  #--------------------------------------------------------------------------
  def y=(y)
    if @gif_infos.nil?
      @y = 0
      return
    end
    @y = y
    for i in 0...@gif_infos.total_frames
      @sp_arr[i].y = @gif_infos.frame_data[i].offset_y + @y
    end
  end
 
  #--------------------------------------------------------------------------
  # ● 定义z=
  #--------------------------------------------------------------------------
  def z=(z)
    if @gif_infos.nil?
      @z = 0
      return
    end
    @z = z
    for i in 0...@gif_infos.total_frames
      @sp_arr[i].z = @z
    end
  end
 
  #--------------------------------------------------------------------------
  # ● 获取宽度
  #--------------------------------------------------------------------------
  def width
    return @gif_infos.nil? ? 0 : @gif_infos.width
  end
 
  #--------------------------------------------------------------------------
  # ● 获取高度
  #--------------------------------------------------------------------------
  def height
    return @gif_infos.nil? ? 0 : @gif_infos.height
  end
 
  #--------------------------------------------------------------------------
  # ● 释放精灵
  #--------------------------------------------------------------------------
  def dispose
    Graphics.del(self)
    @sp_arr.each{|sp|
      sp.bitmap.dispose
      sp.dispose
    }
    @sp_arr.clear
    @gif_infos = nil
  end
 
  #--------------------------------------------------------------------------
  # ● 更新精灵
  #--------------------------------------------------------------------------
  def update
    if @gif_infos.nil?
      return
    end
    @update_frame_count += 1
    if @update_frame_count >= @next_frame_counts
      @current_show_frame = (@current_show_frame + 1) % @gif_infos.total_frames
      case @gif_infos.frame_data[@current_show_frame - 1].disposal_method
      when 0 # 不处理
     
      when 1 # 图象保留在原处
     
      when 2 # 当前图象消失
        @sp_arr[@current_show_frame - 1].visible = false
      when 3 # 尚不明 = =
     
      end
      @sp_arr[@current_show_frame].visible = true
      if @current_show_frame == 0
        @loop_counts -= 1 if @loop_counts > 0
        if @loop_counts == 0
          self.dispose
          return
        end
        for i in 0...@sp_arr.size
          @sp_arr[i].visible = i == @current_show_frame
        end
      end
      @update_frame_count = 0
      @next_frame_counts = (@gif_infos.frame_data[@current_show_frame].\
      delay_time * Graphics.frame_rate / 100)
    end
  end
 
end

script encontrado em:
https://templorpgmakerbr.forumeiros.com/t1048-gif-player


Este script permite a leitura de um dos muitos formatos que o maker não lê: o .gif, podendo ser animado ou não.
é necessário ter uma pasta chamada "GIF" no projeto e depois chamá-los para reproduizir via chamada de script

porém, o que era de se esperar, é extremamente lento para carregar em alguns casos.... o que me fez ter a seguinte dúvida. ...
É possível pré-carregar todos os gifs da pasta "GIF" antes de iniciar o jogo para poder exibi-los posteriormente depois?

tipo uma tela de loading antes da tela inicial pra poder pré recarregar tudo antes :unsure: ....não sei dizer se resolveria o problema...o que vocês acham?

desde já agradeço



EDIT



RESOLVIDO!


A solução foi encontar um script que usa úma unica picture como uma linha de sprite horizontal

O script é o Easy animated pictures V1.... créditos a lavendersiren e Coelocanth pela criação


Ruby:
#-------------------------------------- ---- -- -
#  Easy animated pictures v1
#  by lavendersiren and Coelocanth
#-------------------------------------- ---- -- -
# Where to put: between debug and main, most likely near the top of your script list.
# May have some incompatibilities with other scripts that modify how pictures work.
#
# How to use:
# 1. Turn your animation into a horizontal sprite strip.
# 2. Make sure the file name starts with an exclamation point,
# the number of frames, and an underscore. Put whatever you want right after.
#
# Example: !4_firetest.png
#
# 3. Then, just import it into the picture folder and use as usual!
#
# Terms of use:
# Can be used in any project, commercial or noncommercial, with proper credit.
#
#==============================================================================
# ** Sprite_Picture
#------------------------------------------------------------------------------
#  This sprite is used to display the picture.It observes the Game_Character
#  class and automatically changes sprite conditions.
#==============================================================================

class Sprite_Picture < Sprite
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     viewport : viewport
  #     picture  : picture (Game_Picture)
  #--------------------------------------------------------------------------
  def initialize(viewport, picture)
    super(viewport)
    @picture = picture
    @picframe = 1
  @delay_count = 3
  @delay_val = @delay_count
  @animated = true
    update
  end
  #--------------------------------------------------------------------------
  # * Dispose
  #--------------------------------------------------------------------------
  def dispose
    if self.bitmap != nil
      self.bitmap.dispose
    end
    super
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If picture file name is different from current one
    if @picture_name != @picture.name
      # Remember file name to instance variables
      @picture_name = @picture.name
      # If file name is not empty
      if @picture_name != ""
        # Get picture graphic
        self.bitmap = RPG::Cache.picture(@picture_name)
      end
    end
    # If file name is empty
    if @picture_name == ""
      # Set sprite to invisible
      self.visible = false
      return
    end
   

    # Set sprite coordinates
    self.x = @picture.x
    self.y = @picture.y
    self.z = @picture.number
    # Set zoom rate, opacity level, and blend method
    self.zoom_x = @picture.zoom_x / 100.0
    self.zoom_y = @picture.zoom_y / 100.0
    self.opacity = @picture.opacity
    self.blend_type = @picture.blend_type
    # Set rotation angle and color tone
    self.angle = @picture.angle
    self.tone = @picture.tone
    #------------------------------------
    #  sprite slicinggggggg!!!
    #--------------------------------------
   
    #if the file name string includes a ! sign plus a digit
  if /!(\d+)_/ =~ @picture_name
    @framecount = $1.to_i
    @animated=true
    else
        @framecount = 1
    @animated=false
        #if it doesn't have one, just slice it in 1 piece :b
    end
    if @animated== true
          #SLICE IT!!!
        @cw = bitmap.width / @framecount
      @ch = bitmap.height
      sx = @picframe * @cw
      #set the sx according to which frame you want to start on,
    #and times that by cw
      sy = 1
      #keep sy the same, it's just a strip
     self.src_rect.set(sx, sy, @cw, @ch)  
   
   end
 

    # Set transfer starting point
    if @picture.origin == 0
      self.ox = 0
      self.oy = 0
    else
      if @animated==true
        self.ox = @cw / 2
        self.oy = self.bitmap.height / 2
            else
        self.ox = self.bitmap.width / 2
        self.oy = self.bitmap.height / 2
        end
  end
 
      # Set sprite to visible
    self.visible = true
 
    #timinggg!
if @animated==true

  if @delay_val <= 0
  @delay_val = @delay_count
      if @picframe >= @framecount -1
        @picframe = 0
        else
        @picframe +=1
        end
    else
        @delay_val -= 1
    end
    end

  end
end

encontrado em: https://rpgmaker.net/scripts/775/

a imagem precisa estar na pasta pictures pra funcionar
o nome do arquivo deve começar com um ponto de exclamação, o número de quadros e um sublinhado. e depois pode colocar o nome que quiser .

Exemplo : !4_firetest.png (sendo 4 o número de frames que contem na picture)

depois é só mostrar a picture normalmente por eventos

pra converter os gifs em uma única linha de sprite usei um software gratuito e bem leve chamado Avi4bmp

dá pra baixá-lo rapidamente no link:

http://www.bottomap.com/Software/A4B/A4B.html

Pelo menos aqui pra mim fazendo isso o lag diminuiu bastante então....

OBRIGADO A TODOS!
 
Última edição:
No campo da especulação é uma boa ideia, porém... não sei se o Maker XP tem suporte a isso.
Acho que a solução mais trabalhosa para a aumentar a eficiência dessa ideia seria desmembrar esses gifs e os animar de forma manual no comando "show picture". Você teria que usar com certa ponderação as gifs, mas mesmo assim é uma ideia... Se fosse para usar em algum tipo de menu ou sei lá que você quer usar os gifs, geralmente os scripts de Menu tem essas pictures animadas se movimentando!

Bem, vamos aguardar alguém ainda melhor que eu dar algumas sugestões.
 
entendo ,eu até poderia salvar quadro a quadro das imagens em uma pasta, mas o fato de ser um numero muito alto de quadros acho que seria inviável .... nesse caso seria mais interessante se desse pra chama-los todos de uma vez controlando a ordem e o tempo entre elas :unsure: é que realmente são muitos quadros, são quadros pra caramba😅.....me lembro de ter visto um script que fazia isso a muitos anos atrás...não sei ao certo onde encontrá-lo de novo mas acredito que dessa maneira tbm resolveria o problema do lag.....
 
Última edição:
Voltar
Topo Inferior