设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
楼主: 尤莉斯
打印 上一主题 下一主题

[原创发布] 怨念产物 - GIF图片播放

 关闭 [复制链接]

Lv1.梦旅人

梦石
0
星屑
50
在线时间
0 小时
注册时间
2006-12-20
帖子
213
41
 楼主| 发表于 2007-6-11 08:18:06 | 只看该作者

怨念产物 - GIF图片播放

点击下载范例工程


  1. =begin

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


  32. #==============================================================================
  33. # ■ System
  34. #------------------------------------------------------------------------------
  35. #  处理系统相关的模块 。
  36. #==============================================================================
  37. module System
  38.   
  39.   #--------------------------------------------------------------------------
  40.   # ● 模块函数
  41.   #--------------------------------------------------------------------------
  42.   module_function
  43.   
  44.   #--------------------------------------------------------------------------
  45.   # ● API函数声明
  46.   #--------------------------------------------------------------------------
  47.   WinExec = Win32API.new("kernel32","WinExec",'pi','i')

  48.   #--------------------------------------------------------------------------
  49.   # ● 查看或修改文件及文件夹属性
  50.   #  filename :文件或文件夹名字
  51.   #
  52.   #  +a -a    :添加、删除 存档 属性
  53.   #  +r -r    :添加、删除 只读 属性
  54.   #  +s -s    :添加、删除 系统 属性
  55.   #  +h -h    :添加、删除 隐藏 属性
  56.   #--------------------------------------------------------------------------
  57.   def attrib(filename,*args)
  58.     if args.empty?
  59.       astr = `attrib #{filename}`
  60.       attri_arr = Array.new
  61.       astr = astr.split(/:/)[0]
  62.       astr = astr[0,astr.size - 1]
  63.       astr.gsub!(/ /,"")
  64.       return astr.split(//)
  65.     else
  66.       cmdline = ""
  67.       for cmdchar in args
  68.         cmdchar.downcase!
  69.         next if cmdline.include? cmdchar
  70.         if ["+a","-a","+r","-r","+s","-s","+h","-h"].include? cmdchar
  71.           cmdline += " " + cmdchar
  72.         end
  73.       end
  74.       cmdline += " "
  75.       result = WinExec.call("attrib #{cmdline}#{filename}",0)
  76.       if result < 31
  77.         return
  78.       end
  79.     end
  80.   end
  81.   
  82. end

  83. #==============================================================================
  84. # ■ GIF
  85. #------------------------------------------------------------------------------
  86. #  分析处理GIF图片的核心模块 。
  87. #==============================================================================
  88. module GIF
  89.   
  90.   # 定义常量
  91.   SIZE_GIFH = 6
  92.   
  93.   SIZE_GIFS = 7
  94.   
  95.   SIZE_GIFI = 9
  96.   
  97.   SIZE_GIFC = 6
  98.   
  99.   SIZE_GIFP = 13
  100.   
  101.   SIZE_GIFA = 12
  102.   
  103.   CODE_MASK = [0x0000,
  104.                0x0001,0x0003,0x0007,0x000f,
  105.                0x001f,0x003f,0x007f,0x00ff,
  106.                0x01ff,0x03ff,0x07ff,0x0fff]
  107.   
  108.   INC_TABLE = [8,8,4,2,0]
  109.   
  110.   BGN_TABLE = [0,4,2,1,0]
  111.   
  112.   # 建立文件夹
  113.   Dir.mkdir("GIF") unless Dir["*"].include?("GIF")
  114.   
  115.   # 函数定义
  116.   module_function
  117.   
  118.   #--------------------------------------------------------------------------
  119.   # ● 分解gif图片
  120.   #--------------------------------------------------------------------------
  121.   def analyze_gif
  122.     @old_dir = Dir.pwd
  123.     Dir.chdir("GIF")
  124.     @total_gif = []
  125.     for g in Dir["*"]
  126.       suf = g.split(/\./)
  127.       if suf[1].is_a?(String) and suf[1].downcase == "gif"
  128.         @total_gif.push(g)
  129.         Dir.mkdir(suf[0]) unless Dir["*"].include? suf[0]
  130.       end
  131.     end
  132.     @total_gif.each{|file| self.readdata(file)}
  133.     Dir.chdir(@old_dir)
  134.     p '全部分解完毕,点击确定退出'
  135.     exit
  136.   end
  137.   
  138.   #--------------------------------------------------------------------------
  139.   # ● 读取文件数据:成功返回@gif_infos,失败返回nil
  140.   #--------------------------------------------------------------------------
  141.   def readdata(filename)
  142.     # 检查是否有临时记忆文件
  143.     tmp_filename = File.basename(filename,".*")
  144.     unless Dir["~TEMP/#{tmp_filename}_infos.fmd"].empty?
  145.       begin
  146.         giffr = open("~TEMP/#{tmp_filename}_infos.fmd","rb")
  147.         tmp_infos = Marshal.load(giffr)
  148.         giffr.close
  149.         if Dir["~TEMP/#{tmp_filename}_*.png"].size == tmp_infos.total_frames
  150.           return tmp_infos
  151.         end
  152.       rescue
  153.       end
  154.     end
  155.     # 初始化数据
  156.     self.initial_var(filename)
  157.     # 打开文件
  158.     begin
  159.       @f = open(filename,"rb")
  160.       # 读取文件头
  161.       self.read_gifh
  162.       # 读取逻辑屏幕描述块
  163.       self.read_gifs
  164.       # 读取下一个字节
  165.       @temp = @f.read(1)[0]
  166.       # 循环读取每个图象描述块
  167.       while true
  168.         if @temp == 0x2c
  169.           # 读取图象描述块
  170.           self.read_gifi
  171.         end
  172.         if @temp == 0x21
  173.           # 读取图象扩展块
  174.           self.read_gife
  175.         end
  176.         if @temp == 0x3b
  177.           break
  178.         end
  179.         # 读取下一个字节
  180.         @temp = @f.read(1)[0]
  181.       end
  182.       # ※ 设置图象帧数
  183.       @gif_infos.total_frames = @frame_count
  184.       # ※ 写入图象分解数据
  185.       giffw = open("~TEMP/#{@filename}_infos.fmd","wb")
  186.       Marshal.dump(@gif_infos,giffw)
  187.       giffw.close
  188.     rescue
  189.       return nil
  190.     ensure
  191.       @f.close
  192.     end
  193.     return @gif_infos
  194.   end
  195.   
  196.   #--------------------------------------------------------------------------
  197.   # ● 初始化变量
  198.   #--------------------------------------------------------------------------
  199.   def initial_var(filename)
  200.     # ※ 生成图象数据对象
  201.     @gif_infos = GIFSprite::Infos.new
  202.     # 帧数计数
  203.     @frame_count = 0
  204.     @f = nil
  205.     @temp = nil
  206.     # 获取文件名
  207.     @filename = File.basename(filename,".*")
  208.   end
  209.   
  210.   #--------------------------------------------------------------------------
  211.   # ● 读取文件头
  212.   #--------------------------------------------------------------------------
  213.   def read_gifh
  214.     @gifh = @f.read(SIZE_GIFH)
  215.     if @gifh[0,3] != "GIF"
  216.       raise "不是GIF文件!"
  217.     end
  218.     if @gifh[3,3] != "87a" and @gifh[3,3] != "89a"
  219.       raise "不支持的版本!"
  220.     end
  221.   end
  222.   
  223.   #--------------------------------------------------------------------------
  224.   # ● 读取逻辑屏幕描述块
  225.   #--------------------------------------------------------------------------
  226.   def read_gifs
  227.     @gifs = @f.read(SIZE_GIFS).unpack("S2C3")
  228.     # 获取调色板位数
  229.     @_pal_bits = (@gifs[2] & 7) + 1
  230.     # ※ 获取图象宽度
  231.     @gif_infos.width = @gifs[0]
  232.     # ※ 获取图象高度
  233.     @gif_infos.height = @gifs[1]
  234.     # 是否有全局调色板
  235.     if @gifs[2] >> 7 == 1
  236.       # 全局调色板大小
  237.       @g_pal_size = 3 * (1 << @_pal_bits)
  238.       # 读取全局调色板数据
  239.       @g_pal = @f.read(@g_pal_size).unpack("C*")
  240.     end
  241.   end
  242.   
  243.   #--------------------------------------------------------------------------
  244.   # ● 读取图象描述块
  245.   #--------------------------------------------------------------------------
  246.   def read_gifi
  247.     # 读取图象描述块
  248.     @gifi = @f.read(SIZE_GIFI).unpack("S4C")
  249.     # ※ 生成临时帧数据对象
  250.     @gif_fd = GIFSprite::Infos::FrameData.new if @gif_fd.nil?
  251.     # ※ 获取帧偏移
  252.     @gif_fd.offset_x = @gifi[0]
  253.     @gif_fd.offset_y = @gifi[1]
  254.     # 获取宽度和高度
  255.     @_width = @gifi[2]
  256.     @_height = @gifi[3]
  257.     # 清空局部调色板
  258.     @l_pal = nil
  259.     # 是否有局部调色板
  260.     if @gifi[4] >> 7 == 1
  261.       # 获取调色板位数
  262.       @_pal_bits = (@gifi[4] & 7) + 1
  263.       # 局部调色板大小
  264.       @l_pal_size = 3 * (1 << @_pal_bits)
  265.       # 读取局部调色板数据
  266.       @l_pal = @f.read(@l_pal_size).unpack("C*")
  267.     end
  268.     # 获取交错标记
  269.     @_lace = (@gifi[4] >> 6) & 1
  270.     # 修正调色板位数
  271.     @_pal_bits = @_pal_bits == 1 ? 1 : (@_pal_bits <= 4 ? 4 : 8)
  272.     # 获取行字节数
  273.     @_width_bytes = (((@_width * @_pal_bits) + 31) >> 5) << 2
  274.     # 读取图象压缩数据
  275.     self.read_lzw_data
  276.     # ※ 设置GIF帧数据
  277.     @gif_infos.frame_data[@frame_count - 1] = @gif_fd
  278.     # ※ 清除帧数据
  279.     @gif_fd = nil
  280.   end
  281.   
  282.   #--------------------------------------------------------------------------
  283.   # ● 读取图象压缩数据
  284.   #--------------------------------------------------------------------------
  285.   def read_lzw_data
  286.     # 解码用
  287.     lzw_mincodelen = @f.read(1)[0]
  288.     # 帧数加 1
  289.     @frame_count += 1
  290.     # 图象块数据
  291.     image_data = ""
  292.     # 块大小
  293.     blocksize = @f.read(1)[0]
  294.     while blocksize > 0
  295.       image_data += @f.read(blocksize)
  296.       blocksize = @f.read(1)[0]
  297.     end
  298.     # 导出图象
  299.     self.dump_imgs(image_data,lzw_mincodelen)
  300.   end

  301.   #--------------------------------------------------------------------------
  302.   # ● 读取扩充块
  303.   #--------------------------------------------------------------------------
  304.   def read_gife
  305.     label = @f.read(1)[0]
  306.     case label
  307.     when 0xf9 # 图形控制扩展块
  308.       @gifc = @f.read(SIZE_GIFC).unpack("C2SC2")
  309.       # ※ 生成帧数据对象
  310.       @gif_fd = GIFSprite::Infos::FrameData.new   
  311.       # ※ 获取帧数据 延迟时间
  312.       @gif_fd.delay_time = @gifc[2]
  313.       # ※ 获取下一帧的处理方法
  314.       @gif_fd.disposal_method = (@gifc[1] & 28) >> 2
  315.       # 获取透明颜色
  316.       @_trans_index = nil
  317.       if @gifc[1] & 1 > 0
  318.         @_trans_index = @gifc[3]
  319.       end
  320.     when 0x01 # 图形说明扩展块
  321.       @gifp = @f.read(SIZE_GIFP).unpack("CS4C4")
  322.       blocksize = @f.read(1)[0]
  323.       while blocksize > 0
  324.         @f.read(blocksize)
  325.         blocksize = @f.read(1)[0]
  326.       end
  327.     when 0xfe # 注解说明扩展块
  328.       blocksize = @f.read(1)[0]
  329.       while blocksize > 0
  330.         @f.read(blocksize)
  331.         blocksize = @f.read(1)[0]
  332.       end
  333.     when 0xff # 应用程序扩展块
  334.       @gifa = @f.read(SIZE_GIFA).unpack("C*")
  335.       blocksize = @f.read(1)[0]
  336.       while blocksize > 0
  337.         @f.read(blocksize)
  338.         blocksize = @f.read(1)[0]
  339.       end
  340.     end
  341.   end
  342.   
  343.   #--------------------------------------------------------------------------
  344.   # ● 设置调色板
  345.   #--------------------------------------------------------------------------
  346.   def set_pal
  347.     @_pal = []
  348.     if @l_pal != nil
  349.       @_pal = @l_pal
  350.     elsif @g_pal != nil
  351.       @_pal = @g_pal
  352.     else
  353.       for i in 0...1 << @_pal_bits
  354.         @_pal.push i,i,i
  355.       end
  356.     end
  357.   end
  358.   
  359.   #--------------------------------------------------------------------------
  360.   # ● 解码图形数据
  361.   #--------------------------------------------------------------------------
  362.   def dump_imgs(image_data,lze_len)
  363.     @image_data = image_data.unpack("C*")
  364.    
  365.     self.set_pal
  366.    
  367.     @png_data = []

  368.     @stack = []
  369.     @images = []
  370.    
  371.     @prefix = []
  372.     @suffix = []
  373.    
  374.     @bitcount = @_pal_bits
  375.     @widthcount = 0
  376.    
  377.     @left_bits = 0x00
  378.     @current_bits = lze_len + 0x01
  379.    
  380.     @lzw_clear = 1 << lze_len
  381.     @lzw_eoi = @lzw_clear + 1
  382.     @nowtablendx = @lzw_clear + 2
  383.     @toptablendx = 1 << @current_bits
  384.    
  385.     @wdata = 0
  386.     @wcode = 0
  387.     @oldcode = 0xffff
  388.     @row_num = 0
  389.     @tempchar = 0x00
  390.     @pass = 0x00
  391.     @firstchar = 0
  392.     @tempndx = 0
  393.     # 读取编码字符
  394.     self.read_byte
  395.     # 不是@lzw_eoi则循环
  396.     while @wcode != @lzw_eoi
  397.       # @lzw_clear码
  398.       if @wcode == @lzw_clear
  399.         for i in 0...@lzw_clear
  400.           @prefix[i] = 0xffff
  401.           @suffix[i] = i
  402.         end
  403.         for i in @nowtablendx...4096
  404.           @prefix[i] = 0xffff
  405.           @suffix[i] = 0x00
  406.         end
  407.         @current_bits = lze_len + 0x01
  408.         @nowtablendx = @lzw_clear + 2
  409.         @toptablendx = 1 << @current_bits
  410.         @oldcode = 0xffff
  411.         # 读取编码字符
  412.         self.read_byte
  413.         if @wcode != @lzw_eoi
  414.           while @prefix[@wcode] != 0xffff
  415.             @stack.push(@suffix[@wcode])
  416.             @wcode = @prefix[@wcode]
  417.           end
  418.           @stack.push(@suffix[@wcode])
  419.           @firstchar = @stack[-1]
  420.           # 输出解码数据
  421.           self.output_data
  422.         end
  423.       else
  424.         if @wcode < @nowtablendx
  425.           @tempndx = @wcode
  426.         else
  427.           @tempndx = @oldcode
  428.           @stack.push(@firstchar)
  429.         end
  430.         while @prefix[@tempndx] != 0xffff
  431.           @stack.push(@suffix[@tempndx])
  432.           @tempndx = @prefix[@tempndx]
  433.         end
  434.         @stack.push(@suffix[@tempndx])
  435.         @firstchar = @stack[-1]
  436.         @prefix[@nowtablendx] = @oldcode
  437.         @suffix[@nowtablendx] = @firstchar
  438.         @nowtablendx += 1
  439.         if @nowtablendx == @toptablendx and @current_bits < 12
  440.           @current_bits += 1
  441.           @toptablendx = 1 << @current_bits
  442.         end
  443.         # 输出解码数据
  444.         self.output_data
  445.       end
  446.       @oldcode = @wcode
  447.       # 读取编码字符
  448.       self.read_byte
  449.     end
  450.     Graphics.update
  451.     # 生成png图
  452.     self.make_png
  453.   end

  454.   #--------------------------------------------------------------------------
  455.   # ● 读取下一个字节
  456.   #--------------------------------------------------------------------------
  457.   def read_byte
  458.     while @left_bits < @current_bits
  459.       @next_char = @image_data.shift
  460.       @wdata |= (@next_char << @left_bits)
  461.       @left_bits += 0x08
  462.     end
  463.     @wcode = @wdata & CODE_MASK[@current_bits]
  464.     @wdata >>= @current_bits
  465.     @left_bits -= @current_bits
  466.   end
  467.   
  468.   #--------------------------------------------------------------------------
  469.   # ● 输出解码数据
  470.   #--------------------------------------------------------------------------
  471.   def output_data
  472.     while [email protected]?
  473.       @tempchar |= (@stack.pop << (8 - @bitcount))
  474.       if @bitcount == 8
  475.         @images.push(@tempchar)
  476.         @tempchar = 0x00
  477.         @bitcount = @_pal_bits
  478.       else
  479.         @bitcount += @_pal_bits
  480.       end
  481.       @widthcount += 1
  482.       if @widthcount == @_width
  483.         if @bitcount != @_pal_bits
  484.           @images.push(@tempchar)
  485.           @tempchar = 0x00
  486.           @bitcount = @_pal_bits
  487.         end
  488.         @png_data[@row_num] = @images.clone
  489.         @images.clear
  490.         if @_lace > 0
  491.           @row_num += INC_TABLE[@pass]
  492.           if @row_num >= @_height
  493.             @pass += 1
  494.             @row_num = BGN_TABLE[@pass]
  495.           end
  496.         else
  497.           @row_num += 1
  498.         end
  499.         @widthcount = 0
  500.       end
  501.     end
  502.   end
  503.   
  504.   #--------------------------------------------------------------------------
  505.   # ● 生成png图片
  506.   #--------------------------------------------------------------------------
  507.   def make_png
  508.     fp = open("~TEMP/#@filename" + sprintf("_%02d",@frame_count)+".png","wb")
  509.     fp.write(self.make_png_header)
  510.     fp.write(self.make_png_ihdr)
  511.     fp.write(self.make_png_plte) if @_trans_index.nil?
  512.     fp.write(self.make_png_idat)
  513.     fp.write(self.make_png_iend)
  514.     fp.close
  515.   end
  516.    
  517.   #--------------------------------------------------------------------------
  518.   # ● png头文件
  519.   #--------------------------------------------------------------------------
  520.   def make_png_header
  521.     return [0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a].pack("C*")
  522.   end
  523.   
  524.   #--------------------------------------------------------------------------
  525.   # ● png信息头块
  526.   #--------------------------------------------------------------------------
  527.   def make_png_ihdr
  528.     ih_size = [13].pack("N")
  529.     ih_sign = "IHDR"
  530.     ih_width = [@_width].pack("N")
  531.     ih_height = [@_height].pack("N")
  532.     if @_trans_index != nil
  533.       ih_bit_depth = [@_pal_bits > 8 ? 16 : 8].pack("C")
  534.       ih_color_type = [6].pack("C")
  535.     else
  536.       ih_bit_depth = [@_pal_bits].pack("C")
  537.       ih_color_type = [3].pack("C")
  538.     end
  539.     ih_compression_method = [0].pack("C")
  540.     ih_filter_method = [0].pack("C")
  541.     ih_interlace_method = [0].pack("C")
  542.     string = ih_sign + ih_width + ih_height + ih_bit_depth + ih_color_type +
  543.              ih_compression_method + ih_filter_method + ih_interlace_method
  544.     ih_crc = [Zlib.crc32(string)].pack("N")
  545.     return ih_size + string + ih_crc
  546.   end
  547.   
  548.   #--------------------------------------------------------------------------
  549.   # ● png调色板块
  550.   #--------------------------------------------------------------------------
  551.   def make_png_plte
  552.     pl_size = [@_pal.size].pack("N")
  553.     pl_sign = "PLTE"
  554.     pl_data = @_pal.pack("C*")
  555.     pl_crc = [Zlib.crc32(pl_sign + pl_data)].pack("N")
  556.     return pl_size + pl_sign + pl_data + pl_crc
  557.   end
  558.   
  559.   #--------------------------------------------------------------------------
  560.   # ● png数据块
  561.   #--------------------------------------------------------------------------
  562.   def make_png_idat
  563.     lz_data = []
  564.     if @_trans_index != nil
  565.       for i in 0...@png_data.size
  566.         lz_data.push 0
  567.         for j in @png_data[i]
  568.           if j == @_trans_index
  569.             lz_data.push @_pal[j*3],@_pal[j*3+1],@_pal[j*3+2],0
  570.           else
  571.             lz_data.push @_pal[j*3],@_pal[j*3+1],@_pal[j*3+2],255
  572.           end
  573.         end
  574.       end
  575.     else
  576.       for i in 0...@png_data.size
  577.         lz_data.push 0
  578.         lz_data += @png_data[i]
  579.       end
  580.     end
  581.     id_data = Zlib::Deflate.deflate(lz_data.pack("C*"),9)
  582.     id_size = [id_data.size].pack("N")
  583.     id_sign = "IDAT"
  584.     id_crc = [Zlib.crc32(id_sign + id_data)].pack("N")
  585.     return id_size + id_sign + id_data + id_crc
  586.   end
  587.   
  588.   #--------------------------------------------------------------------------
  589.   # ● png 结尾块
  590.   #--------------------------------------------------------------------------
  591.   def make_png_iend
  592.     ie_size = [0].pack("N")
  593.     ie_sign = "IEND"
  594.     ie_crc = [Zlib.crc32(ie_sign)].pack("N")
  595.     return ie_size + ie_sign + ie_crc
  596.   end
  597.   
  598. end

  599. #==============================================================================
  600. # ■ Graphics
  601. #------------------------------------------------------------------------------
  602. #  处理画面的模块 。
  603. #==============================================================================
  604. class << Graphics

  605.   #--------------------------------------------------------------------------
  606.   # ● 添加别名、线程、临界区
  607.   #--------------------------------------------------------------------------
  608.   unless method_defined? :origin_update
  609.     alias origin_update update
  610.     def update_critical
  611.       Thread.critical = true
  612.       origin_update
  613.       Thread.critical = false
  614.     end
  615.     Thread.new{loop{Graphics.update_critical;sleep(9)}}
  616.   end
  617.   
  618.   #--------------------------------------------------------------------------
  619.   # ● 定义类变量
  620.   #--------------------------------------------------------------------------
  621.   @@gif_sprites = Array.new
  622.   
  623.   #--------------------------------------------------------------------------
  624.   # ● 添加GIF图片精灵
  625.   #--------------------------------------------------------------------------
  626.   def add(gs)
  627.     @@gif_sprites << gs
  628.   end
  629.   
  630.   #--------------------------------------------------------------------------
  631.   # ● 删除GIF图片精灵
  632.   #--------------------------------------------------------------------------
  633.   def del(gs)
  634.     @@gif_sprites.delete gs
  635.   end

  636.   #--------------------------------------------------------------------------
  637.   # ● 更新画面
  638.   #--------------------------------------------------------------------------
  639.   def update
  640.     update_critical
  641.     @@gif_sprites.each{|gs| gs.update}
  642.   end
  643.   
  644. end

  645. #==============================================================================
  646. # ■ GIFSprite
  647. #------------------------------------------------------------------------------
  648. #  GIF精灵的核心类 。
  649. #==============================================================================
  650. class GIFSprite
  651.   
  652.   #============================================================================
  653.   # ● GIFSprite::Infos
  654.   #----------------------------------------------------------------------------
  655.   #  GIF图片信息类 。
  656.   #============================================================================
  657.   class Infos
  658.    
  659.     #------------------------------------------------------------------------
  660.     # ● 定义实例变量
  661.     #------------------------------------------------------------------------
  662.     attr_accessor :total_frames
  663.     attr_accessor :width
  664.     attr_accessor :height
  665.     attr_accessor :frame_data
  666.    
  667.     #------------------------------------------------------------------------
  668.     # ● 初始化
  669.     #------------------------------------------------------------------------
  670.     def initialize
  671.       @total_frames = 0
  672.       @width = 0
  673.       @height = 0
  674.       @frame_data = Array.new
  675.     end
  676.    
  677.     #==========================================================================
  678.     # ● GIFSprite::Infos::FrameData
  679.     #--------------------------------------------------------------------------
  680.     #  GIF图片每帧信息类 。
  681.     #==========================================================================
  682.     class FrameData
  683.       
  684.       #----------------------------------------------------------------------
  685.       # ● 定义实例变量
  686.       #----------------------------------------------------------------------
  687.       attr_accessor :offset_x
  688.       attr_accessor :offset_y
  689.       attr_accessor :delay_time
  690.       attr_accessor :disposal_method
  691.       
  692.       #----------------------------------------------------------------------
  693.       # ● 初始化
  694.       #----------------------------------------------------------------------
  695.       def initialize
  696.         @offset_x = 0
  697.         @offset_y = 0
  698.         @delay_time = 0
  699.         @disposal_method = 0
  700.       end
  701.       
  702.     end
  703.    
  704.   end
  705.   
  706.   #--------------------------------------------------------------------------
  707.   # ● 预处理:建立临时文件夹
  708.   #--------------------------------------------------------------------------
  709.   unless Dir["*"].include?("~TEMP")
  710.     Dir.mkdir("~TEMP")
  711.     System.attrib("~TEMP","+h","+s")
  712.   end
  713.   
  714.   #--------------------------------------------------------------------------
  715.   # ● 清空硬缓存
  716.   #--------------------------------------------------------------------------
  717.   def self.TmpFileclear
  718.     begin
  719.       Dir["~TEMP/*"].each{|filename| File.delete filename}
  720.     rescue
  721.     end
  722.   end
  723.   
  724.   #--------------------------------------------------------------------------
  725.   # ● 预加载图片
  726.   #--------------------------------------------------------------------------
  727.   def self.pre_load(filename_arr)
  728.     filename_arr.each{|fn| GIF.readdata(fn)}
  729.   end
  730.   
  731.   #--------------------------------------------------------------------------
  732.   # ● 定义实例变量
  733.   #--------------------------------------------------------------------------
  734.   attr_accessor :x
  735.   attr_accessor :y
  736.   attr_reader   :z
  737.   attr_accessor :loop_counts
  738.   attr_accessor :viewport
  739.   
  740.   #--------------------------------------------------------------------------
  741.   # ● 创建对象
  742.   #--------------------------------------------------------------------------
  743.   def self.new(viewport = nil,x = 0,y = 0,loop_counts = -1)
  744.     obj = super()
  745.     obj.viewport = viewport
  746.     obj.x = x
  747.     obj.y = y
  748.     obj.loop_counts = loop_counts
  749.     Graphics.add(obj)
  750.     obj
  751.   end
  752.   
  753.   #--------------------------------------------------------------------------
  754.   # ● 获取图片信息
  755.   #--------------------------------------------------------------------------
  756.   def bitmap
  757.     @gif_infos
  758.   end
  759.   
  760.   #--------------------------------------------------------------------------
  761.   # ● 设置图片文件名
  762.   #--------------------------------------------------------------------------
  763.   def bitmap=(filename)
  764.     @gif_infos = GIF.readdata(filename)
  765.     if @gif_infos != nil
  766.       @sp_arr = Array.new
  767.       basename = File.basename(filename,".*")
  768.       for i in 0...@gif_infos.total_frames
  769.         sp   = Sprite.new(@viewport)
  770.         sp.bitmap = Bitmap.new(sprintf("~TEMP/#{basename}_%02d.png",i + 1))
  771.         sp.visible = i == 0
  772.         sp.x = @gif_infos.frame_data[i].offset_x
  773.         sp.y = @gif_infos.frame_data[i].offset_y
  774.         @sp_arr << sp
  775.       end
  776.       @update_frame_count = 0
  777.       @current_show_frame = 0
  778.       @next_frame_counts =
  779.       (@gif_infos.frame_data[0].delay_time * Graphics.frame_rate / 100)
  780.     end
  781.   end
  782.   
  783.   #--------------------------------------------------------------------------
  784.   # ● 定义x=
  785.   #--------------------------------------------------------------------------
  786.   def x=(x)
  787.     if @gif_infos.nil?
  788.       @x = 0
  789.       return
  790.     end
  791.     @x = x
  792.     for i in 0...@gif_infos.total_frames
  793.       @sp_arr[i].x = @gif_infos.frame_data[i].offset_x + @x
  794.     end
  795.   end
  796.   
  797.   #--------------------------------------------------------------------------
  798.   # ● 定义y=
  799.   #--------------------------------------------------------------------------
  800.   def y=(y)
  801.     if @gif_infos.nil?
  802.       @y = 0
  803.       return
  804.     end
  805.     @y = y
  806.     for i in 0...@gif_infos.total_frames
  807.       @sp_arr[i].y = @gif_infos.frame_data[i].offset_y + @y
  808.     end
  809.   end
  810.   
  811.   #--------------------------------------------------------------------------
  812.   # ● 定义z=
  813.   #--------------------------------------------------------------------------
  814.   def z=(z)
  815.     if @gif_infos.nil?
  816.       @z = 0
  817.       return
  818.     end
  819.     @z = z
  820.     for i in 0...@gif_infos.total_frames
  821.       @sp_arr[i].z = @z
  822.     end
  823.   end
  824.   
  825.   #--------------------------------------------------------------------------
  826.   # ● 获取宽度
  827.   #--------------------------------------------------------------------------
  828.   def width
  829.     return @gif_infos.nil? ? 0 : @gif_infos.width
  830.   end
  831.   
  832.   #--------------------------------------------------------------------------
  833.   # ● 获取高度
  834.   #--------------------------------------------------------------------------
  835.   def height
  836.     return @gif_infos.nil? ? 0 : @gif_infos.height
  837.   end
  838.   
  839.   #--------------------------------------------------------------------------
  840.   # ● 释放精灵
  841.   #--------------------------------------------------------------------------
  842.   def dispose
  843.     Graphics.del(self)
  844.     @sp_arr.each{|sp|
  845.       sp.bitmap.dispose
  846.       sp.dispose
  847.     }
  848.     @sp_arr.clear
  849.     @gif_infos = nil
  850.   end
  851.   
  852.   #--------------------------------------------------------------------------
  853.   # ● 更新精灵
  854.   #--------------------------------------------------------------------------
  855.   def update
  856.     if @gif_infos.nil?
  857.       return
  858.     end
  859.     @update_frame_count += 1
  860.     if @update_frame_count >= @next_frame_counts
  861.       @current_show_frame = (@current_show_frame + 1) % @gif_infos.total_frames
  862.       case @gif_infos.frame_data[@current_show_frame - 1].disposal_method
  863.       when 0 # 不处理
  864.         
  865.       when 1 # 图象保留在原处
  866.         
  867.       when 2 # 当前图象消失
  868.         @sp_arr[@current_show_frame - 1].visible = false
  869.       when 3 # 尚不明 = =
  870.         
  871.       end
  872.       @sp_arr[@current_show_frame].visible = true
  873.       if @current_show_frame == 0
  874.         @loop_counts -= 1 if @loop_counts > 0
  875.         if @loop_counts == 0
  876.           self.dispose
  877.           return
  878.         end
  879.         for i in 0...@sp_arr.size
  880.           @sp_arr[i].visible = i == @current_show_frame
  881.         end
  882.       end
  883.       @update_frame_count = 0
  884.       @next_frame_counts = (@gif_infos.frame_data[@current_show_frame].\
  885.       delay_time * Graphics.frame_rate / 100)
  886.     end
  887.   end
  888.   
  889. end

复制代码


gpra8764:
加亮显示!


              [本贴由 叶舞枫 于 2007-6-15 18:06:40 进行了编辑]
哼哼。。。。
回复 支持 反对

使用道具 举报

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-26 02:57

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表