#=============================================================================
# ** Graphics
#-----------------------------------------------------------------------------
# Rewrites Graphics.freeze and Graphics.transition
#=============================================================================
module Graphics
# If the Transition is smaller than the Screen...
# 0: Do the rest like it was filled with black
# 1: Copy the Bitmap abreast
# 2: Stretch the Bitmap
Transition_Scale_Method = 0
@_freezed_sprite = Sprite.new
@_freezed_sprite.z = 1073741823
#--------------------------------------------------------------------------
# * Freezes the Screen
#--------------------------------------------------------------------------
def self.freeze
# Make Screenshot
Screenshot.shot("screenshot")
screen = Bitmap.new("screenshot.png")
File.delete("screenshot.png")
@_freezed_sprite.bitmap = screen
end
#--------------------------------------------------------------------------
# * Performs a transition
# duration: The duration in frames.
# filename: The filename of the transition.
# vague: The softness of the transition.
#--------------------------------------------------------------------------
def self.transition(duration = 8, filename = "", vague = 40)
self.prepare_transition(duration, filename, vague)
Graphics.update
# Do the Transition
for frame in 0...duration
@_freezed_sprite.bitmap = @_next_transition[frame]
Graphics.update
end
# Dispose everything and start GC
@_freezed_sprite.bitmap = Bitmap.new(1, 1)
bitmap, @_next_transition, hash = 0, 0, 0, 0
GC.start
end
private
#--------------------------------------------------------------------------
# * Prepares a Transition
# duration: The duration in frames.
# filename: The filename of the transition.
# vague: The softness of the transition.
#--------------------------------------------------------------------------
def self.prepare_transition(duration, filename, vague)
time = Time.now
# Make Transition-Bitmap
bitmap = self.transition_bitmap(filename)
# Calculate pixels
pixels = self.transition_order(bitmap, duration)
# Pack pixels so its size is equal to duration
array = Array.new(duration, [])
part = (255.0/duration).ceil
for n in 1..256
dur = (n.to_f/part).ceil - 1
array[dur] = array[dur].concat(pixels[n-1])
end
Graphics.update
@_next_transition = self.transition_create_bitmaps(array, duration, vague)
end
#--------------------------------------------------------------------------
# * Makes the Transition-Bitmaps.
# (this methods needs a loooong time => sometimes 'Script is hanging')
# array: The Array which holds the pixel-data.
# duration: The duration in frames.
# vague: The softness of the transition.
#--------------------------------------------------------------------------
def self.transition_create_bitmaps(array, duration, vague)
bitmaps = Array.new(duration) {|n| @_freezed_sprite.bitmap.dup}
# Loop through frames
for frame in 0...duration
# Create vague-hash
hash = {}
for n in 0...vague
break if (frame-n) < 0
k = vague < 1 ? 0 : n*255/vague
hash[k] = array[frame]
end
# Create Bitmap
bmp = bitmaps[frame]
for opacity in hash.keys
Graphics.update
for pix in hash[opacity]
x, y = pix[0], pix[1]
color = bmp.get_pixel(x, y)
bmp.set_pixel(x, y, Color.new(color.red, color.green, color.blue, opacity))
end
end
end
bitmaps
end
#--------------------------------------------------------------------------
# * Returns the finished Transition-Bitmap
# filename: The filename of the image.
#--------------------------------------------------------------------------
def self.transition_bitmap(filename)
# Get width and height of the RGSS-Player
if method_defined?(:width) && method_defined?(:height)
w, h = self.width, self.height
else
w, h = 640, 480
end
# Create Transition-Bitmap
if filename == ""
bitmap = Bitmap.new(w, h)
bitmap.fill_rect(bitmap.rect, Color.new(0, 0, 0))
else
bitmap = RPG::Cache.transition(filename)
end
# If the Bitmap is smaller than the screen
if bitmap.width < w or bitmap.height < h
new = Bitmap.new(w, h)
case Transition_Scale_Method
when 0
new.fill_rect(new.rect, Color.new(0, 0, 0))
new.fill_rect(bitmap.rect, Color.new(0, 0, 0, 0))
new.blt(0, 0, bitmap, bitmap.rect)
when 1
tw = (w.to_f/bitmap.width).ceil
th = (h.to_f/bitmap.height).ceil
for ox in 0...tw
for oy in 0...th
x, y = ox*bitmap.width, oy*bitmap.height
new.blt(x, y, bitmap, bitmap.rect)
end
end
when 2
new.stretch_blt(new.rect, bitmap, bitmap.rect)
end
bitmap = new
end
bitmap
end
#--------------------------------------------------------------------------
# * Returns an Array with the pixel-order
# bitmap: The Transition as a Bitmap
# duration: Duration of the Transition
#--------------------------------------------------------------------------
def self.transition_order(bitmap, duration)
array = Array.new(256) {|n| Array.new}
# Loop through each pixel
for x in 0...bitmap.width
for y in 0...bitmap.height
# Get color
c = bitmap.get_pixel(x, y)
# Calculate average (grayscale it)
av = Math.average(c.red, c.green, c.blue).round
# Add the coordinates to array
array[av] << [x, y]
end
end
array
end
end