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.

Character Transitions (More eye-candy !)

@Sir Lord Biowulve
this error was discussed above and solved.

not for me.. i?ve done everything.. switches the varaible to true... check alle settings..etc.. nothings works...

Kuri$u has the same fault..
 
Maybe you should make one for like teleporting? Like on DBZ or Naruto..Like when they dash and dissappear and re-appear somewhere else?
 
McP;209206 said:
Yeah thats a nice script, but i keep getting errors with non rtp characters.
I get the message: Error in character transition: File "whatever".png not found.
Even if I put the character graphic into the rtp folder i get this message.
It works with all rtp charas though.. any idea?

I get this same error. I have no idea what could be causing it.

EDIT: Thanks rataime. Your scripts make everything sexier.
 
I have updated the demo to version 1.1 (link in the first post)

You now can load from a local file (a single dot was missing in the script >_<)

The hanging prevention is on by default, and an additional one can be activated at the cost of creation speed.
 
You deserve some praise as well, I got the idea while seeing Sparrow's moves. This is why there's a thief guy in the demo...
 
Really ? Could you post the specifics (the charsets and transition you're using) or, if it happens in the demo, which event fails (also : what do you see before the crash ?)
 
I get a script hanging error on the sign by the goats, with only one variable on, and the game crashes, (properly, not 'script hanging') and says "RMXP has encountered an error" or whatever that engine error one says, if I put on both.

I like the idea, I thought at first you were going to use the standerd transition function, (create a new bitmap, but the transition in at the relevent place, and run it as a transition), so I was taken by suprise when they ran without pausing the rest of the screen ^_^
 
AAUUGGHH!

Great script, don't get me wrong, but is there a way to generate stuff without having to open the game...

Oh, no... you have to be kidding me...
It got to 13 of the smaller images done... then said it was hanging...
All of the anti-hang things are set to true, so what could possibly be wrong? This is in the demo, BTW...

PLEASE HELP!

-Moriarty

EDIT:
I got the demo to work... just takes forever... is there any way to either make it run faster, or pre-generate the images?
 
Once it has been generated, it'll stay so and will be fast when re-used. Just create a test map and play the animation once, so you can make sure it has been generated.

I still don't see why it hangs that often... Are you guys using Vista or something ?
 
Nope. I'm using XP.

Anyway, it takes at least a minute to generate something that takes less that 3 seconds to playback...
Plus, if it's a moving event, you have to make one for each way it moves... that's annoying... is there a way to get it to generate all of them for you in a row?
Also, my previous question still stands... is there a way to generate stuff without having to open the game?

Thanks for your help,
Moriarty

EDIT:
If you're STILL having trouble, try using this script
Code:
#==============================================================================
# ** Character Transition
#------------------------------------------------------------------------------
# Rataime
# Version 1.1
# 22/05/2007 (2007-05-22)
#
# convert.exe is an ImageMagick binary. Their license is very permissive and
# can be found here : http://www.imagemagick.org/script/license.php
# Basically, you can redistribute it (even in commercial bundles)
# as long as you credit ImageMagick.
#------------------------------------------------------------------------------
# This script allows you to generate and use characters transitions, ie going
# from one character sprite to another (or a blank one) in the same way you
# can use transitions from one scene to another. All you will need is a
# transition file like those for maps, but smaller.
#
# Given that the Bitmap class is not really powerful, I'm using an external
# binary from ImageMagick called convert.exe. The first time you request a
# specific animation (example : 001-fighter01 to 002-fighter02 facing down using
# a circle transition), the animation bitmap will have to be generated. You'll
# see quite a lot of terminal windows opening and closing, this is quite ugly,
# but the good news is you can delete convert.exe if you're sure you have
# generated every transition you need.
#
# To start a transition, first configure a new animation. Its name must be
# transition_to_character, where transition is the transition name and character
# the final charset name. Example : random_to_002-Fighter02. You can use 'none'
# without the quotes to make your sprite dissapear. The number of frames of the
# animation will be the number of frames of the transition (shortcut : 1=>21)
# Then, after adding this animation's id to the CHARACTER_TRANSITION_ANIMATION_LIST,
# playing it over a character will start the transition. 
#------------------------------------------------------------------------------
# Additionnal notes :
#
# - You may want to prevent the player/event from moving during an animation.
#   The animation will be displayed where the animation was started, but it
#   doesn't automatically prevent the hero (or any other event) from moving.
# - Regarding encryption, the script cannot generate new transitions from
#   encrypted archives. However, it'll play previously generated transitions 
#   or generate transitions from RTP sprites or local folders just fine.
# - You should use a transition and characters of the same size. It might work, 
#   but I don't want to know what will happen otherwise (weird things, probably)
# - The script assumes everything is PNG. You should use PNG anyway. 
# - The script needs the events to have been properly loaded and displayed once.
#   Just use a wait 1 frame to prevent the script from crashing
# - There should be no lag from using the transition, only from generating it.
#==============================================================================


# The folder where the transitions and results are stored.
CHARACTER_TRANSITION_FOLDER = 'Graphics/Character_transition/'

# The list of active animations. EDIT ME !
# Note : 101..103 is equivalent to [101, 102, 103]
CHARACTER_TRANSITION_ANIMATION_LIST = 102..112, 200

# If your computer is slow/unlucky enough to cause hanging errors when generating
# animations, set those to true. It will be slower but won't crash.
# You can try to set the first one to false and see if it works for you.
CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING = true
CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING_EVEN_MORE = true

#The following constant isn't used. Yet.
CHARACTER_TRANSITION_BLOODY_SCRIPT_YOU_ARE_GOING_TO_REGRET_HANGING_ON_ME = true

#------------------------------------------------------------------------------
# * SDK Log Script and Check requirements if you want to use those.
#------------------------------------------------------------------------------
#SDK.log('Character_Transition', 'rataime', 1.00, '05.16.2007')
#SDK.check_requirements(2, [1,2])

#==============================================================================
# ** Sprite_Character
#==============================================================================

class Sprite_Character < RPG::Sprite
  
  alias rataime_character_transition_update update
  
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  def update
    # If an animation included in the list is currently played on this event...
    if CHARACTER_TRANSITION_ANIMATION_LIST.include?(@character.animation_id) or
        @transition != nil
      # The first time, it generates the transition parameters 
      if @transition == nil
        animation = $data_animations[@character.animation_id]
        @transition = RPG::Character_Transition.new
        @transition.animation_id = animation
        @transition.name, @transition.to = animation.name.split('_to_')
        if @character.character_name == ''
          @transition.from = 'none'
          if @transition.to != 'none'            
            # If we can't get the dimentions of the sprites from the current
            # character because it is invisible, we have to load the expected result
            # and get our data from it.
            to_bitmap = RPG::Cache.character(@transition.to, 0)
            @cw = to_bitmap.width/4
            @ch = to_bitmap.height/4
            sx = @character.pattern * @cw
            sy = (@character.direction - 2) / 2 * @ch
            @transition.rect = Rect.new(sx, sy, @cw, @ch)
            to_bitmap = nil
          end
        else
          @transition.from = @character.character_name
          @transition.rect = self.src_rect
        end
        if @transition.to == @transition.from
          @transition = nil
          @character.animation_id = 0
          return
        end
        @transition.character = @character
        if animation.frame_max != 1
          @transition.frame_max = animation.frame_max
        end

        # The character's bitmap is changed to the transition set
        self.bitmap = @transition.bitmap
        # The character's graphic is changed to what it will be after the
        # transition
        # IF THE SCRIPT CRASH HERE, READ THE LAST ADDITIONNAL NOTE ABOVE
        self.ox = @cw / 2 
        self.oy = @ch
      end
      # A bit of maths to know where to take the frame from
      quotient, modulus = (@transition.frame - 1 ).divmod(5)
      sx = (modulus) * @cw
      sy = quotient * @ch
      self.src_rect.set(sx, sy, @cw, @ch)
      super
      @transition.frame += 1
      # If the animation has ended, we tell the character it has.
      if @transition.frame == @transition.frame_max + 1
        if @transition.to == 'none'
          @character.set_character_name('')
        else
          @character.set_character_name(@transition.to)
        end
        @transition = nil
        @character.animation_id = 0
      end
      # Anyway, we return without using the standard update
      return
    end
    # If no correct animation is played, things stay the same as usual
    rataime_character_transition_update
  end
end

#==============================================================================
# ** Module RPG::Cache
#==============================================================================
module RPG
  module Cache
    # A standard Cache function, except there are 3 parameters
    def self.character_transition(subfolder, filename, hue)
      self.load_bitmap(CHARACTER_TRANSITION_FOLDER + subfolder, filename, hue)
    end
  end
end

#==============================================================================
# ** Game_Character 
#==============================================================================
class Game_Character
  #--------------------------------------------------------------------------
  # * set_character_name
  #--------------------------------------------------------------------------
  def set_character_name(name)
    @character_name = name
  end
  
end

#==============================================================================
# ** RPG::Character_Transition
#------------------------------------------------------------------------------
# Better having a new class than setting lots of variables in the Sprite class
#==============================================================================
module RPG
  class Character_Transition
    #--------------------------------------------------------------------------
    # Initialise
    #--------------------------------------------------------------------------
    def initialize
      @animation_id = 0
      @name = ''
      @from = ''
      @to = ''
      @frame_max = 21
      @frame = 1
      @character = nil
      @rect = nil
    end
    attr_accessor :animation_id
    attr_accessor :name
    attr_accessor :from
    attr_accessor :to
    attr_accessor :character
    attr_accessor :frame_max
    attr_accessor :frame
    attr_accessor :rect
    #--------------------------------------------------------------------------
    # Bitmap : return the bitmap containing the animation frames
    #--------------------------------------------------------------------------
    def bitmap
      id = @character.pattern.to_s + @character.direction.to_s
      # If it doesn't exist for this particular transition in this particular
      # configuration (eg : facing up), we generate it.
      if !FileTest.exist?(CHARACTER_TRANSITION_FOLDER + @name + '/' + @from \
                        + '_' + @to + '_' + id + '_' + @frame_max.to_s + '.png')
        self.generate(id)
      end
      # Anyway, we cache the bitmap and return it.
      return RPG::Cache.character_transition( @name + '/', 
            @from + '_' + @to + '_' + id + '_' + @frame_max.to_s,
            @character.character_hue)
    end
    #--------------------------------------------------------------------------
    # Generate : generate the actual  animation bitmap
    #--------------------------------------------------------------------------
    def generate(id = '02')
      
      if !FileTest.exist?('convert.exe')
        p 'Error : cannot find convert.exe'
        raise
      end
      
      src_dir = CHARACTER_TRANSITION_FOLDER
      dir = src_dir + @name + '/'
      if !FileTest.directory?(dir)
        Dir.mkdir(dir)
      end
      
      rect = @rect
      
      animation_file = @from + '_' + @to + '_' + id + '_' + @frame_max.to_s \
                       + '.png'
      
      # We get the RTP path
      rgssGetRTPPath  = Win32API.new('RGSS102E','RGSSGetRTPPath','l','l')
      rgssGetPathWithRTP = Win32API.new("RGSS102E","RGSSGetPathWithRTP","l","p")
      rtp_folder = rgssGetPathWithRTP.call(rgssGetRTPPath.call(1)).gsub("\\", '/')
      
      # If the transition isn't to invisibility, we check both the character folder
      # in the project and the one in the RTP to get the starting bitmap.
      if @from!='none'
        if FileTest.exist?('./Graphics/Characters/' + @from + '.png')
          file_from = './Graphics/Characters/' + @from + '.png'
        elsif FileTest.exist?(rtp_folder + '/Graphics/Characters/' + @from + '.png')
          file_from = rtp_folder + '/Graphics/Characters/' + @from + '.png'
        else
          p 'Error in character transition : file ' + @from + '.png not found.'
          raise
        end
        # Once found, we crop it to have only the relevant pose
        arg = 'convert.exe "' + file_from + '" -quiet  -crop ' + rect.width.to_s + 'x' \
            + rect.height.to_s + '+' + rect.x.to_s + '+' + rect.y.to_s + ' +repage  ' \
            + dir + 'from.png'
        system(arg)
        file_from = dir + 'from.png'
      else
        file_from = dir + 'none.png'
      end
      
      # Same here, with the final bitmap
      if @to!='none'
        if FileTest.exist?('./Graphics/Characters/' + @to + '.png')
          file_to = './Graphics/Characters/' + @to + '.png'
        elsif FileTest.exist?(rtp_folder + '/Graphics/Characters/' + @to + '.png')
          file_to = rtp_folder + '/Graphics/Characters/' + @to + '.png'
        else
          p 'Error in character transition : file ' + @to + '.png not found.'
          raise
        end
        
        arg = 'convert.exe "' + file_to + '" -quiet  -crop ' + rect.width.to_s + 'x' \
            + rect.height.to_s + '+' + rect.x.to_s + '+' + rect.y.to_s + ' +repage  ' \
            + dir + 'to.png'     
        system(arg)
        file_to = dir + 'to.png'
      else
        file_to = dir + 'none.png'
      end
                  
      transition = src_dir + @name + '.png'

      frames = @frame_max
      
      # Hanging prevention
      Graphics.update if CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING_EVEN_MORE
      
      # We generate an empty picture we're going to use for various purposes
      arg = 'convert -size ' + rect.width.to_s + 'x' + rect.height.to_s + \
            ' xc:#00000000 ' + dir + 'none.png'
      system(arg)
      
      # We generate the map of the sprites' visible areas
      # It seems complex, but there is a bug in convert.exe that prevented a
      # direct copy-and-paste-over while keeping the transparency.
      arg = 'convert.exe '+file_to+' -channel matte -negate -separate  +matte ' \
            + dir + 'matte_out.png'
      system(arg)
      arg = 'convert.exe '+file_from+' -channel matte -negate -separate  +matte ' \
            + dir + 'matte_in.png'
      system(arg)
      
      # Hanging prevention
      Graphics.update if CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING_EVEN_MORE
    
      # For each frame, we are going to generate the corresponding graphic
      for i in 0..frames-1
        value = i.to_s
        percent = (5*i).to_s
        # Generating the transition mask
        arg =  'convert.exe '+ transition +' -black-threshold '+ percent \
                +'% -white-threshold '+ percent +'% -negate '+ dir + value + '.png'
        system(arg)
        
        # Composing it with the "to" file alpha mask (the map of visible areas)
        arg = 'convert.exe '+ dir + value + '.png ' + dir + 'matte_out.png '\
              + '-compose Multiply  -composite '+ dir + value + '_out.png'
        system(arg)
        
       # Hanging prevention
        Graphics.update if CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING_EVEN_MORE
        
        # Also composing it with the "from" file alpha mask
        arg = 'convert.exe '+ dir + value + '.png -negate ' + dir + 'matte_in.png '\
              + '-compose Multiply  -composite '+ dir + value + '_in.png'
        system(arg)
        
        # Applying the 1st mask on the "to" file and pasting it on the transparent canevas
        arg = 'convert.exe '+ dir + 'none.png '+ file_to +' '+ dir + value \
                + '_out.png -compose Copy -composite '+ dir + value + '.png'
        system(arg)
        
        Graphics.update if CHARACTER_TRANSITION_BLOODY_SCRIPT_YOU_ARE_GOING_TO_REGRET_HANGING_ON_ME
        
        # Applying the 2nd mask on the "from" file and pasting it on the previous image
        arg = 'convert.exe '+ dir + value + '.png ' + file_from +' '+ dir + value \
                + '_in.png -compose Copy -composite '+ dir + value + '.png'
        system(arg)
        
        # Deleting the temporary frame files
        File.delete(dir + value + '_in.png')
        File.delete(dir + value + '_out.png')
        
        # Better safe than so ERROR : SCRIPT HANGED
        Graphics.update if CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING
      end
      # Deleting the temporary masks, source and background files
      File.delete(dir + 'matte_in.png')
      File.delete(dir + 'matte_out.png')
      File.delete(file_from)
      File.delete(file_to)
      File.delete(dir + 'none.png') if FileTest.exist?(dir + 'none.png')
      # Prepare the animation rows
      for i in 0..(frames-1)/5
        arg = 'convert.exe '
        for j in 0..4
          num = (5*i + j).to_s
          arg = arg + dir + num + '.png ' 
        end
        arg = arg + '+append ' + dir + 'row' + i.to_s + '.png'
        system(arg)
        Graphics.update if CHARACTER_TRANSITION_BLOODY_SCRIPT_YOU_ARE_GOING_TO_REGRET_HANGING_ON_ME
      end
      # Hanging prevention
      Graphics.update if CHARACTER_TRANSITION_PREVENT_SCRIPT_FROM_HANGING_EVEN_MORE
      # Paste the rows together
      arg = 'convert.exe '
      for i in 0..(frames-1)/5
        arg = arg + dir + 'row' + i.to_s + '.png '
      end
      arg = arg + '-background none -append ' + dir + animation_file
      system(arg)
      Graphics.update if CHARACTER_TRANSITION_BLOODY_SCRIPT_YOU_ARE_GOING_TO_REGRET_HANGING_ON_ME
      # Delete the temporary row files
      for i in 0..(frames-1)/5
        File.delete(dir + 'row' + i.to_s + '.png ')
      end
      # Delete the temporary individual frames
      for i in 0..frames-1
        File.delete(dir + i.to_s + '.png ')
      end
    end      
          
  end
end

I added Graphics.update so it would update every 2 or 3 calls to convert.exe.
I also added it to the end of the row-making loop at the end... that was where mine was hanging up...
Be sure that you have ALL the variables/constants at the top set to TRUE (at least in mine)
 
I downloaded your demo and everything on the left hand side works fine. But as soon as I try the sign, pig, etc, the game sort of freezes. Then a blank regular window pops up over the demo playtest window with the location of the script in the title. That seperate window will close, and another will open, etc, etc.

I have NO IDEA what the problem is... I have a legal version of RMXP and I am using your demo. *shrugs* Has anyone else seen this problem before?
 
I don't find that error... But I keep finding an error with this line:

unidentified method 'include?' for 76:Fixum

This is the line:

CHARACTER_TRANSITION_ANIMATION_LIST.include?(@character.animation_id)

Hope you can help, Jamie Delo
 

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