RPG Maker VX Ace
AnimEx

Sometimes when coming up with new scripts I hit a point where I think, well, it's a nice feature to use in this script, but it could also have some use as a stand-alone script.

This is one such script. I came up with the idea after someone suggested I should add diagonal animations to my Free Movement script, so, while I was at it, I could also work on adding support for sprites with more animation frames and for procedurally generated sprites. You know, for when someone creates a character editor. Like me.

I have too much time on my hands.

Download (21.69 kB, 1620 times downloaded)

Demo (1.32 MB, 441 times downloaded)

Before I begin, I would like to point out that this is mainly a developer tool. All basic features here are set in place so you as a developer can build upon it. However, I did implement a basic diagonal movement system that can be turned on or off. By default it's disabled, as the main focus doesn't lie there.

How the animations are displayed is dependent on the name of the resource. You have the standard name signs, like ! and $, but on top of that you'll have a few new options.

First of all, I've added support for Victor Engine's Multi Frames naming convention, where [f*] defines the amount of frames present on a character's animation, and where the asterix (*) defines the amount of frames.

On top of that though I've added a new way to define frames. Before I continue though it is needed to say that only the ! sign works here, and that is only if it's placed at the very beginning. Having said that, let's continue.

At the beginning of the filename, but after an optional !, you will need to use the following tag:

[index_cols, index_rows, anim_frames, anim_rows(, wrap_around?)]
index_cols   - The amount of characters per row
index_rows   - The amount of rows for each line of characters
anim_frames  - The amount of frames per character
anim_rows    - The amount of rows for each character
wrap_around? - If it wraps around the animation (optional, 0: off, 1: on)

When wrap_around is set to true, it will act like Victor's multi frames script, meaning when it reaches the end of the animation, instead of going backwards again, it will start again at the beginning.

With this script, you can place more characters on a sheet, although both the database as well as the events stop working correctly.

This script has support for diagonal sprites. There are two ways this is accomplished.

First, if there are eight or nine animation rows for a character, it uses the following table to determine which row it picks:

Bottom        (2):  0
Left          (4):  1
Right         (6):  2
Top           (8):  3
Bottom left   (1):  4
Top left      (7):  5
Bottom right  (3):  6
Top right     (9):  7
Center        (5):  8 if 9 rows, otherwise 0

In any other case, it will only use the first four rows to determine the row, where bottom left is 0, top left is 1, bottom right is 2 and top right is 3. To make use of diagonal sprites, one has to put diagonal sprites at the following index as in other diagonal sprite scripts. To define if a character has diagonal sprites, one has to set @has_diagonal to true. This setting is ignored if there are already eight or nine rows. For actors, one can also set a notetag.

<sprite has diagonal>

As said in the introduction, one can also use procedurally generated sprites. In order to do that, one needs a bitmap. When you have the bitmap ready, you can use the CXJ::ANIMEX::AnimBitmap class.

AnimBitmap.new(bitmap[,index_w[,index_h[,anim_w[,anim_h[,wrap_around]]]]])

If no argument other than the bitmap is used, it defaults to a regular eight character sprite sheet.

This script overrides several methods. If you are sure no method that is used by other scripts get overridden, you can place it anywhere, otherwise, make sure this script is loaded first. Do know that there is a possibility that this script will stop working due to that.

  • class Game_CharacterBase
    • update_anime_pattern
    • character_index
  • class Game_Player
    • move_by_input (when diagonal movement is enabled)
  • class Sprite_Character
    • update_bitmap
    • set_character_bitmap
    • update_src_rect(type)

This script adds aliases for several methods. If you are sure no method that is used by other scripts get overridden, you can place it anywhere, otherwise, make sure this script is loaded after any other script overriding these methods, otherwise this script stops working.

  • class Game_CharacterBase
    • init_public_members
    • refresh
    • move_diagonal(horz, vert) (when diagonal movement is enabled)
  • class Sprite_Character
    • graphic_changed?

Download AnimEx v1.00 (20.92 kB, 1553 times downloaded)

Download AnimEx Demo v1.00 (1.32 MB, 376 times downloaded)

#==============================================================================
# 
# GaryCXJk - AnimEx v1.00
# * Last Updated: 2013.01.05
# * Level: Medium
# * Requires: N/A
# 
#==============================================================================

$imported = {} if $imported.nil?
$imported["CXJ-AnimEx"] = true

#==============================================================================
#
# Changelog:
#
#------------------------------------------------------------------------------
# 2013.01.05 - v1.01
#
# * Fixed: Diagonal animation not showing up correctly on character sheets with
#           eight or nine rows and <sprite has diagonal> set.
#
#------------------------------------------------------------------------------
# 2013.01.04 - v1.00
#
# * Initial release
#
#==============================================================================
#
# Sometimes when coming up with new scripts I hit a point where I think, well,
# it's a nice feature to use in this script, but it could also have some use
# as a stand-alone script.
#
# This is one such script. I came up with the idea after someone suggested I
# should add diagonal animations to my Free Movement script, so, while I was
# at it, I could also work on adding support for sprites with more animation
# frames and for procedurally generated sprites. You know, for when someone
# creates a character editor. Like me.
#
# I have too much time on my hands.
#
#==============================================================================
#
# Installation:
#
# Make sure to put this below Materials, but above Main Process.
#
# This script overrides several methods. If you are sure no method that is
# used by other scripts get overridden, you can place it anywhere, otherwise,
# make sure this script is loaded first. Do know that there is a possibility
# that this script will stop working due to that.
#
# This script adds aliases for several methods. If you are sure no method that
# is used by other scripts get overridden, you can place it anywhere,
# otherwise, make sure this script is loaded after any other script overriding
# these methods, otherwise this script stops working.
#
#------------------------------------------------------------------------------
# Overridden functions:
#
# * class Game_CharacterBase
#   - update_anime_pattern
# * class Game_Player
#   - move_by_input (when diagonal movement is enabled)
# * class Sprite_Character
#   - update_bitmap
#   - set_character_bitmap
#   - update_src_rect
#
#------------------------------------------------------------------------------
# Aliased methods:
#
# * class Game_CharacterBase
#   - init_public_members
#   - refresh
#   - move_diagonal(horz, vert) (when diagonal movement is enabled)
# * class Sprite_Character
#   - graphic_changed?
#
#==============================================================================
#
# Usage:
#
# Before I begin, I would like to point out that this is mainly a developer
# tool. All basic features here are set in place so you as a developer can
# build upon it. However, I did implement a basic diagonal movement system
# that can be turned on or off. By default it's disabled, as the main focus
# doesn't lie there.
#
# How the animations are displayed is dependent on the name of the resource.
# You have the standard name signs, like ! and $, but on top of that you'll
# have a few new options.
#
# First of all, I've added support for Victor Engine's Multi Frames naming
# convention, where [f*] defines the amount of frames present on a character's
# animation, and where the asterix (*) defines the amount of frames.
#
# On top of that though I've added a new way to define frames. Before I
# continue though it is needed to say that only the ! sign works here, and
# that is only if it's placed at the very beginning. Having said that, let's
# continue.
#
# At the beginning of the filename, but after an optional !, you will need to
# use the following tag:
#
# [index_cols, index_rows, anim_frames, anim_rows(, wrap_around?)]
#
# index_cols   - The amount of characters per row
# index_rows   - The amount of rows for each line of characters
# anim_frames  - The amount of frames per character
# anim_rows    - The amount of rows for each character
# wrap_around? - If it wraps around the animation (optional, 0: off, 1: on)
#
# When wrap_around is set to true, it will act like Victor's multi frames
# script, meaning when it reaches the end of the animation, instead of going
# backwards again, it will start again at the beginning.
#
# With this script, you can place more characters on a sheet, although both
# the database as well as the events stop working correctly.
#
# This script has support for diagonal sprites. There are two ways this is
# accomplished.
#
# First, if there are eight or nine animation rows for a character, it uses
# the following table to determine which row it picks:
#
# Bottom        (2):  0
# Left          (4):  1
# Right         (6):  2
# Top           (8):  3
# Bottom left   (1):  4
# Top left      (7):  5
# Bottom right  (3):  6
# Top right     (9):  7
# Center        (5):  8 if 9 rows, otherwise 0
#
# In any other case, it will only use the first four rows to determine the
# row, where bottom left is 0, top left is 1, bottom right is 2 and top right
# is 3. To make use of diagonal sprites, one has to put diagonal sprites at
# the following index as in other diagonal sprite scripts. To define if a
# character has diagonal sprites, one has to set @has_diagonal to true. This
# setting is ignored if there are already eight or nine rows. For actors, one
# can also set a notetag.
#
# <sprite has diagonal>
#
# As said in the introduction, one can also use procedurally generated sprites.
# In order to do that, one needs a bitmap. When you have the bitmap ready,
# you can use the CXJ::ANIMEX::AnimBitmap class.
#
# AnimBitmap.new(bitmap[,index_w[,index_h[,anim_w[,anim_h[,wrap_around]]]]])
#
# If no argument other than the bitmap is used, it defaults to a regular eight
# character sprite sheet.
#
#==============================================================================
#
# License:
#
# Creative Commons Attribution 3.0 Unported
#
# The complete license can be read here:
# http://creativecommons.org/licenses/by/3.0/legalcode
#
# The license as it is described below can be read here:
# http://creativecommons.org/licenses/by/3.0/deed
#
# You are free:
#
# to Share — to copy, distribute and transmit the work
# to Remix — to adapt the work
# to make commercial use of the work
#
# Under the following conditions:
#
# Attribution — You must attribute the work in the manner specified by the
# author or licensor (but not in any way that suggests that they endorse you or
# your use of the work).
#
# With the understanding that:
#
# Waiver — Any of the above conditions can be waived if you get permission from
# the copyright holder.
#
# Public Domain — Where the work or any of its elements is in the public domain
# under applicable law, that status is in no way affected by the license.
#
# Other Rights — In no way are any of the following rights affected by the
# license:
#
# * Your fair dealing or fair use rights, or other applicable copyright
#   exceptions and limitations;
# * The author's moral rights;
# * Rights other persons may have either in the work itself or in how the work
#   is used, such as publicity or privacy rights.
#
# Notice — For any reuse or distribution, you must make clear to others the
# license terms of this work. The best way to do this is with a link to this
# web page.
#
#------------------------------------------------------------------------------
# Extra notes:
#
# Despite what the license tells you, I will not hunt down anybody who doesn't
# follow the license in regards to giving credits. However, as it is common
# courtesy to actually do give credits, it is recommended that you do.
#
# As I picked this license, you are free to share this script through any
# means, which includes hosting it on your own website, selling it on eBay and
# hang it in the bathroom as toilet paper. Well, not selling it on eBay, that's
# a dick move, but you are still free to redistribute the work.
#
# Yes, this license means that you can use it for both non-commercial as well
# as commercial software.
#
# You are free to pick the following names when you give credit:
#
# * GaryCXJk
# * Gary A.M. Kertopermono
# * G.A.M. Kertopermono
# * GARYCXJK
#
# Personally, when used in commercial games, I prefer you would use the second
# option. Not only will it actually give me more name recognition in real
# life, which also works well for my portfolio, it will also look more
# professional. Also, do note that I actually care about capitalization if you
# decide to use my username, meaning, capital C, capital X, capital J, lower
# case k. Yes, it might seem stupid, but it's one thing I absolutely care
# about.
#
# Finally, if you want my endorsement for your product, if it's good enough
# and I have the game in my posession, I might endorse it. Do note that if you
# give me the game for free, it will not affect my opinion of the game. It
# would be nice, but if I really did care for the game I'd actually purchase
# it. Remember, the best way to get any satisfaction is if you get people to
# purchase the game, so in a way, I prefer it if you don't actually give me
# a free copy.
#
# This script was originally hosted on:
# http://area91.multiverseworks.com
#
#==============================================================================
#
# The code below defines the settings of this script, and are there to be
# modified.
#
#==============================================================================

module CXJ
  module ANIMEX
    ENABLE_DIAGONAL_MOVEMENT = false
  end
end

#==============================================================================
#
# The code below should not be altered unless you know what you're doing.
#
#==============================================================================

module CXJ
  module ANIMEX
    #==========================================================================
    # ** CXJ::ANIMEX::AnimBitmap
    #--------------------------------------------------------------------------
    #  This class contains animation data for bitmaps.
    #==========================================================================
    class AnimBitmap
      attr_reader :bitmap
      attr_reader :index_w
      attr_reader :index_h
      attr_reader :anim_w
      attr_reader :anim_h
      attr_reader :wrap_around
      
      #----------------------------------------------------------------------
      # * New: Initialization
      #----------------------------------------------------------------------
      def initialize(bmp, ind_w = 4, ind_h = 2, ani_w = 3, ani_h = 4, wrap = true)
        @bitmap = bmp
        @index_w = ind_w
        @index_h = ind_h
        @anim_w = ani_w
        @anim_h = anim_h
        @wrap_around = wrap
      end
    end
  end
end

#==============================================================================
# ** Game_CharacterBase
#------------------------------------------------------------------------------
#  This base class handles characters. It retains basic information, such as 
# coordinates and graphics, shared by all characters.
#==============================================================================

class Game_CharacterBase
  attr_accessor :has_diagonal
  attr_accessor :anim_bitmap
  #--------------------------------------------------------------------------
  # * Alias: Initialize Public Member Variables
  #--------------------------------------------------------------------------
  alias game_characterbase_init_public_members_cxj_animex init_public_members
  def init_public_members
    game_characterbase_init_public_members_cxj_animex
    @anim_bitmap = nil
    @has_diagonal = false
  end
  #--------------------------------------------------------------------------
  # * Override: Update Animation Pattern
  #--------------------------------------------------------------------------
  def update_anime_pattern
    if !@step_anime && @stop_count > 0
      @pattern = @original_pattern
    elsif !@anim_bitmap.nil?
      if @anim_bitmap.wrap_around
        @pattern = @pattern % @anim_bitmap.anim_w
      else
        @pattern = (@pattern + 1) % [((@anim_bitmap.anim_w - 1) * 2), 1].max
      end
    elsif @character_name =~ /\[f(\d+)\]/
      @pattern = (@pattern + 1) % $1.to_i
    else
      @pattern = (@pattern + 1) % 4
    end
  end
  #--------------------------------------------------------------------------
  # * New: Animation Row
  #--------------------------------------------------------------------------
  def animation_row
    if(!@anim_bitmap.nil?)
      if([8, 9].include?(@anim_bitmap.anim_h))
        animrows = [4, 0, 6, 1, (@anim_bitmap.anim_h == 9 ? 8 : 0), 2, 5, 3, 7]
        return animrows[@direction - 1]
      end
    elsif @character_name =~ /^\!?\[(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*(1|0))?\]/
      if([8, 9].include?($4.to_i))
        animrows = [4, 0, 6, 1, ($4.to_i == 9 ? 8 : 0), 2, 5, 3, 7]
        return animrows[@direction - 1]
      end
    end
    if(@direction % 2 != 0)
      case @direction
      when 1
        return 0
      when 3
        return 2
      when 7
        return 1
      when 9
        return 3
      end
    end
    return (@direction - 2) / 2
  end
  
  #--------------------------------------------------------------------------
  # * New: Is Regular Sprite?
  #--------------------------------------------------------------------------
  def is_regular_sprite?
    if(!@anim_bitmap.nil?)
      if([8, 9].include?(@anim_bitmap.anim_h))
        return false
      end
    elsif @character_name =~ /^\!?\[(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*(1|0))?\]/
      if([8, 9].include?($4.to_i))
        return false
      end
    end
    return true
  end
  
  #--------------------------------------------------------------------------
  # * Override: Character Index
  #--------------------------------------------------------------------------
  def character_index
    is_regular_sprite? && @has_diagonal && @direction % 2 != 0 ? @character_index + 1 : @character_index
  end
end

#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
#  This class handles the player. It includes event starting determinants and
# map scrolling functions. The instance of this class is referenced by
# $game_player.
#==============================================================================

class Game_Player < Game_Character
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  alias game_player_refresh_cxj_animex refresh
  def refresh
    game_player_refresh_cxj_animex
    if actor.actor.note =~ /<sprite has diagonal>/
      @has_diagonal = true
    else
      @has_diagonal = false
    end
  end
end

#==============================================================================
# ** Game_Follower
#------------------------------------------------------------------------------
#  This class handles followers. A follower is an allied character, other than
# the front character, displayed in the party. It is referenced within the
# Game_Followers class.
#==============================================================================

class Game_Follower < Game_Character
  #--------------------------------------------------------------------------
  # * Alias: Refresh
  #--------------------------------------------------------------------------
  alias game_follower_refresh_cxj_animex refresh
  def refresh
    game_follower_refresh_cxj_animex
    if !actor.nil? && actor.actor.note =~ /<sprite has diagonal>/
      @has_diagonal = true
    else
      @has_diagonal = false
    end
  end
end

#==============================================================================
# ** Sprite_Character
#------------------------------------------------------------------------------
#  This sprite is used to display characters. It observes an instance of the
# Game_Character class and automatically changes sprite state.
#==============================================================================

class Sprite_Character < Sprite_Base
  #--------------------------------------------------------------------------
  # * Override: Update Transfer Origin Bitmap
  #--------------------------------------------------------------------------
  def update_bitmap
    if graphic_changed?
      @tile_id = @character.tile_id
      @character_name = @character.character_name
      @character_index = @character.character_index
      @anim_bitmap = @character.anim_bitmap
      if @tile_id > 0
        set_tile_bitmap
      else
        set_character_bitmap
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Alias: Determine if Graphic Changed
  #--------------------------------------------------------------------------
  alias sprite_character_graphic_changed_cxj_animex? graphic_changed?
  def graphic_changed?
    @anim_bitmap != @character.anim_bitmap ||
    sprite_character_graphic_changed_cxj_animex?
  end
  #--------------------------------------------------------------------------
  # * Override: Set Character Bitmap
  #--------------------------------------------------------------------------
  def set_character_bitmap
    @wrap_around = false
    if !@anim_bitmap.nil?
      bmp = @anim_bitmap.bitmap
      self.bitmap = Bitmap.new(bmp.width, bmp.height)
      self.bitmap.blt(0, 0, bmp, bmp.rect)
      @iw = @anim_bitmap.index_w
      @ih = @anim_bitmap.index_h
      @aw = @anim_bitmap.anim_w
      @ah = @anim_bitmap.anim_h
      @wrap_around = @anim_bitmap.wrap_around
    else
      self.bitmap = Cache.character(@character_name)
      if @character_name =~ /^\!?\[(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)(?:\s*,\s*(1|0))?\]/
        @iw = $1.to_i
        @ih = $2.to_i
        @aw = $3.to_i
        @ah = $4.to_i
        @wrap_around = true if $5 == "1"
      else
        @aw = 3
        @ah = 4
        if @character_name =~ /\[f(\d+)\]/
          @ah = $1.to_i
          @wrap_around = true
        end
        sign = @character_name[/^[\!\$]./]
        if sign && sign.include?('$')
          @iw = 1
          @ih = 1
        else
          @iw = 4
          @ih = 2
        end
      end
    end
    @cw = bitmap.width / (@iw * @aw)
    @ch = bitmap.height / (@ih * @ah)
    self.ox = @cw / 2
    self.oy = @ch
  end
  #--------------------------------------------------------------------------
  # * Override: Update Transfer Origin Rectangle
  #--------------------------------------------------------------------------
  def update_src_rect
    if @tile_id == 0
      index = @character.character_index
      pattern = @character.pattern
      pattern = 2 * @aw - pattern - 2 if pattern >= @aw && !@wrap_around
      sx = (index % @iw * @aw + pattern) * @cw
      sy = (index / @iw * @ah + @character.animation_row) * @ch
      self.src_rect.set(sx, sy, @cw, @ch)
    end
  end
end
#==============================================================================
# The following enables if diagonal movement is enabled.
#==============================================================================
if CXJ::ANIMEX::ENABLE_DIAGONAL_MOVEMENT

  #============================================================================
  # ** Game_CharacterBase
  #----------------------------------------------------------------------------
  #  This base class handles characters. It retains basic information, such as 
  # coordinates and graphics, shared by all characters.
  #============================================================================

  class Game_CharacterBase
    #------------------------------------------------------------------------
    # * Alias: Move Diagonally
    #     horz:  Horizontal (4 or 6)
    #     vert:  Vertical (2 or 8)
    #------------------------------------------------------------------------
    alias game_characterbase_move_diagonal_cxj_animex move_diagonal
    def move_diagonal(horz, vert)
      game_characterbase_move_diagonal_cxj_animex(horz, vert)
      d = (horz == 6 ? 1 : horz == 4 ? -1 : 0) + (vert == 0 ? 5 : vert)
      set_direction(d)
    end
  end

  #==============================================================================
  # ** Game_Player
  #------------------------------------------------------------------------------
  #  This class handles the player. It includes event starting determinants and
  # map scrolling functions. The instance of this class is referenced by
  # $game_player.
  #==============================================================================

  class Game_Player < Game_Character
    #--------------------------------------------------------------------------
    # * Override: Processing of Movement via Input from Directional Buttons
    #--------------------------------------------------------------------------
    def move_by_input
      return if !movable? || $game_map.interpreter.running?
      d = Input.dir8
      if Input.dir4 > 0 && d == 0
        move_straight(Input.dir4)
      else
        return if d == 0
        horz = (d - 1) % 3 + 4
        vert = (d > 6 ? 8 : d < 4 ? 2 : 5)
        move_diagonal(horz, vert)
      end
    end
  end
end                                
AnimEx

Creator: GaryCXJk

Release date: 2013-01-04

Last updated: 2013-01-05

Downloads: 1620

License: Creative Commons Attribution 4.0 International Public License