Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

VX Animated State Icons

Animated State Icons Version: 1.0
By: Racheal

Introduction
Ever wanted to display more state icons then there's space for? Then this script might help. Instead of the default row of icons, this script displays them all in one spot, cross-fading between each one.

Features
  • Can be applied every time a state is drawn or just where you want it to be
  • Customize the speed of the cross-fade and wait count between states
  • Optional: Display an icon for "normal" aka no state

Screenshots

Since the script is all about animation, it's a little hard to show with a stationary screenshot. So instead, here's a gif of approximately what it looks like:
states.gif


Script

[rgss]#==============================================================================
# Animated State Icons
# by: Racheal
# Version 1.0
# Created: 02/04/2010
#==============================================================================
# Displays states as one animated sprite instead of a row of icons
#==============================================================================
# Instructions:
# * Insert in the Materials section
#   (though it should work anywhere below Window_Base and above Main)
# * Four constants in module AnimatedStates are editable; see comments below
#==============================================================================
# Compatibility:
# * Alias 8 Window_Base functions: initialize, dispose, update,
#                                  visible=, viewport=, x=, y=
#                                  and draw_actor_state
# * Overwrites nothing
#==============================================================================
 
module AnimatedStates
  #-------------------------------CUSTOMIZATION--------------------------------
 
  # icon index for "Normal" aka no status. Set it to a blank icon if you
  # do not want an icon for Normal. To determine the icon index of an icon
  # count left to right, starting from 0, in the icon set file.
  # (There are 16 icons per row)
  NORMAL_STATUS = 0
 
  # Amount opacity is changed per frame; higher number = faster cross fade
  # Value must be between 1 and 255
  OPACITY_STEP = 5
 
  # Number of frames current state is displayed before starting cross-fade
  # into next state
  WAIT = 60
 
  # If set to true, all draw_actor_states draw animated icons.
  # If you want some state draws to be animated, and some to be the old
  # stationary style, set this to false and call the function
  # draw_animated_state(battler, x, y)
  # instead of draw_actor_state(actor, x, y, width = 96)
  # when you want to use animated state icons.
  ANIMATE_ALWAYS = true
 
  #---------------------------END CUSTOMIZATION--------------------------------
end
 
#==============================================================================
# Sprite_States
#==============================================================================
 
class Sprite_States < Sprite_Base
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :battler
  #--------------------------------------------------------------------------
  # * Object Initialization
  #     viewport : viewport
  #     battler  : battler (Game_Battler)
  #--------------------------------------------------------------------------
  def initialize(viewport, battler = nil)
    super(viewport)
    @battler = battler
    @state_index = -2
    @win_x = @win_y = 0
    @wait_count = AnimatedStates::WAIT
    self.bitmap = Cache.system("Iconset")
    @next_state = Sprite_Base.new(viewport)
    @next_state.bitmap = Cache.system("Iconset")
    start_state
    update
  end
  #--------------------------------------------------------------------------
  # * Dispose
  #--------------------------------------------------------------------------
  def dispose
    @battler = nil
    @next_state.dispose
    super
  end
  #--------------------------------------------------------------------------
  # * Set Window Cordinates
  #--------------------------------------------------------------------------
  def set_window_cord (x, y)
    self.x -= @win_x
    self.y -= @win_y
    @win_x = x
    @win_y = y
    self.x += @win_x
    self.y += @win_y
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # Update Next State icons based on self
    @next_state.x = self.x
    @next_state.y = self.y
    @next_state.ox = self.ox
    @next_state.oy = self.oy
    @next_state.z = self.z + 5
    @next_state.viewport = self.viewport
    @next_state.visible = self.visible
    # Do not display if not battler
    if @battler == nil
      @state_index = -2
      self.opacity = 0
      @next_state.opacity = 0
    else
      return unless self.visible # Don't update if not visible
      if @state_index != -2
        if @next_state.opacity > 0
          update_fade
        else
          if @wait_count == 0
            update_state
            @wait_count = AnimatedStates::WAIT
          else
            @wait_count -= 1
          end
        end
      else # Set icon to current state, no fading
        start_state
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Start State Display
  #--------------------------------------------------------------------------
  def start_state
    if @battler == nil or @battler.states.size == 0 # Normal Status
      set_current_state(AnimatedStates::NORMAL_STATUS)
      @state_index = -1
    else
      set_current_state(@battler.states[0].icon_index)
      @state_index = 0
    end
    set_next_state(AnimatedStates::NORMAL_STATUS)
    self.opacity = 255
    @next_state.opacity = 0
  end
  #--------------------------------------------------------------------------
  # * Update State Display
  #--------------------------------------------------------------------------
  def update_state
    return if @battler == nil
    states = @battler.states
    if states.size == 0
      return if @state_index == -1
      set_next_state(AnimatedStates::NORMAL_STATUS)
      @state_index = -1
    else
      return if states.size == 1 and @state_index == 0 # Don't animate if only 1 status
      @state_index += 1
      @state_index = 0 if @state_index >= states.size
      set_next_state(states[@state_index].icon_index)
      @state_index = @state_index
    end
    update_fade
  end
  #--------------------------------------------------------------------------
  # * Update Fading between states
  #--------------------------------------------------------------------------
  def update_fade
    @next_state.opacity += AnimatedStates::OPACITY_STEP
    self.opacity -= AnimatedStates::OPACITY_STEP
    if @next_state.opacity == 255
      self.src_rect = @next_state.src_rect
      self.opacity = 255
      @next_state.opacity = 0
    end
  end
  #--------------------------------------------------------------------------
  # * Set Current Icon
  #--------------------------------------------------------------------------
  def set_current_state(icon_index)
    self.src_rect.set(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
  end
  #--------------------------------------------------------------------------
  # * Set Next Icon
  #--------------------------------------------------------------------------
  def set_next_state(icon_index)
    @next_state.src_rect.set(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
  end
end
 
#==============================================================================
# Base Window Edit
#==============================================================================
 
class Window_Base < Window    
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  alias animstate_old_init initialize
  def initialize(x, y, width, height)
    @anim_states = []
    animstate_old_init(x, y, width, height)
  end
  #--------------------------------------------------------------------------
  # * Dispose
  #--------------------------------------------------------------------------
  alias animstate_old_dispose dispose
  def dispose
    animstate_old_dispose
    for state in @anim_states
      state.dispose if state != nil
    end
  end
  #--------------------------------------------------------------------------
  # * Set Visible
  #--------------------------------------------------------------------------
  alias animstate_old_visible visible=
  def visible= (visibility)
    animstate_old_visible(visibility)
    update_all_state_sprites
  end
  #--------------------------------------------------------------------------
  # * Set Viewport
  #--------------------------------------------------------------------------
  alias animstate_old_viewport viewport=
  def viewport= (view)
    animstate_old_viewport(view)
    update_all_state_sprites
  end
  #--------------------------------------------------------------------------
  # * Set X
  #--------------------------------------------------------------------------
  alias animstate_old_x x=
  def x= (x)
    animstate_old_x(x)
    update_all_state_sprites
  end
  #--------------------------------------------------------------------------
  # * Set Y
  #--------------------------------------------------------------------------
  alias animstate_old_y y=
  def y= (y)
    animstate_old_y(y)
    update_all_state_sprites
  end
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  alias animstate_old_update update
  def update
    animstate_old_update
    update_all_state_sprites
  end
  #--------------------------------------------------------------------------
  # * Update All State Sprites
  #--------------------------------------------------------------------------
  def update_all_state_sprites
    for i in 0...@anim_states.size
      update_state_sprite(i)
    end
  end
  #--------------------------------------------------------------------------
  # * Update State Sprite
  #--------------------------------------------------------------------------
  def update_state_sprite(index)
    state = @anim_states[index]
    return if state == nil
    state.viewport = self.viewport
    if self.viewport != nil
      state.visible = (self.visible and self.viewport.visible)
    else
      state.visible = self.visible
    end
    state.set_window_cord(self.x, self.y)
    state.ox = self.ox
    state.oy = self.oy
    state.visible = state.visible and sprite_in_bounds?(state)
    state.z = self.z + 5
    state.update
  end
  #--------------------------------------------------------------------------
  # * Sprites in Bounds?
  #      determine is sprite is within the window
  #--------------------------------------------------------------------------
  def sprite_in_bounds?(sprite)
    return false unless (sprite.x - sprite.ox) >= self.x
    return false unless (sprite.y - sprite.oy) >= self.y
    return false unless (sprite.x - sprite.ox) <= (self.x + self.width)
    return false unless (sprite.y - sprite.oy) <= (self.y + self.height)
    return true
  end
  #--------------------------------------------------------------------------
  # * Draw Animated State
  #--------------------------------------------------------------------------
  def draw_animated_state(battler, x, y)
    # Check if battler's state is already drawn
    for i in 0...@anim_states.size
      if @anim_states.battler.index == battler.index
        @anim_states.x = x + self.x + 16
        @anim_states.y = y + self.y + 16
        return
      end
    end
    viewp = self.viewport == nil ? Viewport.new(0, 0, 544, 416) : self.viewport
    new_state = Sprite_States.new(viewp, battler)
    new_state.x = x + 16
    new_state.y = y + 16
    @anim_states.push(new_state)
    update_state_sprite(@anim_states.size - 1)
  end
  #--------------------------------------------------------------------------
  # * Draw State
  #--------------------------------------------------------------------------
  alias animstate_old_draw_state draw_actor_state
  def draw_actor_state(actor, x, y, width = 96)
    if AnimatedStates::ANIMATE_ALWAYS
      draw_animated_state(actor, x, y)
    else
      animstate_old_draw_state(actor, x, y, width)
    end
  end
end
[/rgss]

Instructions

Copy-Paste above Main but below Window_Base.

Most of the cutomization options are explained in the script.

Compatibility

Doesn't overwrite anything so should be compatible with most anything.

Author's Notes

This is the first script I've released publically outside of a old tiny little thing, but I tried to make it as user friendly as I could. I spent a few hours testing and squashing bugs, but please let me know if you encounter any issues.

Terms and Conditions

Free for non-commercial use, though I do request you credit me.
If you want to use it for commercial use, please contact me via pm.
 
Nice idea, nice scripting, nice thread... thumbs up from me (which I think means something :p ).

The only things you could improve are the customization constants (in my opinion totally unneeded - everyone not satisfied with the default could easily find those values within the script anyway) and not making update_state_sprite() a seperate method, as it's only called in one place (if I'm not mistaken) and therefore doesn't need it's own definition.
As far as the thread goes, you don't need a spoiler around code tags... that's why they're shut by default ^^

Keep up the good work, it's definately rare to see well executed (as well as commented, for that matter) scripts in here!
 

leech

Member

I get a bug whenever I use F12 to return to the Title Menu... I added unless $@ to the end of all of your aliases,
but the error still persists...


EDIT: NVM. Was incompatibility with KGC_DrawFormatText... my bad.

Also, there seems to be a small bug if you apply states via events. Upon entering battle, your states don't
animate.

I am using Enu's Sideview Battle System 3.3d + the ATB 1.1i script, which could be the cause of the problem.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top