=begin ▼ アニメーションフレーム補間 ver. 1.0 RPGツクールVXAce用スクリプト 制作 : 木星ペンギン URL : http://woodpenguin.blog.fc2.com/ ------------------------------------------------------------------------------ 概要 □ アニメーションのフレーム補間を行い、滑らかにします。 ※ アニメーションによっては不自然になることがあるので注意! =end #////////////////////////////////////////////////////////////////////////////// # # 設定項目なし # #////////////////////////////////////////////////////////////////////////////// module WdTk @material ||= [] @material << :FrameInt def self.include?(sym) @material.include?(sym) end end #============================================================================== # ■ Sprite_Base #============================================================================== class Sprite_Base #-------------------------------------------------------------------------- # ○ アニメーション グラフィックの読み込み #-------------------------------------------------------------------------- alias _wdtk_frmint_load_animation_bitmap load_animation_bitmap def load_animation_bitmap _wdtk_frmint_load_animation_bitmap @frameint_bitmaps = Array.new(16) { Bitmap.new(192, 192) } end #-------------------------------------------------------------------------- # ● アニメーションの解放 #-------------------------------------------------------------------------- alias _wdtk_frmint_dispose_animation dispose_animation def dispose_animation _wdtk_frmint_dispose_animation @frameint_bitmaps.each {|bitmap| bitmap.dispose } if @frameint_bitmaps @frameint_bitmaps = nil end #-------------------------------------------------------------------------- # ○ アニメーションの更新 #-------------------------------------------------------------------------- alias _wdtk_frmint_update_animation update_animation def update_animation _wdtk_frmint_update_animation return unless animation? unless @ani_duration % @ani_rate == 0 if @ani_duration > 0 frame_index = @animation.frame_max frame_index -= (@ani_duration + @ani_rate - 1) / @ani_rate frames1 = @animation.frames[frame_index] frames2 = @animation.frames[frame_index + 1] animation_set_sprites_frmint(frames1, frames2) if frames1 end end end #-------------------------------------------------------------------------- # ● アニメーションスプライトの補間 #-------------------------------------------------------------------------- def animation_set_sprites_frmint(frames1, frames2) d = @ani_duration % @ani_rate cell_data1 = frames1.cell_data cell_data2 = frames2 ? frames2.cell_data : cell_data1.dup cell_data2.xsize.times {|i| cell_data2[i, 0] = -1 } unless frames2 reserve = [] @ani_sprites.each_index do |i| pattern1 = cell_data1[i, 0] next if !pattern1 || pattern1 < 0 16.times do |n| m = (n + i) % 16 pattern2 = cell_data2[m, 0] next if !pattern2 || pattern2 < 0 if cell_data1[i, 1] == cell_data2[m, 1] && cell_data1[i, 2] == cell_data2[m, 2] && (pattern2 - pattern1).between?(0, 1) reserve[i] = m end end end @ani_sprites.each_with_index do |sprite, i| next unless sprite if !reserve[i] && reserve.include?(i) sprite.opacity = frmint_val(sprite.opacity, 0, d) next end pattern1 = cell_data1[i, 0] next if !pattern1 || pattern1 < 0 n = reserve[i] || i pattern2 = cell_data2[n, 0] if !pattern2 || pattern2 < 0 sprite.opacity = frmint_val(sprite.opacity, 0, d) next end next if cell_data1[i, 5] != cell_data2[n, 5] next if cell_data1[i, 7] != cell_data2[n, 7] if pattern2 != pattern1 next if pattern2 - pattern1 != 1 #if cell_data1[i, 3] == cell_data2[n, 3] sprite.bitmap = @frameint_bitmaps[i] sprite.bitmap.clear bitmap = pattern1 < 100 ? @ani_bitmap1 : @ani_bitmap2 rect = Rect.new rect.set(pattern1 % 5 * 192, pattern1 % 100 / 5 * 192, 192, 192) sprite.bitmap.blt(0, 0, bitmap, rect, 255 * d / @ani_rate) bitmap = pattern2 < 100 ? @ani_bitmap1 : @ani_bitmap2 rect = Rect.new rect.set(pattern2 % 5 * 192, pattern2 % 100 / 5 * 192, 192, 192) sprite.bitmap.blt(0, 0, bitmap, rect, 255 - 255 * d / @ani_rate) #end end angle2 = cell_data2[n, 4] - 360 angle2 += 360 while (sprite.angle - angle2).abs > 180 if @ani_mirror sprite.x = frmint_val(sprite.x, @ani_ox - cell_data2[n, 1], d) sprite.y = frmint_val(sprite.y, @ani_oy + cell_data2[n, 2], d) sprite.angle = -frmint_val(sprite.angle, angle2, d) else sprite.x = frmint_val(sprite.x, @ani_ox + cell_data2[n, 1], d) sprite.y = frmint_val(sprite.y, @ani_oy + cell_data2[n, 2], d) sprite.angle = frmint_val(sprite.angle, angle2, d) end #if pattern2 == pattern1 sprite.zoom_x = frmint_val(sprite.zoom_x, cell_data2[n, 3] / 100.0, d) sprite.zoom_y = frmint_val(sprite.zoom_y, cell_data2[n, 3] / 100.0, d) #end sprite.opacity = frmint_val(sprite.opacity, cell_data2[n, 6] * self.opacity / 255.0, d) end end #-------------------------------------------------------------------------- # ● 補間した数値の取得 #-------------------------------------------------------------------------- def frmint_val(val1, val2, d) (val1 * (d - 1) + val2) / d end end