FANDOM


Animating battle sprites
This tutorial was written by Luka S.J. Please give credit.

This tutorial is related to the following pages:

Click here for more tutorials!


Creating two frames animations for wild and trainer battles is not that complicated. For this you will need to handle only two scripts. PokemonUtilities, and PokeBattle_ActualScene. But before we begin to edit scripts, you have to create your folders containing sprite animations. Go to Graphics/Battlers, and here create a new folder called "firstframe" and another one called "secondframe" (spelling and capitalisation does matter!). Place the indexed, first frames of your Pokemon in the folder called "firstframe", and the second frame, indexed .png files in "secondframe". No additional name extensions are needed for the indexing of the sprites.

Now the first thing you should do for scripting is go to PokemonUtilities, and search for "pbLoadPokemonBitmap". What you want to do there is delete the full "def pbLoadPokemonBitmap" and delete the full "def pbLoadPokemonBitmapSpecies". Now here you just insert this script:

def pbLoadPokemonBitmap(pokemon, back=false)
return pbLoadPokemonBitmapSpecies(pokemon,pokemon.species,back)
end

def pbLoadPokemonBitmapSpecies(pokemon, species, back=false)
if pokemon.egg?
return BitmapCache.load_bitmap(sprintf("Graphics/Pictures/egg"))
end
ret=nil
bitmapFileName=pbResolveBitmap(sprintf("Graphics/Battlers/firstframe/%03d%s%s%s_%d",species,
pokemon.gender==1 ? "f" : "",
pokemon.isShiny? ? "s" : "",
back ? "b" : "",(pokemon.form rescue 0)))
bitmapFileName=pbResolveBitmap(sprintf("Graphics/Battlers/firstframe/%03d%s%s_%d",species,
pokemon.isShiny? ? "s" : "",
back ? "b" : "",(pokemon.form rescue 0))) if !bitmapFileName
bitmapFileName=pbResolveBitmap(sprintf("Graphics/Battlers/firstframe/%03d%s%s%s",species,
pokemon.gender==1 ? "f" : "",
pokemon.isShiny? ? "s" : "",
back ? "b" : "")) if !bitmapFileName
bitmapFileName=pbResolveBitmap(sprintf("Graphics/Battlers/firstframe/%03d%s%s",species,
pokemon.isShiny? ? "s" : "",
back ? "b" : "")) if !bitmapFileName
# Alter bitmap if supported
alterBitmap=(MultipleForms.getFunction(species,"alterBitmap") rescue nil)
if bitmapFileName && alterBitmap
animatedBitmap=BitmapCache.load_bitmap(bitmapFileName)
copiedBitmap=animatedBitmap.copy
animatedBitmap.dispose
copiedBitmap.each {|bitmap|
alterBitmap.call(pokemon,bitmap)
}
ret=copiedBitmap
elsif bitmapFileName
ret=BitmapCache.load_bitmap(bitmapFileName)
end
return ret
end

def pbLoadPokemonBitmap2(pokemon, back=false)
return pbLoadPokemonBitmapSpecies2(pokemon,pokemon.species,back)
end

def pbLoadPokemonBitmapSpecies2(pokemon, species, back=false)
if pokemon.egg?
return BitmapCache.load_bitmap(sprintf("Graphics/Pictures/egg"))
end
ret=nil
bitmapFileName=pbResolveBitmap(sprintf("Graphics/Battlers/secondframe/%03d%s%s%s_%d",species,
pokemon.gender==1 ? "f" : "",
pokemon.isShiny? ? "s" : "",
back ? "b" : "",(pokemon.form rescue 0)))
bitmapFileName=pbResolveBitmap(sprintf("Graphics/Battlers/secondframe/%03d%s%s_%d",species,
pokemon.isShiny? ? "s" : "",
back ? "b" : "",(pokemon.form rescue 0))) if !bitmapFileName
bitmapFileName=pbResolveBitmap(sprintf("Graphics/Battlers/secondframe/%03d%s%s%s",species,
pokemon.gender==1 ? "f" : "",
pokemon.isShiny? ? "s" : "",
back ? "b" : "")) if !bitmapFileName
bitmapFileName=pbResolveBitmap(sprintf("Graphics/Battlers/secondframe/%03d%s%s",species,
pokemon.isShiny? ? "s" : "",
back ? "b" : "")) if !bitmapFileName
# Alter bitmap if supported
alterBitmap=(MultipleForms.getFunction(species,"alterBitmap") rescue nil)
if bitmapFileName && alterBitmap
animatedBitmap=BitmapCache.load_bitmap(bitmapFileName)
copiedBitmap=animatedBitmap.copy
animatedBitmap.dispose
copiedBitmap.each {|bitmap|
alterBitmap.call(pokemon,bitmap)
}
ret=copiedBitmap
elsif bitmapFileName
ret=BitmapCache.load_bitmap(bitmapFileName)
end
return ret
end

Ok so now that this is done, if you aren't using the latest version of Pokemon Essentials, under the newly pasted definition in PokemonUtilities, also place this code:

def getID(mod,constant)
return nil if !mod || !constant || constant==""
if constant.is_a?(Symbol) || constant.is_a?(String)
if (mod.const_defined?(constant.to_sym) rescue false)
return mod.const_get(constant.to_sym) rescue 0
else
return 0
end
else
return constant
end
end

Create a new blank script, and name it PokemonMultipleForms. This is just like the name says - Poccil's multiple form script. For those of you that don't have the script here it is:

class PokeBattle_Pokemon
def form
v=MultipleForms.call("getForm",self)
return v if v!=nil
return @form || 0
end
def form=(value)
@form=value
self.calcStats
MultipleForms.call("onSetForm",self,value)
end
alias __mf_baseStats baseStats
alias __mf_initialize initialize
alias __mf_ability ability
alias __mf_type1 type1
alias __mf_type2 type2
def baseStats
v=MultipleForms.call("getBaseStats",self)
return v if v!=nil
return self.__mf_baseStats
end
def ability
v=MultipleForms.call("ability",self)
return v if v!=nil
return self.__mf_ability
end
def type1
v=MultipleForms.call("type1",self)
return v if v!=nil
return self.__mf_type1
end
def type2
v=MultipleForms.call("type2",self)
return v if v!=nil
return self.__mf_type2
end
def initialize(*args)
__mf_initialize(*args)
f=MultipleForms.call("getFormOnCreation",self)
if f
self.form=f
end
end
end

class PokeBattle_RealBattlePeer
def pbOnEnteringBattle(battle,pokemon)
f=MultipleForms.call("getFormOnEnteringBattle",pokemon)
if f
pokemon.form=f
end
end
end

module MultipleForms
@@formSpecies=HandlerHash.new(:PBSpecies)
def self.copy(sym,*syms)
@@formSpecies.copy(sym,*syms)
end
def self.register(sym,hash)
@@formSpecies.add(sym,hash)
end
def self.registerIf(cond,hash)
@@formSpecies.addIf(cond,hash)
end
def self.hasFunction?(pokemon,func)
spec=(pokemon.is_a?(Numeric)) ? pokemon : pokemon.species
sp=@@formSpecies[spec]
return sp && sp[func]
end
def self.getFunction(pokemon,func)
spec=(pokemon.is_a?(Numeric)) ? pokemon : pokemon.species
sp=@@formSpecies[spec]
return (sp && sp[func]) ? sp[func] : nil
end
def self.call(func,pokemon,*args)
sp=@@formSpecies[pokemon.species]
return nil if !sp || !sp[func]
return sp[func].call(pokemon,*args)
end
end
def drawSpot(bitmap,spotpattern,x,y,red,green,blue)
height=spotpattern.length
width=spotpattern[0].length
for yy in 0...height
spot=spotpattern[yy]
for xx in 0...width
if spot[xx]==1
xOrg=(x+xx)<<1
yOrg=(y+yy)<<1
color=bitmap.get_pixel(xOrg,yOrg)
r=color.red+red
g=color.green+green
b=color.blue+blue
color.red=[[r,0].max,255].min
color.green=[[g,0].max,255].min
color.blue=[[b,0].max,255].min
bitmap.set_pixel(xOrg,yOrg,color)
bitmap.set_pixel(xOrg+1,yOrg,color)
bitmap.set_pixel(xOrg,yOrg+1,color)
bitmap.set_pixel(xOrg+1,yOrg+1,color)
end
end
end
end

def pbSpindaSpots(pokemon,bitmap)
spot1=[
[0,0,1,1,1,1,0,0],
[0,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,0],
[0,0,1,1,1,1,0,0]
]
spot2=[
[0,0,1,1,1,0,0],
[0,1,1,1,1,1,0],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[1,1,1,1,1,1,1],
[0,1,1,1,1,1,0],
[0,0,1,1,1,0,0]
]
spot3=[
[0,0,0,0,0,1,1,1,1,0,0,0,0],
[0,0,0,1,1,1,1,1,1,1,0,0,0],
[0,0,1,1,1,1,1,1,1,1,1,0,0],
[0,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,1,1,1,0,0],
[0,0,0,1,1,1,1,1,1,1,1,0,0],
[0,0,0,0,0,1,1,1,0,0,0,0,0]
]
spot4=[
[0,0,0,0,1,1,1,0,0,0,0,0],
[0,0,1,1,1,1,1,1,1,0,0,0],
[0,1,1,1,1,1,1,1,1,1,0,0],
[0,1,1,1,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1,1,1,0],
[0,0,1,1,1,1,1,1,1,1,0,0],
[0,0,0,0,0,1,1,1,1,0,0,0]
]
id=pokemon.personalID
h=(id>>28)&15
g=(id>>24)&15
f=(id>>20)&15
e=(id>>16)&15
d=(id>>12)&15
c=(id>>8)&15
b=(id>>4)&15
a=(id)&15
if pokemon.isShiny?
drawSpot(bitmap,spot1,b+33,a+25,-100,30,-100)
drawSpot(bitmap,spot2,d+21,c+24,-100,30,-100)
drawSpot(bitmap,spot3,f+39,e+7,-100,30,-100)
drawSpot(bitmap,spot4,h+15,g+6,-100,30,-100)
else
drawSpot(bitmap,spot1,b+33,a+25,30,-100,-100)
drawSpot(bitmap,spot2,d+21,c+24,30,-100,-100)
drawSpot(bitmap,spot3,f+39,e+7,30,-100,-100)
drawSpot(bitmap,spot4,h+15,g+6,30,-100,-100)
end
end


MultipleForms.register(:SHELLOS,{
"getFormOnCreation"=>proc{|pokemon|
maps=[] # Map IDs for second form
if $game_map && maps.include?($game_map.map_id)
next 1
else
next 0
end
}
})

MultipleForms.copy(:SHELLOS,:GASTRODON)


MultipleForms.register(:SPINDA,{
"alterBitmap"=>proc{|pokemon,bitmap|
pbSpindaSpots(pokemon,bitmap)
}
})


MultipleForms.register(:UNOWN,{
"getForm"=>proc{|pokemon|
d=pokemon.personalID&3
d|=((pokemon.personalID>>8)&3)<<2
d|=((pokemon.personalID>>16)&3)<<4
d|=((pokemon.personalID>>24)&3)<<6
d%=28 # index of letter : ABCDEFGHIJKLMNOPQRSTUVWXYZ!?
next d
}
})

MultipleForms.register(:ROTOM,{
"getBaseStats"=>proc{|pokemon|
case pokemon.form
# Normal Form
when 0; next [50,50,77,91,95,77]
# Alternate Form
else; next [50,65,107,86,105,107]
end
},
"onSetForm"=>proc{|pokemon,form|
moves=[
:OVERHEAT, # Heat, Microwave
:HYDROPUMP, # Wash, Washing Machine
:BLIZZARD, # Frost, Refrigerator
:AIRSLASH, # Fan
:LEAFSTORM # Mow, Lawnmower
]
moves.each{|move|
pbDeleteMoveByID(pokemon,getID(PBMoves,move))
}
if pokemon.moves.find_all{|i| i.id!=0}.length==0
pbAutoLearnMove(pokemon,getID(PBMoves,:THUNDERSHOCK))
end
if form>0
pbAutoLearnMove(pokemon,getID(PBMoves,moves[form-1]))
end
}
})

MultipleForms.register(:DEOXYS,{
"getBaseStats"=>proc{|pokemon|
case pokemon.form
# Attack Forme
when 2; next [50,180,20,150,180,20]
# Defense Forme
when 3; next [50,70 ,160,90,70,160]
# Speed Forme
when 4; next [50,95, 90, 180,95,90]
# Normal Forme
else; next [50,150,50,150,150,50]
end
}
})

MultipleForms.register(:SHAYMIN,{
"type2"=>proc{|pokemon|
case pokemon.form
# Sky Forme
when 1; next getID(PBTypes,:FLYING)
# Land Forme
else; next getID(PBTypes,:GRASS)
end
},
"ability"=>proc{|pokemon|
if pokemon.form==0
next getID(PBAbilities,:NATURALCURE)
else
next getID(PBAbilities,:SERENEGRACE)
end
},
"getBaseStats"=>proc{|pokemon|
case pokemon.form
# Sky Forme
when 1; next [100,103,75,127,120,75]
# Land Forme
else; next [100,100,100,100,100,100]
end
},
"getForm"=>proc{|pokemon|
case pokemon.form
# Sky Forme
when 1; next 1
# Land Forme
else; next 0
end
}
})

MultipleForms.register(:BURMY,{
"getFormOnCreation"=>proc{|pokemon|
env=pbGetEnvironment()
if env==PBEnvironment::Grass ||
env==PBEnvironment::TallGrass
next 0 # Plant Cloak
elsif env==PBEnvironment::Sand ||
env==PBEnvironment::Rock ||
env==PBEnvironment::Cave
next 1 # Sandy Cloak
else
next 2 # Trash Cloak
end
},
"getFormOnEnteringBattle"=>proc{|pokemon|
env=pbGetEnvironment()
if env==PBEnvironment::Grass ||
env==PBEnvironment::TallGrass
next 0 # Plant Cloak
elsif env==PBEnvironment::Sand ||
env==PBEnvironment::Rock ||
env==PBEnvironment::Cave
next 1 # Sandy Cloak
else
next 2 # Trash Cloak
end
}
})

MultipleForms.register(:WORMADAM,{
"type2"=>proc{|pokemon|
case pokemon.form
# Sandy Cloak
when 1; next getID(PBTypes,:GROUND)
# Trash Cloak
when 2; next getID(PBTypes,:STEEL)
# Plant Cloak
else; next getID(PBTypes,:GRASS)
end
},
"getBaseStats"=>proc{|pokemon|
case pokemon.form
# Sandy Cloak
when 1; next [60,79,105,36,59,85]
# Trash Cloak
when 2; next [60,69,95,36,69,95]
# Plant Cloak
else; next [60,59,85,36,79,105]
end
}
})

MultipleForms.register(:GIRATINA,{
"ability"=>proc{|pokemon|
if pokemon.form==0
next getID(PBAbilities,:PRESSURE)
else
next getID(PBAbilities,:LEVITATE)
end
},
"getForm"=>proc{|pokemon|
if isConst?(pokemon.item,PBItems,:GRISEOUSORB)
next 1
end
# Note: Also depends on location
next 0
},
"getBaseStats"=>proc{|pokemon|
case pokemon.form
# Origin Forme
when 1; next [150,120,100,90,120,100]
# Normal Forme
else; next [150,100,120,90,100,120]
end
}
})

MultipleForms.register(:ARCEUS,{
"type1"=>proc{|pokemon|
types=[:NORMAL,:FIGHTING,:FLYING,
:POISON,:GROUND,:ROCK,:BUG,:GHOST,:STEEL,
:QMARKS,:FIRE,:WATER,:GRASS,:ELECTRIC,
:PSYCHIC,:ICE,:DRAGON,:DARK]
next getID(PBTypes,types[pokemon.form])
},
"type2"=>proc{|pokemon|
types=[:NORMAL,:FIGHTING,:FLYING,
:POISON,:GROUND,:ROCK,:BUG,:GHOST,:STEEL,
:QMARKS,:FIRE,:WATER,:GRASS,:ELECTRIC,
:PSYCHIC,:ICE,:DRAGON,:DARK]
next getID(PBTypes,types[pokemon.form])
},
"getForm"=>proc{|pokemon|
next 1 if isConst?(pokemon.item,PBItems,:FISTPLATE)
next 2 if isConst?(pokemon.item,PBItems,:SKYPLATE)
next 3 if isConst?(pokemon.item,PBItems,:TOXICPLATE)
next 4 if isConst?(pokemon.item,PBItems,:EARTHPLATE)
next 5 if isConst?(pokemon.item,PBItems,:STONEPLATE)
next 6 if isConst?(pokemon.item,PBItems,:INSECTPLATE)
next 7 if isConst?(pokemon.item,PBItems,:SPOOKYPLATE)
next 8 if isConst?(pokemon.item,PBItems,:IRONPLATE)
next 10 if isConst?(pokemon.item,PBItems,:FLAMEPLATE)
next 11 if isConst?(pokemon.item,PBItems,:SPLASHPLATE)
next 12 if isConst?(pokemon.item,PBItems,:MEADOWPLATE)
next 13 if isConst?(pokemon.item,PBItems,:GRASSPLATE)
next 14 if isConst?(pokemon.item,PBItems,:MINDPLATE)
next 15 if isConst?(pokemon.item,PBItems,:ICICLEPLATE)
next 16 if isConst?(pokemon.item,PBItems,:DRACOPLATE)
next 17 if isConst?(pokemon.item,PBItems,:DREADPLATE)
next 0
}
})

Ok, now we will go onto the part of actually animating the Pokemon (this was just a setup). Go into PokeBattle_ActualScene, and search for ".setPokemonBitmap", replace this with ".bitmap = pbLoadPokemonBitmap". Now repeat that search as many times as you have to, in order to replace all ".setPokemonBitmap" definitions within PokeBattle_ActualScene with ".bitmap = pbLoadPokemonBitmap". Now go to PokeBattle_ActualScene, and if you're using the newer versions of Essentials, go to somewhere around line 1598. This should be the definition which says to load the animation for shiny pokemon. Well, just before that you want to put this code:

if !@battle.opponent
pokemon = @battle.party2[0]
@sprites["pokemon1"].bitmap = pbLoadPokemonBitmap2(pokemon,false)
pbPlayCry(@battle.party2[0])
pbWait(30)
@sprites["pokemon1"].bitmap = pbLoadPokemonBitmap(pokemon,false)
if @battle.party2[0].isShiny?
pbCommonAnimation("Shiny",@battle.battlers[1],nil)
end
if @battle.party2.length==2
pokemon2 = @battle.party2[1]
@sprites["pokemon3"].bitmap = pbLoadPokemonBitmap2(pokemon2,false)
pbPlayCry(@battle.party2[1])
pbWait(30)
@sprites["pokemon3"].bitmap = pbLoadPokemonBitmap(pokemon2,false)
if @battle.party2[1].isShiny?
pbCommonAnimation("Shiny",@battle.battlers[3],nil)
end
end
end

Now in order to get Trainer's Pokemon animated, go to "pbTrainerSendOut" delete the function pbPlayCry, which should be present somewhere within the definition. Then go to the bottom of the definition, and just after the method sendout.dispose, paste this code:

@sprites["pokemon#{battlerindex}"].bitmap=pbLoadPokemonBitmap2(pkmn,false)
pkmnwav=sprintf("Audio/SE/%03dCry",pkmn.species)
Audio.se_play(pkmnwav,90,100)
pbWait(30)
  @sprites["pokemon#{battlerindex}"].bitmap=pbLoadPokemonBitmap(pkmn,false)

And for Player's Pokemon animating, once again go to "pbSendOut", find and remove pbPlayCry, and right after the method sendout.dispose, paste this code:

@sprites["pokemon#{battlerindex}"].bitmap=pbLoadPokemonBitmap2(pkmn,true)
pkmnwav=sprintf("Audio/SE/%03dCry",pkmn.species)
Audio.se_play(pkmnwav,100,100)
pbWait(30)
@sprites["pokemon#{battlerindex}"].bitmap=pbLoadPokemonBitmap(pkmn,true)

This is it, now all the Pokemon Appearing in battle should be animated. If this wiki has been helpful, and you've used it in your game, please give credit to Alexandre, and Luka S.J. for providing you with this tutorial and script extensions. Thank you :)

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.