# Particle Engine, Peter O., 2007-11-03 # Based on version 2 by Near Fantastica, 04.01.06 # In turn based on the Particle Engine designed by PinkMan class Particle_Engine #-------------------------------------------------------------------------- def initialize(viewport=nil,map=nil) @map=map ? map : $game_map @viewport = viewport @effect = [] @disposed=false @firsttime=true @effects={ # PinkMan's Effects "fire"=>Particle_Engine::Fire, "smoke"=>Particle_Engine::Smoke, "teleport"=>Particle_Engine::Teleport, "spirit"=>Particle_Engine::Spirit, "explosion"=>Particle_Engine::Explosion, "aura"=>Particle_Engine::Aura, # BlueScope's Effects "soot"=>Particle_Engine::Soot, "sootsmoke"=>Particle_Engine::SootSmoke, "rocket"=>Particle_Engine::Rocket, "fixteleport"=>Particle_Engine::FixedTeleport, "smokescreen"=>Particle_Engine::Smokescreen, "flare"=>Particle_Engine::Flare, "splash"=>Particle_Engine::Splash, # By Peter O. "starteleport"=>Particle_Engine::StarTeleport } end def add_effect(event) @effect[event.id]=pbParticleEffect(event) end def realloc_effect(event,particle) type = pbEventCommentInput(event, 1, "Particle Engine Type") if type.nil? particle.dispose if particle return nil end type=type[0].downcase cls=@effects[type] if cls.nil? particle.dispose if particle return nil end if !particle || !particle.is_a?(cls) particle.dispose if particle particle=cls.new(event,@viewport) end return particle end def pbParticleEffect(event) return realloc_effect(event,nil) end def remove_effect(event) return if @effect[event.id].nil? @effect[event.id].dispose @effect.delete_at(event.id) end def update if @firsttime @firsttime=false for event in @map.events.values remove_effect(event) add_effect(event) end end for i in 0...@effect.length particle=@effect[i] next if particle.nil? if particle.event.pe_refresh event=particle.event event.pe_refresh=false particle=realloc_effect(event,particle) @effect[i]=particle end particle.update if particle end end def disposed? return @disposed end def dispose return if disposed? for particle in @effect next if particle.nil? particle.dispose end @effect.clear @map=nil @disposed=true end end class ParticleEffect attr_accessor :x,:y,:z def initialize @x=0 @y=0 @z=0 end def update end def dispose end end class ParticleSprite attr_accessor :x,:y,:z,:opacity,:bitmap,:blend_type def initialize(viewport) @viewport=viewport @sprite=nil @x=0 @y=0 @z=0 @opacity=255 @bitmap=nil @blend_type=0 @minleft=0 @mintop=0 end def bitmap=(value) @bitmap=value if value @minleft=-value.width @mintop=-value.height else @minleft=0 @mintop=0 end end def dispose @sprite.dispose if @sprite end def update w=Graphics.width h=Graphics.height if !@sprite && @x>=@minleft && @y>=@mintop && @x=w || @y>=h) @sprite.dispose @sprite=nil end if @sprite @sprite.x=@x if @sprite.x!=@x @sprite.y=@y if @sprite.y!=@y @sprite.z=@z if @sprite.z!=@z @sprite.opacity=@opacity if @sprite.opacity!=@opacity @sprite.blend_type=@blend_type if @sprite.blend_type!=@blend_type @sprite.bitmap=@bitmap if @sprite.bitmap!=@bitmap end end end class ParticleEffect_Event < ParticleEffect attr_accessor :event def initialize(event,viewport=nil) @event=event @viewport=viewport @particles=[] @bitmaps={} end def setParameters(params) @randomhue,@leftright,@fade, @maxparticless,@hue,@slowdown, @ytop,@ybottom,@xleft,@xright, @xgravity,@ygravity,@xoffset,@yoffset, @opacityvar,@originalopacity=params end def loadBitmap(filename,hue) key=[filename,hue] bitmap=@bitmaps[key] if !bitmap || bitmap.disposed? bitmap=BitmapCache.fog(filename,hue) @bitmaps[key]=bitmap end return bitmap end def initParticles(filename,opacity,zOffset=0,blendtype=1) @particles = [] @particlex = [] @particley = [] @opacity = [] @startingx = self.x + @xoffset @startingy = self.y + @yoffset @screen_x = self.x @screen_y = self.y @real_x = @event.real_x @real_y = @event.real_y @filename=filename @zoffset=zOffset @bmwidth=32 @bmheight=32 for i in 0...@maxparticless @particlex[i]=-@xoffset @particley[i]=-@yoffset @particles[i] = ParticleSprite.new(@viewport) @particles[i].bitmap = loadBitmap(filename, @hue) if filename if i==0 && @particles[i].bitmap @bmwidth=@particles[i].bitmap.width @bmheight=@particles[i].bitmap.height end @particles[i].blend_type = blendtype @particles[i].y = @startingy @particles[i].x = @startingx @particles[i].z = self.z+zOffset @opacity[i] = rand(opacity/4) @particles[i].opacity = @opacity[i] @particles[i].update end end def x return ScreenPosHelper.pbScreenX(@event) end def y return ScreenPosHelper.pbScreenY(@event) end def z return ScreenPosHelper.pbScreenZ(@event) end def update if @viewport && (@viewport.rect.x >= Graphics.width || @viewport.rect.y >= Graphics.height) return end selfX=self.x selfY=self.y selfZ=self.z newRealX=@event.real_x newRealY=@event.real_y @startingx = selfX + @xoffset @startingy = selfY + @yoffset @__offsetx=(@real_x==newRealX) ? 0 : selfX-@screen_x @__offsety=(@real_y==newRealY) ? 0 : selfY-@screen_y @screen_x = selfX @screen_y = selfY @real_x = newRealX @real_y = newRealY if @opacityvar>0 && @viewport opac=(255.0/@opacityvar) minX=opac*(-@xgravity*1.0 / @slowdown).floor + @startingx maxX=opac*(@xgravity*1.0 / @slowdown).floor + @startingx minY=opac*(-@ygravity*1.0 / @slowdown).floor + @startingy maxY=@startingy minX-=@bmwidth minY-=@bmheight maxX+=@bmwidth maxY+=@bmheight if maxX<0 || maxY<0 || minX>=Graphics.width || minY>=Graphics.height return end end particleZ=selfZ+@zoffset for i in 0...@maxparticless @particles[i].z = particleZ if @particles[i].y <= @ytop @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end if @particles[i].x <= @xleft @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end if @particles[i].y >= @ybottom @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end if @particles[i].x >= @xright @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end if @fade == 0 if @opacity[i] <= 0 @opacity[i] = @originalopacity @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end else if @opacity[i] <= 0 @opacity[i] = 250 @particles[i].y = @startingy + @yoffset @particles[i].x = @startingx + @xoffset @particlex[i]=0.0 @particley[i]=0.0 end end calcParticlePos(i) if @randomhue == 1 if @hue >= 360 @hue = 0 end @hue = @hue + 0.5 @particles[i].bitmap = loadBitmap(@filename, @hue) if @filename end @opacity[i] = @opacity[i] - rand(@opacityvar) @particles[i].opacity = @opacity[i] @particles[i].update end end def calcParticlePos(i) @leftright = rand(2) if @leftright == 1 xo=(-@xgravity*1.0 / @slowdown) else xo=(@xgravity*1.0 / @slowdown) end yo=(-@ygravity*1.0 / @slowdown) @particlex[i]+=xo @particley[i]+=yo @particlex[i]-=@__offsetx @particley[i]-=@__offsety @particlex[i]=@particlex[i].floor @particley[i]=@particley[i].floor @particles[i].x=@particlex[i]+@startingx+@xoffset @particles[i].y=@particley[i]+@startingy+@yoffset end def dispose for particle in @particles particle.dispose end for bitmap in @bitmaps.values bitmap.dispose end @particles.clear @bitmaps.clear end end class Particle_Engine::Fire < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,20,40,0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0.10,-5,-13,30,0]) initParticles("particle",250) end end class Particle_Engine::Smoke < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,0,80,20,0.5,-64, Graphics.height,-64,Graphics.width,0.5,0.10,-5,-15,5,80]) initParticles("smoke",250) end end class Particle_Engine::Teleport < ParticleEffect_Event def initialize(event,viewport) super setParameters([1,1,1,10,rand(360),1,-64, Graphics.height,-64,Graphics.width,0,3,-8,-15,20,0]) initParticles("wideportal",250) for i in 0...@maxparticless @particles[i].ox=16 @particles[i].oy=16 end end end class Particle_Engine::Spirit < ParticleEffect_Event def initialize(event,viewport) super setParameters([1,0,1,20,rand(360),0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0.10,-5,-13,30,0]) initParticles("particle",250) end end class Particle_Engine::Explosion < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,20,0,0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0.10,-5,-13,30,0]) initParticles("explosion",250) end end class Particle_Engine::Aura < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,20,0,1, -64,Graphics.height,-64,Graphics.width, 2,2,-5,-13,30,0]) initParticles("particle",250) end end class Particle_Engine::Soot < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,0,20,0,0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0.10,-5,-15,5, 80]) initParticles("smoke",100,0,2) end end class Particle_Engine::SootSmoke < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,0,30,0,0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0.10,-5,-15,5, 80]) initParticles("smoke",100,0) for i in 0...@maxparticless @particles[i].blend_type = rand(6) < 3 ? 1 : 2 end end end class Particle_Engine::Rocket < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,0,60,0,0.5, -64,Graphics.height,-64,Graphics.width, 0.5,0,-5,-15,5,80]) initParticles("smoke",100,-1) end end class Particle_Engine::FixedTeleport < ParticleEffect_Event def initialize(event,viewport) super setParameters([1,0,1,10,rand(360),1, -Graphics.height,Graphics.height,0,Graphics.width,0,3,-8,-15,20,0]) initParticles("wideportal",250) for i in 0...@maxparticless @particles[i].ox=16 @particles[i].oy=16 end end end # By Peter O. class Particle_Engine::StarTeleport < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,10,0,1, -Graphics.height,Graphics.height,0,Graphics.width,0,3,-8,-15,10,0]) initParticles("star",250) for i in 0...@maxparticless @particles[i].ox=48 @particles[i].oy=48 end end end class Particle_Engine::Smokescreen < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,0,450,0,0.2, -64,Graphics.height,-64,Graphics.width, 0.8,0.8,-5,-15,5,80]) initParticles(nil,100) for i in 0...@maxparticless rnd=rand(3) @opacity[i] = (rnd==0) ? 1 : 100 filename=(rnd==0) ? "explosionsmoke" : "smoke" @particles[i].bitmap = loadBitmap(filename, @hue) end end def calcParticlePos(i) if @randomhue==1 filename=(rand(3)==0) ? "explosionsmoke" : "smoke" @particles[i].bitmap = loadBitmap(filename, @hue) end multiple = 1.7 xgrav=(@xgravity*multiple/@slowdown) xgrav=-xgrav if (rand(2)==1) ygrav=(@ygravity*multiple/@slowdown) ygrav=-ygrav if (rand(2)==1) @particlex[i]+=xgrav @particley[i]+=ygrav @particlex[i]-=@__offsetx @particley[i]-=@__offsety @particlex[i]=@particlex[i].floor @particley[i]=@particley[i].floor @particles[i].x=@particlex[i]+@startingx+@xoffset @particles[i].y=@particley[i]+@startingy+@yoffset end end class Particle_Engine::Flare < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,30,10,1, -64,Graphics.height,-64,Graphics.width, 2,2,-5,-12,30,0]) initParticles("particle",255) end end class Particle_Engine::Splash < ParticleEffect_Event def initialize(event,viewport) super setParameters([0,0,1,30,255,1, -64,Graphics.height,-64,Graphics.width, 4,2,-5,-12,30,0]) initParticles("smoke",50) end def update super for i in 0...@maxparticless @particles[i].opacity=50 @particles[i].update end end end class Game_Event < Game_Character #-------------------------------------------------------------------------- attr_accessor :pe_refresh #-------------------------------------------------------------------------- alias nf_particles_game_map_initialize initialize alias nf_particles_game_map_refresh refresh #-------------------------------------------------------------------------- def initialize(map_id,event,map=nil) @pe_refresh=false begin nf_particles_game_map_initialize(map_id, event,map) rescue ArgumentError nf_particles_game_map_initialize(map_id, event) end end #-------------------------------------------------------------------------- def refresh nf_particles_game_map_refresh @pe_refresh=true end end