Kain Nobel
Member
In the CMS Contest topic, there was some talk about animating the windows to slide in/out of the screen during scene change, which in all of my scripts to date slide in. There is one thing I've always had trouble with though, that I've only got to work ONCE before (which I later messed up and deleted), and that is getting the windows to move to their "out" destination before the scene changes over to the next.
First off, when I did it in Scene_Item a while back I thought I did it in this sort of fashion, so I tried to do something with my windows and SDK::Scene_Base to halt the dispose and update just the windows until each of their move variables were set to nil.
Attempting that method, I also tried a couple different arrangements, with either a loop do or a begin ; end until blah fashion but they still gave me hangups. But yet, another approach I tried gave me another strange behavior and I'm kinda wondering how and why it does it.
This causes everything in my scenes to double-update (everything updates twice as fast, and input is doubled so that when you go down one space in a menu it goes down two instead of one.) So in that case, I re-arranged it like so...
Commenting out the return false didn't solve it, I had to comment out the if / end statement as well so the culprit is most likely window_movement_wait?.
Here is the entire Windows.Movable script I wrote, the methods you want to focus on are the last two in Window_Base and the additional coding to SDK::Scene_Base. (If I knew there was a Movable module in the MACL long before I wrote this I'd probably use it but I wrote my own :P)
PS; If anybody has a better suggestion on how to dance with the Out-movement of the windows before the main_dispose, feel free to throw me a bone ! Thanks.
First off, when I did it in Scene_Item a while back I thought I did it in this sort of fashion, so I tried to do something with my windows and SDK::Scene_Base to halt the dispose and update just the windows until each of their move variables were set to nil.
Code:
class Scene_Blah < SDK::Scene_Base
 alias_method :winmovable_sdkscnbase_maindispose, :main_dispose
 def main_dispose
  if window_movement_wait?
   begin
    all_windows.each {|win| win.update}
   end until !window_movement_wait?
  end
  winmovable_sdkscnbase_maindispose
 end
end
Attempting that method, I also tried a couple different arrangements, with either a loop do or a begin ; end until blah fashion but they still gave me hangups. But yet, another approach I tried gave me another strange behavior and I'm kinda wondering how and why it does it.
Code:
def main_break?
 return winmovable_sdkscnbase_mainbreak? && !window_movement_wait?
end
This causes everything in my scenes to double-update (everything updates twice as fast, and input is doubled so that when you go down one space in a menu it goes down two instead of one.) So in that case, I re-arranged it like so...
Code:
def main_break?
 if window_movement_wait?
  return false
 end
 return winmovable_sdkscenebase_mainbreak?
end
Commenting out the return false didn't solve it, I had to comment out the if / end statement as well so the culprit is most likely window_movement_wait?.
Here is the entire Windows.Movable script I wrote, the methods you want to focus on are the last two in Window_Base and the additional coding to SDK::Scene_Base. (If I knew there was a Movable module in the MACL long before I wrote this I'd probably use it but I wrote my own :P)
Code:
#===============================================================================
# ** Window_Base
#-------------------------------------------------------------------------------
# Â Additional methods appended to the origional Window_Base, used to enhance
# the default Window system in some way.
#===============================================================================
class Window_Base < Window
 #-----------------------------------------------------------------------------
 # * Customizable Constant
 #-----------------------------------------------------------------------------
 Default_Speed = 5
 #-----------------------------------------------------------------------------
 # * Public Instance Variables
 #-----------------------------------------------------------------------------
 attr_accessor :new_x
 attr_accessor :new_y
 attr_accessor :new_width
 attr_accessor :new_height
 attr_accessor :delay
 attr_accessor :new_z
 attr_accessor :new_o
 attr_accessor :new_co
 #-----------------------------------------------------------------------------
 # * Alias Listing
 #-----------------------------------------------------------------------------
 alias_method :movable_win_base_update,    :update
 #-----------------------------------------------------------------------------
 # * Movable Initialize
 #-----------------------------------------------------------------------------
 def movable_initialize
  # Set move delay based off instance / constant, then autoset if not numeric
  if @delay.nil?
   @delay = Default_Speed
  end
  # Store each of these parameters into instance of @init_(param)
  ['x','y','width','height','z','opacity','contents_opacity'].each do |obj|
   eval "@init_#{obj} = self.#{obj}"
  end
  # Fade opacity if instance is integer, set instance to nil
  if @fade_opacity.is_a?(Integer)
   fade_opacity(@fade_opacity)
   @fade_opacity = nil
  end
  # Fade contents if instance is integer, set instance to nil
  if @fade_contents.is_a?(Integer)
   fade_contents(@fade_contents)
   @fade_contents = nil
  end
  # Move to initial X/Y coords if instance is true, set instance nil
  if @move_in == true
   move_to(@init_x, @init_y)
   @move_in = nil
  end
  # Lastly, set movable initialized to true
  @movable_initialized = true
 end
 #-----------------------------------------------------------------------------
 # * Update Method
 #-----------------------------------------------------------------------------
 def update
  # The very initial update, runs once during window's life
  unless @movable_initialized.is_a?(TrueClass)
   movable_initialize
   return
  end
  # The usual...
  movable_win_base_update
  # Automatically update "x_to" movement
  if @new_x.kind_of?(Numeric)
   if @new_x != self.x
    x_to(@new_x)
   end
  end
  # Automatically update "y_to" movement
  if @new_y.kind_of?(Numeric)
   if @new_y != self.y
    y_to(@new_y)
   end
  end
  # Automatically update "width_to" phasing
  if @new_width.kind_of?(Numeric)
   if @new_width != self.width
    width_to(@new_width)
   end
  end
  # Automatically update "height_to" phasing
  if @new_height.kind_of?(Numeric)
   if @new_height != self.height
    height_to(@new_height)
   end
  end
  # Automatically update "fade_z" phasing
  if @new_z.kind_of?(Numeric)
   if @new_z != self.z
    fade_z(@new_z)
   end
  end
  # Automatically update "fade_opacity" phasing
  if @new_o.kind_of?(Numeric)
   if @new_o != self.opacity
    fade_opacity(@new_o)
   end
  end
  # Automatically update "fade_contents" phasing
  if @new_co.kind_of?(Numeric)
   if @new_co != self.contents_opacity
    fade_contents(@new_co)
   end
  end
 end
 #-----------------------------------------------------------------------------
 # * Move To (X, Y, Speed, Opacity)
 #-----------------------------------------------------------------------------
 def move_to(new_x = self.x, new_y = self.y, delay = @delay, opacity = nil)
  x_to(new_x) unless new_x == self.x
  y_to(new_y) unless new_y == self.y
  fade_opacity(opacity, delay) unless opacity.nil?
 end
 #-----------------------------------------------------------------------------
 # * X Move To (Destination, Speed, Opacity)
 #-----------------------------------------------------------------------------
 def x_to(new_x = self.x, delay = @delay, opacity = nil)
  delay ||= 5
  unless self.x == new_x
   @new_x = new_x
   self.x -= ((self.x - new_x + 9) / delay).abs if self.x > new_x
   self.x += ((self.x - new_x + 0) / delay).abs if self.x < new_x
  else ; @new_x = nil
  end
  fade_opacity(opacity, delay) unless opacity.nil?
 end
 #-----------------------------------------------------------------------------
 # * Y Move To (Destination, Speed, Opacity)
 #-----------------------------------------------------------------------------
 def y_to(new_y = self.y, delay = @delay, opacity = nil)
  delay ||= 5
  unless self.y == new_y
   @new_y = new_y
   self.y -= ((self.y - new_y + 9) / delay).abs if self.y > new_y
   self.y += ((self.y - new_y + 0) / delay).abs if self.y < new_y
  else ; @new_y = nil
  end
  fade_opacity(opacity, delay) unless opacity.nil?
 end
 #-----------------------------------------------------------------------------
 # * Width To
 #-----------------------------------------------------------------------------
 def width_to(new_w = self.width, delay = @delay)
  delay ||= 5
  unless self.width == new_w
   @new_width = new_w
   self.width -= ((self.width + new_w) / delay).abs if self.width > new_w
   self.width += ((self.width + new_w) / delay).abs if self.width < new_w
  else ; @new_width = nil
  end
 end
 #-----------------------------------------------------------------------------
 # * Height To
 #-----------------------------------------------------------------------------
 def height_to(new_h = self.height, delay = @delay)
  delay ||= 5
  unless self.height == new_h
   @new_height = new_h
   self.height -= ((self.height - new_h + 9) / delay).abs if self.height > new_h
   self.height += ((self.height - new_h + 0) / delay).abs if self.height < new_h
   return
  else ; @new_height = nil
  end
 end
 #-----------------------------------------------------------------------------
 # * Fade Opacity (Opacity, Speed)
 #-----------------------------------------------------------------------------
 def fade_opacity(n = nil, delay = @delay)
  unless self.opacity == n || n.nil?
   @new_o = n
   self.opacity -= ((self.opacity - n) / delay).abs if self.opacity > n
   self.opacity += ((self.opacity - n) / delay).abs if self.opacity < n
  else ; @new_o = nil
  end
 end
 #-----------------------------------------------------------------------------
 # * Fade Contents (Opacity, Speed)
 #-----------------------------------------------------------------------------
 def fade_contents(n = nil, delay = @delay)
  unless self.contents_opacity == n || n.nil?
   @new_co = n
   if self.contents_opacity > n
    self.contents_opacity -= ((self.contents_opacity - n) / delay).abs
   elsif self.contents_opacity < n
    self.contents_opacity += ((self.contents_opacity + n) / delay).abs
   else
    @new_co = nil
   end
  end
 end
 #-----------------------------------------------------------------------------
 # * Fade Z
 #-----------------------------------------------------------------------------
 def fade_z(n, delay = @delay)
  unless self.z == n
   @new_z = n
   self.z -= ((self.z - n) / delay).abs if self.z > n
   self.z += ((self.z - n) / delay).abs if self.z < n
  else ; @new_z = nil
  end
 end
 #-----------------------------------------------------------------------------
 # * Set Position
 #-----------------------------------------------------------------------------
 def position(edge = 0, offset = 0)
  if edge.is_a?(Integer)
   if edge == 5 || edge == -5 || edge > 9 || edge < -9
    edge = 0
   end
  else ; return
  end
  o = offset.is_a?(Integer) ? offset : 0
  case edge
  when 0 # Center
   self.x, self.y = (320 - (self.width / 2)) , (240 - (self.height / 2))
  when 2 # Center Bottom
   self.x, self.y = (320 - (self.width / 2)) , (480 - (self.height))
   unless o.zero? ; self.y -= o ; end
  when 4 # Center Left
   self.x, self.y = 0             , (240 - (self.height / 2))
   unless o.zero? ; self.x += o ; end
  when 6 # Center Right
   self.x, self.y = (640 - self.width)    , (240 - (self.height / 2))
   unless o.zero? ; self.x -= o ; end
  when 8 # Center Top
   self.x, self.y = (320 - (self.width / 2)) , 0
   unless o.zero? ; self.y += o ; end
  when 1 # Lower Left
   self.x, self.y = (0)            , (480 - self.height)
   unless o.zero? ; self.x += o ; self.y -= o ; end
  when 3 # Lower Right
   self.x, self.y = (640 - self.width)    , (480 - self.height)
   unless o.zero? ; self.x -= o ; self.y -= o ; end
  when 7 # Upper Left
   self.x, self.y = 0             , 0
   unless o.zero? ; self.x += o ; self.y += o ; end
  when 9 # Upper Right
   self.x, self.y = 640 - self.width     , 0
   unless o.zero? ; self.x -= o ; self.y += o ; end
  when -2 # Center Bottom Outside
   self.x, self.y = (320 - (self.width / 2)) , 480
  when -4 # Center Left Outside
   self.x, self.y = (0 - self.width)     , (240 - (self.height / 2))
  when -6 # Center Right Outside
   self.x, self.y = (640 + self.width)    , (240 - (self.height / 2))
  when -8 # Center Top Outside
   self.x, self.y = (320 - (self.width / 2)) , (0 - self.height)
  when -1 # Lower Left Outside
   self.x, self.y = (0 - self.width)     , (480 + self.height)
  when -3 # Lower Right Outside
   self.x, self.y = (640 + self.width)    , (480 + self.height)
  when -7 # Upper Right Outside
   self.x, self.y = (0 - self.width)     , (0 - self.height)
  when -9 # Upper Left Outside
   self.x, self.y = (640 - self.width)    , (0 - self.height)
  end
 end
 #-----------------------------------------------------------------------------
 # * Move Pos
 #-----------------------------------------------------------------------------
 def pos_to(edge)
  if edge.is_a?(Integer)
   if edge == 5 || edge == -5 || edge > 9 || edge < -9
    edge = 0
   end
  else ; return
  end
  case edge
  when 0 # Center
   move_to(320 - (self.width / 2), 240 - (self.height / 2))
  when 2 # Center Bottom
   move_to(320 - (self.width / 2), 480 - self.height)
  when 4 # Center Left
   move_to(0, 240 - (self.height / 2))
  when 6 # Center Right
   move_to(640 - self.width, 240 - (self.height / 2))
  when 8 # Center Top
   move_to(320 - (self.width / 2), 0)
  when 1 # Lower Left
   move_to(0, 480 - self.height)
  when 3 # Lower Right
   move_to(640 - self.width, 480 - self.height)
  when 7 # Upper Left
   move_to(0, 0)
  when 9 # Upper Right
   move_to(640 - self.width, 0)
  when -2 # Center Bottom Outside
   move_to(320 - (self.width / 2), 480)
  when -4 # Center Left Outside
   move_to(0 - self.width, 240 - (self.height / 2))
  when -6 # Center Right Outside
   move_to(640 + self.width, 240 - (self.height / 2))
  when -8 # Center Top Outside
   move_to(320 - (self.width / 2) , 0 - self.height)
  when -1 # Lower Left Outside
   move_to(0 - self.width, 480 + self.height)
  when -3 # Lower Right Outside
   move_to(640 + self.width, 480 + self.height)
  when -7 # Upper Right Outside
   move_to(0 - self.width, 0 - self.height)
  when -9 # Upper Left Outside
   move_to(640 - self.width, 0 - self.height)
  end
 end
 #-----------------------------------------------------------------------------
 # * Centered X?
 #-----------------------------------------------------------------------------
 def x_center?
  return self.width_center_offset == 0
 end
 #-----------------------------------------------------------------------------
 # * Centered Y?
 #-----------------------------------------------------------------------------
 def y_center?
  return self.height_center_offset == 0
 end
 #-----------------------------------------------------------------------------
 # * Closest to Left?
 #-----------------------------------------------------------------------------
 def closest_to_left?
  return self.width_center_offset < 0
 end
 #-----------------------------------------------------------------------------
 # * Closest To Right?
 #-----------------------------------------------------------------------------
 def closest_to_right?
  return self.width_center_offset > 0
 end
 #-----------------------------------------------------------------------------
 # * Closest To Top?
 #-----------------------------------------------------------------------------
 def closest_to_top?
  return self.height_center_offset < 0
 end
 #-----------------------------------------------------------------------------
 # * Closest To Bottom?
 #-----------------------------------------------------------------------------
 def closest_to_bottom?
  return self.height_center_offset > 0
 end
 #-----------------------------------------------------------------------------
 # * Width Center Offset
 #-----------------------------------------------------------------------------
 def width_center_offset
  return -(320 - self.width)
 end
 #-----------------------------------------------------------------------------
 # * Height Center Offset
 #-----------------------------------------------------------------------------
 def height_center_offset
  return -(240 - self.height)
 end
 #-----------------------------------------------------------------------------
 # * Movement Animation Variables
 #-----------------------------------------------------------------------------
 def movement_animation_variables
  arr = Array.new
  arr << @new_x
  arr << @new_y
  arr << @new_width
  arr << @new_height
  arr << @new_z
  arr << @new_o
  arr << @new_co
  return arr
 end
 #-----------------------------------------------------------------------------
 # * Animation Nil?
 #-----------------------------------------------------------------------------
 def movement_nil?
  movement_animation_variables.each do |var|
   return false unless var.nil?
  end
  return true
 end
end
Â
#===============================================================================
# ** SDK::Scene_Base
#===============================================================================
Â
Â
class SDK::Scene_Base
 #-----------------------------------------------------------------------------
 # * Alias Listings
 #-----------------------------------------------------------------------------
 alias_method :winmovable_sdkscnbase_mainbreak?,  :main_break?
 alias_method :winmovable_sdkscnbase_maindispose,  :main_dispose
 #-----------------------------------------------------------------------------
 # * Each Window
 #-----------------------------------------------------------------------------
 def all_windows
  all_windows = Array.new
  self.instance_variables.each do |obj|
   object = eval obj
   if object.is_a?(Window) && object != all_windows
    all_windows << object
   end
  end
  return all_windows
 end
 #-----------------------------------------------------------------------------
 # * Main Animation In?
 #-----------------------------------------------------------------------------
 def window_movement_wait?
  all_windows.each do |win|
   return false if win.movement_nil?
  end
  return true
 end
 #-----------------------------------------------------------------------------
 # * Main Break?
 #-----------------------------------------------------------------------------
 def main_break?
  return winmovable_sdkscenebase_mainbreak? && !window_movement_wait?
 end
 #-----------------------------------------------------------------------------
 # * Main Dispose
 #-----------------------------------------------------------------------------
 def main_dispose
  #if window_movement_wait?
   loop do
    all_windows.each {|win| win.update}
    break if !window_movement_wait?
   end
  #end
  winmovable_sdkscnbase_maindispose
 end
end
Â
PS; If anybody has a better suggestion on how to dance with the Out-movement of the windows before the main_dispose, feel free to throw me a bone ! Thanks.