Animated Sprites instead of Faces
Version: 1.1
Author: modern algebra
Date: January 1, 2011
Version History
- <Version 1.1> 01.01.2011 - Added features to control zoom, opacity, blend type, and angle of the sprite
- <Version 1.0> 02.19.2010 - Original Release
Description
This script allows you to draw an actor's sprite in any scene that already draws the actor's face. You can either use it to supplement the face graphic or replace the face graphic altogether. For each scene where you choose to use this feature, you can configure a number of options, such as where the sprite will show up (in relation to the face graphic), how big it will be, its opacity, whether or not the face will also be drawn, what pose the sprite will start in, whether it will be animated, whether it will change directions (and if so, over what time interval), and if subsequently drawn sprites should be drawn in a different pose.
Features
- Can show an actor's sprite to supplement or replace an actor's face graphic in any scene
- You can choose to have the sprites animated or stationary and, if animated, what speed they animate at
- You can choose what direction the sprites face, as well as turn on or off a feature to have the sprites change directions every so often; you also have an option where sprites drawn in the same window will start facing different directions, if you want it.
- Can choose the position where the sprite shows up
- Can choose the size of the sprite (zoom), its opacity, its angle, and its blend type
- All of the above can be customized on a scene to scene basis. Not only can you choose not to include this script in some scenes, but you can customize how it operates in the scenes you do want it in
ScreenshotsMenu: Supplement face; Animated; Alternate Start Pose; Change Directions; X Offset +32
Status: Remove face; Animated; Y Offset -24; Zoom 150
Instructions Place this script in its own slot below Materials and above Main in the Script Editor (F11). For detailed instructions on configuration, see the EDITABLE REGION at line 30.
Script
#==============================================================================
# Animated Sprites instead of Faces in scenes.
# Version: 1.1
# Author: modern algebra (rmrk.net)
# Date: January 1, 2011
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Description:
#
# This script allows you to draw an actor's sprite in any scene that already
# draws the actor's face. You can either use it to supplement the face
# graphic or replace the face graphic altogether. For each scene where you
# choose to use this feature, you can configure a number of options, such as
# where the sprite will show up (in relation to the face graphic), how big it
# will be, its opacity, whether or not the face will also be drawn, what pose
# the sprite will start in, whether it will be animated, whether it will
# change directions (and if so, over what time interval), and if subsequently
# drawn sprites should be drawn in a different initial pose.
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Instructions:
#
# Place this script in its own slot below Materials and above Main in the
# Script Editor (F11).
#
# To add a scene and configure how the sprites will show up in it, read the
# instructions in the EDITABLE REGION at line 30 very carefully.
#==============================================================================
ASF_CONFIGURATION = {
#\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
# EDITABLE REGION
#````````````````````````````````````````````````````````````````````````````
# For each scene that you want the faces to be replaced (or supplemented) by
# sprites, set up an entry as follows (values are default), omitting any that
# you want to be default (pay attention to commas and curly brackets):
#
# Scene_X => {
# :x_offset => 0,
# :y_offset => 0,
# :zoom => 100,
# :remove_face => false,
# :default_start_pose => 0,
# :alternate_start_pose => false,
# :change_directions => false,
# :direction_frames => 120,
# :animate_sprites => false,
# :move_speed => 4,
# :opacity => 255,
# :blend_type => 0,
# :angle => 0,
# },
#
# where:
# Scene_X ~ the name of the scene. eg Scene_Menu; Scene_Battle; Scene_Name
# :x_offset ~ an integer, representing how many pixels left or right it
# should be moved from the center of where the face would be drawn.
# Positive numbers will be drawn right of that, and negative numbers drawn
# left of that. If excluded, it defaults to 0.
# :y_offset ~ an integer, representing how many pixels up or down it should
# be moved from the bottom of where the face would be drawn. If negative,
# it will be drawn higher and if positive, it will be drawn lower. If
# excluded, it defaults to 0.
# :zoom ~ an integer, representing percent zoom along the x axis. 100 is
# 100%, meaning it will be normal size. 200% would be twice its normal
# size, etc... Defaults to 100
# :remove_face ~ a boolean. If true, the face won't be drawn. If false, the
# face will be drawn along with the sprite. Defaults to false.
# :default_start_pose ~ an integer, 0-3. This is the starting pose of the
# first drawn sprite. 0 => Down; 1 => Right; 2 => Up; 3 => Left. If
# excluded, defaults to 0.
# :alternate_start_pose ~ a boolean. If true, then each time a new sprite
# is drawn, its start position will differ. So, if you have three actor
# sprites are being drawn, and the default start pose is 0 (Down), then
# the first sprite would start facing down, the second sprite would
# start facing Right, and the third sprite would start facing Up. If
# excluded, defaults to false
# :change_directions ~ a boolean. If true, the sprites would change
# over the time interval set in :direction_frames. If false, the sprites
# will only face one direction for the duration of the scene. If excluded,
# defaults to false
# :direction_frames ~ an integer. If :change_directions is true, this
# integer will determine the number of frames before the sprite changes
# direction. 60 frames = 1 second. If excluded, defaults to 120.
# :animate_sprites ~ a boolean. If true, the sprites will be shown walking.
# If false, they will remain stationary. If excluded, defaults to false.
# :move_speed ~ an integer, 1-6. If :animate_sprites is true, this is
# the speed that the sprite will be animating. 1 is the slowest and 6 is
# the fastest. Defaults to 4
# :opacity ~ an integer between 0 and 255. This is a scale, with 0 being
# totally transparent and 255 totally opaque. Defaults to 255.
# :blend_type ~ Either 0, 1, or 2. 0 => normal, 1 => addition;
# 2 => subtraction. Defaults to 0 if excluded
# :angle ~ an integer between 0 and 360. This corresponds to degrees on a
# circle. For instance, 0 is rightside up, 180 is upside down, etc...
# If excluded, defaults to 0.
#
# If you get a syntax error when test playing your game, you most likely
# forgot to put a comma or curly bracket in. If you set up entries for more
# than one scene, you need to put a comma after each } except for the last
# entry. For all of the attributes you specify in each scene entry, you need
# a comma after the value except for the last entry.
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Scene_Menu => {
:x_offset => 32,
:y_offset => 0,
:remove_face => false,
:default_start_pose => 0,
:alternate_start_pose => true,
:animate_sprites => true,
:move_speed => 1,
:change_directions => true,
:direction_frames => 120,
},
Scene_Status => {
:x_offset => 0,
:y_offset => -24,
:zoom => 150,
:remove_face => true,
:default_start_pose => 0,
:animate_sprites => true,
},
#||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# END EDITABLE REGION
#////////////////////////////////////////////////////////////////////////////
}
#==============================================================================
# ** Bitmap
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# new attr_accessor - asf_just_cleared
# aliased method - clear
#==============================================================================
class Bitmap
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Public Instance Variable
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
attr_accessor :asf_just_cleared
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Clear
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias mala_wlksprtmnu_clr_2gc1 clear unless self.method_defined? (:mala_wlksprtmnu_clr_2gc1)
def clear (*args)
mala_wlksprtmnu_clr_2gc1 (*args) # Run Original Method
@asf_just_cleared = true
end
end
#==============================================================================
# ** Game_Character
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Compatibility patch for Composite Characters
#==============================================================================
class Game_Character
attr_writer :composite_character if self.method_defined? (:composite_character)
end
#==============================================================================
# ** Sprite_MenuActor
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This window displays the walking sprite of an actor.
#==============================================================================
class Sprite_MenuActor < Sprite_Character
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def initialize (actor_id, x, y, dir, config, viewport = nil)
@frame_count = 0
@change_direction, @asf_animation = config[:change_directions], config[:animate_sprites]
@direction_frames = config[:direction_frames].is_a? (Integer) ? config[:direction_frames] : 120
actor = $game_actors[actor_id]
character = Game_Character.new
# Set to composite character if that script exists.
if character.methods.include? ("composite_character")
character.composite_character = actor.composite_character
else
character.set_graphic (actor.character_name, actor.character_index)
end
super (viewport, character)
self.x, self.y = x, y
case dir
when 1 then @character.turn_right
when 2 then @character.turn_up
when 3 then @character.turn_left
end
# Change sprite properties
self.zoom_x = self.zoom_y = config[:zoom].to_f / 100.0 if config[:zoom]
self.opacity = config[:opacity] if config[:opacity]
self.angle = config[:angle] if config[:angle]
self.blend_type = config[:blend_type] if config[:blend_type]
# Change Speed and Frequency of the Sprite
freq = config[:move_speed] ? config[:move_speed] : 4
move_route = RPG::MoveRoute.new
move_route.list.unshift (RPG::MoveCommand.new (29, [freq]))
@character.force_move_route (move_route)
update_bitmap
update
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Frame Update
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def update
# Turn at user-specified intervals
if @change_direction
if @frame_count >= @direction_frames
@character.turn_right_90
@frame_count = 0
end
@frame_count += 1
end
if @asf_animation
@character.update_move
@character.update_animation
end
update_src_rect
end
end
#==============================================================================
# ** Window_Base
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Summary of Changes:
# aliased methods - initialize, update, dispose, draw_actor_face
# new methods - dispose_walking_sprites
#==============================================================================
class Window_Base
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Object Initialization
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias ma_asf_init_wlkng_7jk2 initialize
def initialize (*args)
@ma_walking_sprites = []
ma_asf_init_wlkng_7jk2 (*args) # Run Original Method
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Dispose
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias malgba_wlksprts_disps_5yu2 dispose
def dispose (*args)
@ma_walking_sprites.each { |sprite| sprite.dispose }
@ma_walking_sprites.clear
malgba_wlksprts_disps_5yu2 (*args) # Run Original Method
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Frame Update
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias mrnalb_sprtwlk_updt_7uj2 update
def update (*args)
# Dispose all sprites if bitmap recently cleared and new faces not drawn
if self.contents.asf_just_cleared
@ma_walking_sprites.each { |sprite| sprite.dispose }
@ma_walking_sprites.clear
self.contents.asf_just_cleared = false
end
# Check if contents have scrolled
x_plus, y_plus = 0, 0
if @asf_scroll_x != self.ox
@asf_scroll_x = 0 unless @asf_scroll_x
x_plus += (@asf_scroll_x - self.ox)
@asf_scroll_x = self.ox
end
if @asf_scroll_y != self.oy
@asf_scroll_y = 0 unless @asf_scroll_y
y_plus += (@asf_scroll_y - self.oy)
@asf_scroll_y = self.oy
end
@ma_walking_sprites.each { |sprite|
sprite.update
# Scroll if contents have scrolled.
sprite.x += x_plus
sprite.y += y_plus
}
mrnalb_sprtwlk_updt_7uj2 (*args) # Run Original Method
end
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# * Draw Actor Face Graphic
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
alias malg_drwactrface_spritereplce_6uj2 draw_actor_face
def draw_actor_face(actor, x, y, size = 96, *args)
# If scene is specified to replace the face graphic
if ASF_CONFIGURATION.keys.include? ($scene.class)
# Dispose all sprites if bitmap recently cleared
if self.contents.asf_just_cleared
@ma_walking_sprites.each { |sprite| sprite.dispose }
@ma_walking_sprites.clear
self.contents.asf_just_cleared = false
end
config = ASF_CONFIGURATION[$scene.class]
malg_drwactrface_spritereplce_6uj2 (actor, x, y, size, *args) unless config[:remove_face]
# Get offset
x_off = config[:x_offset] ? config[:x_offset] : 0
y_off = config[:y_offset] ? config[:y_offset] : 0
sx = x + (size / 2) + x_off
sy = y + size + y_off
pose = config[:default_start_pose] ? config[:default_start_pose] : 0
dir = config[:alternate_start_pose] ? @ma_walking_sprites.size % 4 : pose
# Create Sprite
viewport = Viewport.new (self.x + 16, self.y + 16, contents.width, contents.height)
viewport.z = self.z + 50
viewport.z += self.viewport.z if self.viewport
sprite = Sprite_MenuActor.new (actor.id, sx, sy, dir, config, viewport)
@ma_walking_sprites.push (sprite)
else
# Draw face if scene not affected
malg_drwactrface_spritereplce_6uj2 (actor, x, y, size, *args)
end
end
end
Credit
Thanks
- Kyle?, for the request
- kirinelf, for requesting the zoom feature
Support
Please post in this topic at RMRK.net for support. Please do not PM me, as any issues you may be having someone else will be having too, and I want them to see the solution.
Known Compatibility Issues
No known compatibility issues. Note, however, that it only works with scripts that use the Draw Actor Face method of Window_Base. The default scenes that do that are Scene_Menu, Scene_Status, Scene_Battle, and Scene_Name. It should work with custom scripts that use that method as well, but not with scenes that select faces directly (such as the message window of Scene_Map).
Author's Notes
If anyone wants me to add a feature so that it would work even in scenes where the regular draw_face (not draw_actor_face) method is called, I can. You suggest the implementation. I was thinking that for it, I would just use the name and index of the face graphic and call the character sprite from that. If you want it but think another implementation would be better, feel free to suggest one.
This script by
modern algebra is licensed under a
Creative Commons Attribution-Non-Commercial-Share Alike 2.5 Canada License.