Submit Your Article


 
RPG Maker

Welcome Guest ( Log In | Register )


  Games Resources RPG Maker VX RPG Maker XP Scripts Tutorials Downloads

 
Reply to this topicStart new topic
> [RGSS] Animation Clipping Engine
Jens of Zanicuud
post Feb 11 2013, 11:51 AM
Post #1


Dark Jentleman
Group Icon

Group: Local Mod
Posts: 904
Type: Scripter
RM Skill: Skilled
Rev Points: 120




Animation Clipping Engine

version: 1.0
release date: 11th January, 2013
system: RGSS // RPG Maker XP

Introduction

This script allows you to decide whether an animation is confined inside enemies' battlers or not.
A picture can explain much better than words, though:



Script

CODE
#==============================================================================
# ** Jens of Zanicuud's animation clipping script
#=============================================================================
# -version 1.0
# -free use, just credit
# -you can find me at www.rpgrevolution.com
# -snapshot script made by Keroro at www.rpg2s.net
#==============================================================================
#--------------------------------------------------------------------------
# * Customization
#--------------------------------------------------------------------------
  MASK_ANIME = [1,2,101] #list of animation which have to be clipped

#--------------------------------------------------------------------------
# ** Graphics
#--------------------------------------------------------------------------
module Graphics
  #--------------------------------------------------------------------------
  # * Call Win32APIs
  #--------------------------------------------------------------------------
  RtlMoveMemory          = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
  BitBlt                 = Win32API.new('gdi32', 'BitBlt', 'iiiiiiiii', 'i')
  CreateCompatibleBitmap = Win32API.new('gdi32', 'CreateCompatibleBitmap', 'iii', 'i')
  CreateCompatibleDC     = Win32API.new('gdi32', 'CreateCompatibleDC', 'i', 'i')
  DeleteObject           = Win32API.new('gdi32', 'DeleteObject', 'i', 'i')
  GetDIBits              = Win32API.new('gdi32', 'GetDIBits', 'iiiiipi', 'i')
  SelectObject           = Win32API.new('gdi32', 'SelectObject', 'ii', 'i')
  SetDIBits              = Win32API.new('gdi32', 'SetDIBits', 'iiiiipi', 'i')
  hWnd = Win32API.new('user32', 'FindWindow', 'pp', 'i').call('RGSS Player', 0)
  DC   = Win32API.new('user32', 'GetDC', 'i', 'i').call(hWnd)
  #--------------------------------------------------------------------------
  # * snap_to_bitmap
  #--------------------------------------------------------------------------
  def Graphics.snap_to_bitmap(width=640, height=480)
    bitmap = Bitmap.new(width, height)
    RtlMoveMemory.call(address="\0"*4, bitmap.__id__*2+16, 4)
    RtlMoveMemory.call(address, address.unpack('L')[0]+8, 4)
    RtlMoveMemory.call(address, address.unpack('L')[0]+16, 4)
    address = address.unpack('L')[0]
    info = [40,width,height,1,32,0,0,0,0,0,0].pack('LllSSLLllLL')
    hDC = CreateCompatibleDC.call(DC)
    hBM = CreateCompatibleBitmap.call(DC, width, height)
    DeleteObject.call(SelectObject.call(hDC, hBM))
    SetDIBits.call(hDC, hBM, 0, height, address, info, 0)
    BitBlt.call(hDC, 0, 0, width, height, DC, 0, 0, 0xCC0020)
    GetDIBits.call(hDC, hBM, 0, height, address, info, 0)
    DeleteObject.call(hBM)
    DeleteObject.call(hDC)
    bitmap
  end
end

#--------------------------------------------------------------------------
# ** Sprite
#--------------------------------------------------------------------------
class Sprite
  #--------------------------------------------------------------------------
  # ** Subtract_bitmap
  #--------------------------------------------------------------------------
  def subtract_bitmap(bmp, x, y)
    for i in 0...bmp.width
      for j in 0...bmp.height
        color = bmp.get_pixel(i,j)
        if color.alpha != 0
          self.bitmap.set_pixel(x+i,y+j,Color.new(0,0,0,0))
        end
      end
    end
    return true
  end
  #--------------------------------------------------------------------------
  # ** Create Background Mask
  #--------------------------------------------------------------------------
  def create_background_mask(battlers)
     self.bitmap.dispose if self.bitmap != nil
     self.bitmap = Graphics.snap_to_bitmap(640,320)
     for battler in battlers
       battler_bitmap = RPG::Cache.battler(battler.battler_name,0)
       x = battler.screen_x - battler_bitmap.width/2
       y = battler.screen_y - battler_bitmap.height
       self.subtract_bitmap(battler_bitmap, x, y)
     end
  end
end

#==============================================================================
# ** Spriteset_Battle
#==============================================================================
class Spriteset_Battle
  #--------------------------------------------------------------------------
  # * Aliases
  #--------------------------------------------------------------------------
  alias cutin_anime_aliased_update     update
  alias cutin_anime_aliased_initialize initialize
  alias cutin_anime_aliased_dispose    dispose
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize
    cutin_anime_aliased_initialize
    @mask_sprite         = RPG::Sprite.new(@viewport1)
    @mask_sprite.z       = 9999
    @mask_sprite.visible = false
  end
  #--------------------------------------------------------------------------
  # * dispose
  #--------------------------------------------------------------------------
  def dispose
    cutin_anime_aliased_dispose
    @mask_sprite.bitmap.dispose
    @mask_sprite.dispose
  end
  #--------------------------------------------------------------------------
  # * update
  #--------------------------------------------------------------------------
  def update
    #check if mask sprite has been initialized yet
    if !@mask_sprite.nil?
    anim_actors = []
    for actor in $game_troop.enemies
      if actor.animation_id != 0 and MASK_ANIME.include?(actor.animation_id)
        anim_actors.push(actor)
      end
    end
    if !anim_actors.empty?
      @mask_sprite.create_background_mask(anim_actors)
      @mask_sprite.visible = true
    else
      if not self.effect?
      @mask_sprite.visible = false
      end
      end
    end
    #do default update
    cutin_anime_aliased_update
  end
end


Terms of use

free use, just credit me for the script and Keroro for the snap_to_bitmap function.

Instructions

Place it in a blank above Main and it will work.
You can decide what animations have to be clipped and what not just filling the array named MASK_ANIME.
e.g. MASK_ANIME = [1,2,101]
means that animations 1, 2 and 101 will be clipped when applied to an enemy.

Notes

This script works only on enemies. In practice, it takes a snapshot of the battle background before the animation, cut the enemy picture from the snapshot and then put the cropped picture over the actual layer, "masking" the animation. That's the one way I succeeded in doing this, sorry wink.gif
For large enemies or multiple targets, this could cause some lag.

Credits

snap_to_bitmap script by: Keroro
@http://www.rpg2s.net

Known Issues

There shouldn't be any compatibility issues with Standard BS. For custom BS there's a high chance this won't work properly.
You're free to ask for a compatibility patch anytime.

Ask for troubleshooting anytime.

Jens of Zanicuud


__________________________
"Thorns are the rose's sweetest essence..."
-Jens of Zanicuud


Games I'm working on:
>

official website: TryAdIne eFfeCt

>

Games I worked on (mainly as a scripter):
>
(Warning: it's a 3rr3's project and it's in Italian!)


Awards

Go to the top of the page
 
+Quote Post
   
Resource Dragon
post Feb 11 2013, 01:35 PM
Post #2


Dragon has RAWR. So... RAWR.
Group Icon

Group: Local Mod
Posts: 984
Type: Developer
RM Skill: Masterful
Rev Points: 95




Interesting idea for a script. Is it possible for you to reverse the pixel algorithm so that it only appears on the outside of the battler, making it seem behind him?


__________________________
click me ->Signup for Digital Hijinks!<- click me
Go to the top of the page
 
+Quote Post
   
Jens of Zanicuud
post Feb 12 2013, 04:29 AM
Post #3


Dark Jentleman
Group Icon

Group: Local Mod
Posts: 904
Type: Scripter
RM Skill: Skilled
Rev Points: 120




QUOTE (Resource Dragon @ Feb 11 2013, 10:35 PM) *
Interesting idea for a script. Is it possible for you to reverse the pixel algorithm so that it only appears on the outside of the battler, making it seem behind him?


Sure, it's quite simple wink.gif
It requires very little scripting:
Just fill the BEHIND_ANIME array as the previous one and you're done wink.gif

CODE
#==============================================================================
# ** Jens of Zanicuud's animation clipping script
#=============================================================================
# -version 1.1
# -free use, just credit
# -you can find me at www.rpgrevolution.com
# -snapshot script made by Keroro at www.rpg2s.net
#==============================================================================
#--------------------------------------------------------------------------
# * Customization
#--------------------------------------------------------------------------
  MASK_ANIME   = [1,2,3] #list of animation which have to be clipped
  BEHIND_ANIME = [101] #list of animation which have to be displayed behind the target
#--------------------------------------------------------------------------
# ** Graphics
#--------------------------------------------------------------------------
module Graphics
  #--------------------------------------------------------------------------
  # * Call Win32APIs
  #--------------------------------------------------------------------------
  RtlMoveMemory          = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
  BitBlt                 = Win32API.new('gdi32', 'BitBlt', 'iiiiiiiii', 'i')
  CreateCompatibleBitmap = Win32API.new('gdi32', 'CreateCompatibleBitmap', 'iii', 'i')
  CreateCompatibleDC     = Win32API.new('gdi32', 'CreateCompatibleDC', 'i', 'i')
  DeleteObject           = Win32API.new('gdi32', 'DeleteObject', 'i', 'i')
  GetDIBits              = Win32API.new('gdi32', 'GetDIBits', 'iiiiipi', 'i')
  SelectObject           = Win32API.new('gdi32', 'SelectObject', 'ii', 'i')
  SetDIBits              = Win32API.new('gdi32', 'SetDIBits', 'iiiiipi', 'i')
  hWnd = Win32API.new('user32', 'FindWindow', 'pp', 'i').call('RGSS Player', 0)
  DC   = Win32API.new('user32', 'GetDC', 'i', 'i').call(hWnd)
  #--------------------------------------------------------------------------
  # * snap_to_bitmap
  #--------------------------------------------------------------------------
  def Graphics.snap_to_bitmap(width=640, height=480)
    bitmap = Bitmap.new(width, height)
    RtlMoveMemory.call(address="\0"*4, bitmap.__id__*2+16, 4)
    RtlMoveMemory.call(address, address.unpack('L')[0]+8, 4)
    RtlMoveMemory.call(address, address.unpack('L')[0]+16, 4)
    address = address.unpack('L')[0]
    info = [40,width,height,1,32,0,0,0,0,0,0].pack('LllSSLLllLL')
    hDC = CreateCompatibleDC.call(DC)
    hBM = CreateCompatibleBitmap.call(DC, width, height)
    DeleteObject.call(SelectObject.call(hDC, hBM))
    SetDIBits.call(hDC, hBM, 0, height, address, info, 0)
    BitBlt.call(hDC, 0, 0, width, height, DC, 0, 0, 0xCC0020)
    GetDIBits.call(hDC, hBM, 0, height, address, info, 0)
    DeleteObject.call(hBM)
    DeleteObject.call(hDC)
    bitmap
  end
end

#--------------------------------------------------------------------------
# ** Sprite
#--------------------------------------------------------------------------
class Sprite
  #--------------------------------------------------------------------------
  # ** Subtract_bitmap
  #--------------------------------------------------------------------------
  def subtract_bitmap(bmp, x, y)
    for i in 0...bmp.width
      for j in 0...bmp.height
        color = bmp.get_pixel(i,j)
        if color.alpha != 0
          self.bitmap.set_pixel(x+i,y+j,Color.new(0,0,0,0))
        end
      end
    end
    return true
  end
  #--------------------------------------------------------------------------
  # ** Create Background Mask
  #--------------------------------------------------------------------------
  def create_background_mask(battlers)
     self.bitmap.dispose if self.bitmap != nil
     self.bitmap = Graphics.snap_to_bitmap(640,320)
     for battler in battlers
       battler_bitmap = RPG::Cache.battler(battler.battler_name,0)
       x = battler.screen_x - battler_bitmap.width/2
       y = battler.screen_y - battler_bitmap.height
       self.subtract_bitmap(battler_bitmap, x, y)
     end
  end
end

#==============================================================================
# ** Spriteset_Battle
#==============================================================================
class Spriteset_Battle
  #--------------------------------------------------------------------------
  # * Aliases
  #--------------------------------------------------------------------------
  alias cutin_anime_aliased_update     update
  alias cutin_anime_aliased_initialize initialize
  alias cutin_anime_aliased_dispose    dispose
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize
    cutin_anime_aliased_initialize
    @mask_sprite         = RPG::Sprite.new(@viewport1)
    @mask_sprite.z       = 9998
    @mask_sprite.visible = false
  @mask_battlers         = []
  for enemy in $game_troop.enemies
   dummy            = Sprite.new(@viewport1)
   dummy.z          = 9999
   dummy.visible    = false
   @mask_battlers.push(dummy)
  end
  end
  #--------------------------------------------------------------------------
  # * dispose
  #--------------------------------------------------------------------------
  def dispose
    cutin_anime_aliased_dispose
    @mask_sprite.bitmap.dispose
    @mask_sprite.dispose
  for sprite in  @mask_battlers
   sprite.dispose
  end
  end
  #--------------------------------------------------------------------------
  # * update
  #--------------------------------------------------------------------------
  def update
    #check if mask sprite has been initialized yet
  if !@mask_sprite.nil?
  #update mask sprites
   for sprite in  @mask_battlers
    sprite.update
   end
  #create a temporary array
    anim_actors   = []
  behind_actors = []
     for actor in $game_troop.enemies
       if actor.animation_id != 0 and MASK_ANIME.include?(actor.animation_id)
          anim_actors.push(actor)
     end
     if actor.animation_id != 0 and BEHIND_ANIME.include?(actor.animation_id)
          behind_actors.push(actor)
     end
     end
   effect_flag = false
   #check if background has to be created
     if !anim_actors.empty?
       @mask_sprite.create_background_mask(anim_actors)
       @mask_sprite.visible = true
     effect_flag = true
   end
   #check if sprites has to be added
   if !behind_actors.empty?
     effect_flag = true
     index       = 0
     for actor in behind_actors
       @mask_battlers[index].bitmap  = RPG::Cache.battler(actor.battler_name,actor.battler_hue)
       @mask_battlers[index].ox      = @mask_battlers[index].bitmap.width / 2
       @mask_battlers[index].oy      = @mask_battlers[index].bitmap.height
       @mask_battlers[index].x       = actor.screen_x
       @mask_battlers[index].y       = actor.screen_y
       @mask_battlers[index].visible = true
           index += 1
     end
   end
   #if there aren't any effects...
     if !effect_flag
      if not self.effect?
       @mask_sprite.visible = false
      for sprite in  @mask_battlers
        sprite.visible = false
      end
      end
   end
    end
    #do default update
    cutin_anime_aliased_update
  end
end


and that's the result:

Proof that this script works wink.gif



How does it work:
In practice, this script creates an array of empty sprites, which are set over to the enemies and become visible only when the animation is present, "cropping" the animation itself;)

Jens


__________________________
"Thorns are the rose's sweetest essence..."
-Jens of Zanicuud


Games I'm working on:
>

official website: TryAdIne eFfeCt

>

Games I worked on (mainly as a scripter):
>
(Warning: it's a 3rr3's project and it's in Italian!)


Awards

Go to the top of the page
 
+Quote Post
   
yamina-chan
post Feb 20 2013, 08:45 AM
Post #4


Level 8
Group Icon

Group: Revolutionary
Posts: 128
Type: None
RM Skill: Skilled




=D
Again and again you come up with great scripts.
This one in particular may seem like a small feature to some, but with a little thought this can provide some fairly interesting new set ups.


__________________________
There is a game out there for everyone. All you have to do is to find it.
Go to the top of the page
 
+Quote Post
   

Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 21st May 2013 - 11:20 PM
RPG RPG Revolution is an Privacy Policy and Legal
eXTReMe Tracker