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, 1836 times downloaded)
Demo (1.32 MB, 489 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, 1742 times downloaded)
Download AnimEx Demo v1.00 (1.32 MB, 420 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