Sombra No RMXP Com Sprite_Shadow E Sprite_Sun

29 de abril de 2012

Achei esse script para o RPG Maker XP bacana, funcional e simples, o Sprite_Shadow.

O script, quando adicionado no projeto permite a criação de uma fonte de luz, que quando inserida em algum mapa, cria sombras no herói (automaticamente) e nos eventos, quando desejado pelo maker. A sombra muda seu ângulo e intensidade, de acordo com a fonte de luz no mapa. Parece que é compativel com o Caterpillar também.

Instruções

Para instalar o script, basta copiar e colar o seu código acima do Main.

Para criar uma fonte de luz num mapa, basta inserir o comentário begin shadow source num script. Você pode personalizar a fonte de luz com os seguintes argumentos em comentários no evento:

  • anglemin n e anglemax n: Substitua n por um número de um ângulo. Os ângulos seguem a grade de coordenadas polares (Polar Coordinate Grid). Se você não sabe o que é isso, eu também não sei, use o Google…
  • distancemax n: Substitua n com o número um para justificar o raio do efeito de sombras. Quanto maior o número, mais longe o actor vai ter sombra.
  • opacity n: Substitua n por um valor de opacidade. 255 fica mais preto preto, e 0 sendo completamente transparente.

Para colocar sombra em algum evento (sem ser o herói), basta colocar o comentário begin shadow. Funciona melhor em chars bípedes, ficando meio esquisito em animais quadrúpedes (sem referências a alguns presentes) e objetos.

Para colocar uma sombra estática, como se fosse um sol, basta você ativar com um script que contenha o comentário begin sun. Note que você precisa de adicionar o código do Sprite_Sun em seu projeto também.

Exemplo

Crie um novo evento no mapa, use um grafico de uma fogueira qualquer e deixe para iniciar em apertar tecla.

Dentro dele adicione um comentário (ou anotação). Ele fica na primeira página da aba de eventos, na primeira coluna, no oitavo lugar de cima para baixo.

Adicione um comentário para cada uma destas instruções: begin shadow source, anglemin 0, anglemax 360 e distancemax 300. Pronto, pode rodar.

Código do Sprite_Shadow

#==============================================================================
#  –  Sprite_Shadow (Sprite_Ombre )
# Based on Genzai Kawakami's shadows, dynamisme&features by Rataime, extra features Boushy
#==============================================================================

CATERPILLAR_COMPATIBLE = true
SHADOW_WARN = true

class Game_Party
attr_reader :characters
end

class Sprite_Shadow < RPG::Sprite

attr_accessor :character

def initialize(viewport, character = nil,id=0)
   super(viewport)
   params=$shadow_spriteset.shadows[id]
   @source=params[0]
   @anglemin=0
   @anglemin=params[1] if params.size>1
   @anglemax=0
   @anglemax=params[2] if params.size>2
   @self_opacity=100
   @self_opacity=params[4] if params.size>4
   @distancemax=350
   @distancemax=params[3] if params.size>3
   @character = character
   update
end

def update

   if !in_range?(@character, @source, @distancemax)
     self.opacity=0
     return
   end
   super

   if @tile_id != @character.tile_id or
      @character_name != @character.character_name or
      @character_hue != @character.character_hue
     @tile_id = @character.tile_id
     @character_name = @character.character_name
     @character_hue = @character.character_hue
     if @tile_id >= 384
       self.bitmap = RPG::Cache.tile($game_map.tileset_name,
         @tile_id, @character.character_hue)
       self.src_rect.set(0, 0, 32, 32)
       self.ox = 16
       self.oy = 32
     else
       self.bitmap = RPG::Cache.character(@character.character_name,
         @character.character_hue)
       @cw = bitmap.width / 4
       @ch = bitmap.height / 4
       self.ox = @cw / 2
       self.oy = @ch
     end
   end
   self.visible = (not @character.transparent)
   if @tile_id == 0
     sx = @character.pattern * @cw
     sy = (@character.direction - 2) / 2 * @ch
     if self.angle>90 or angle<-90
       if @character.direction== 6
              sy = ( 4- 2) / 2 * @ch
       end
       if @character.direction== 4
              sy = ( 6- 2) / 2 * @ch
       end
       if @character.direction== 2
              sy = ( 8- 2) / 2 * @ch
       end
       if @character.direction== 8
              sy = ( 2- 2) / 2 * @ch
       end
     end
     self.src_rect.set(sx, sy, @cw, @ch)
   end
   self.x = @character.screen_x
   self.y = @character.screen_y-5
   self.z = @character.screen_z(@ch)-1
   self.blend_type = @character.blend_type
   self.bush_depth = @character.bush_depth
   if @character.animation_id != 0
     animation = $data_animations[@character.animation_id]
     animation(animation, true)
     @character.animation_id = 0
   end
   @deltax=@source.screen_x-self.x
   @deltay= @source.screen_y-self.y
   self.color = Color.new(0, 0, 0)
   @distance = ((@deltax ** 2) + (@deltay ** 2))
   self.opacity = @self_opacity*13000/((@distance*370/@distancemax)+6000)
   self.angle = 57.3*Math.atan2(@deltax, @deltay )
   @angle_trigo=self.angle+90
   if @angle_trigo<0
       @angle_trigo=360+@angle_trigo
    end
   if @anglemin !=0 or @anglemax !=0
      if (@angle_trigo<@anglemin or @angle_trigo>@anglemax) and @anglemin<@anglemax
        self.opacity=0
        return
      end
      if (@angle_trigo<@anglemin and @angle_trigo>@anglemax) and @anglemin>@anglemax
        self.opacity=0
        return
      end     
    end
end

def in_range?(element, object, range)# From Near's Anti Lag Script, edited
   x = (element.screen_x - object.screen_x) * (element.screen_x - object.screen_x)
   y = (element.screen_y - object.screen_y) * (element.screen_y - object.screen_y)
   r = x + y
   if r <= (range * range)
      return true
   else
     return false
   end
end

end

#===================================================
#  –¼ CLASS Sprite_Character edit
#===================================================

class Sprite_Character < RPG::Sprite
alias shadow_initialize initialize

def initialize(viewport, character = nil)
   @character = character
   super(viewport)
   @ombrelist=[]
   if character.is_a?(Game_Event) and $shadow_spriteset.shadows!=[]
     params = XPML_read("Shadow",@character.id,4)
     if params!=nil
       for i in 0...$shadow_spriteset.shadows.size
         @ombrelist.push(Sprite_Shadow.new(viewport, @character,i))
       end
     end
   end
   if character.is_a?(Game_Player) and $shadow_spriteset.shadows!=[]
     for i in 0...$shadow_spriteset.shadows.size
       @ombrelist.push(Sprite_Shadow.new(viewport, $game_player,i))
     end
     #===================================================
     #  — Compatibility with fukuyama's caterpillar script
     #===================================================
     if CATERPILLAR_COMPATIBLE and $game_party.characters!=nil
       for member in $game_party.characters
         for i in 0...$shadow_spriteset.shadows.size
           @ombrelist.push(Sprite_Shadow.new(viewport, member,i))
         end
       end
     end
     #===================================================
     #  — End of the compatibility
     #===================================================
   end
   shadow_initialize(viewport, @character)
end

alias shadow_update update

def update
   shadow_update
   if @ombrelist!=[]
     for i in 0...@ombrelist.size
       @ombrelist[i].update
     end
   end
end 

end

#===================================================
#  –¼ CLASS Game_Event edit
#===================================================
class Game_Event
attr_accessor :id
end

#===================================================
#  –¼ CLASS Spriteset_Map edit
#===================================================
class Spriteset_Map
attr_accessor :shadows
alias shadow_initialize initialize

def initialize
   $shadow_spriteset=self
   @shadows=[]
   warn=false
   for k in $game_map.events.keys.sort
     warn=true if ($game_map.events[k].list!=nil and $game_map.events[k].list[0].code == 108 and ($game_map.events[k].list[0].parameters == ["s"] or $game_map.events[k].list[0].parameters == ["o"]))
     params = XPML_read("Shadow Source",k,4)
     $shadow_spriteset.shadows.push([$game_map.events[k]]+params) if params!=nil
   end
   p "Warning : At least one event on this map uses the obsolete way to add shadows" if warn == true and SHADOW_WARN
   shadow_initialize
end
end

#===================================================
#  –¼ XPML Definition, by Rataime, using ideas from Near Fantastica
#
#   Returns nil if the markup wasn't present at all,
#   returns [] if there wasn't any parameters, else
#   returns a parameters list with "int" converted as int
#   eg :
#   begin first
#   begin second
#   param1 1
#   param2 two
#   begin third
#   anything 3
#
#   p XPML_read("first", event_id) -> []
#   p XPML_read("second", event_id) -> [1,"two"]
#   p XPML_read("third", event_id) -> [3]
#   p XPML_read("forth", event_id) -> nil
#===================================================

def XPML_read(markup,event_id,max_param_number=0)
   parameter_list = nil
   event=$game_map.events[event_id]
   return if event.list==nil
     for i in 0...event.list.size
       if event.list[i].code == 108 and event.list[i].parameters[0].downcase == "begin "+markup.downcase
         parameter_list = [] if parameter_list == nil
         for j in i+1...event.list.size
           if event.list[j].code == 108
             parts = event.list[j].parameters[0].split
             if parts.size!=1 and parts[0].downcase!="begin"
               if parts[1].to_i!=0 or parts[1]=="0"
                 parameter_list.push(parts[1].to_i)
               else
                 parameter_list.push(parts[1])
               end
             else
               return parameter_list
             end
           else
             return parameter_list
           end
           return parameter_list if max_param_number!=0 and j==i+max_param_number
         end
       end
     end
   return parameter_list
end

Código do Sprite_Sun

#==============================================================================
#  –  Sprite_Sun
# # Based on Sprite_Shadow, modified by Rataime
#==============================================================================

CATERPILLAR_COMPATIBLE = true
SUN_WARN =true

class Game_Party
attr_reader :characters
end

class Sprite_Sun < RPG::Sprite
attr_accessor :character           

def initialize(viewport, character = nil,id=0)
   super(viewport)
   @character = character
   params=$sun_spriteset.sun[id]
   self_angle=45
   self_angle=params[0] if params.size>0
   self_opacity=128
   self_opacity=params[1] if params.size>1
   @self_angle=self_angle
   @self_opacity=self_opacity
   update
end

def update
   super
   if @tile_id != @character.tile_id or
      @character_name != @character.character_name or
      @character_hue != @character.character_hue
     @tile_id = @character.tile_id
     @character_name = @character.character_name
     @character_hue = @character.character_hue
     if @tile_id >= 384
       self.bitmap = RPG::Cache.tile($game_map.tileset_name,
         @tile_id, @character.character_hue)
       self.src_rect.set(0, 0, 32, 32)
       self.ox = 16
       self.oy = 32
     else
       self.bitmap = RPG::Cache.character(@character.character_name,
         @character.character_hue)
       @cw = bitmap.width / 4
       @ch = bitmap.height / 4
       self.ox = @cw / 2
       self.oy = @ch
     end
   end

   self.visible = (not @character.transparent)

   if @tile_id == 0
    sx = @character.pattern * @cw
    @direct=@character.direction

     if self.angle>90 or angle<-90

       if @direct== 6
              sy = ( 4- 2) / 2 * @ch
     end
     if @direct== 4
              sy = ( 6- 2) / 2 * @ch
       end
       if @direct != 4 and @direct !=6
       sy = (@character.direction - 2) / 2 * @ch
         end
       else
    sy = (@character.direction - 2) / 2 * @ch
    end
      self.src_rect.set(sx, sy, @cw, @ch)
   end
   self.x = @character.screen_x
   self.y = @character.screen_y-5
   self.z = @character.screen_z(@ch)-1
   self.opacity = @self_opacity
   self.blend_type = @character.blend_type
   self.bush_depth = @character.bush_depth
   if @character.animation_id != 0
     animation = $data_animations[@character.animation_id]
     animation(animation, true)
     @character.animation_id = 0
   end
   self.angle = @self_angle.to_i-90
   self.color = Color.new(0, 0, 0)
end
end

#===================================================
#  –¼ CLASS Sprite_Character edit
#===================================================

class Sprite_Character < RPG::Sprite
alias sun_initialize initialize

def initialize(viewport, character = nil)
   @character = character
   super(viewport)
   @sunlist=[]
   if character.is_a?(Game_Event) and $sun_spriteset.sun!=[]
     params = XPML_read("Shadow",@character.id,2)
     if params!=nil
       for i in 0...$sun_spriteset.sun.size
         @sunlist.push(Sprite_Sun.new(viewport, @character,i))
       end
     end
   end
  if character.is_a?(Game_Player) and $sun_spriteset.sun!=[]
     for i in 0...$sun_spriteset.sun.size
       @sunlist.push(Sprite_Sun.new(viewport, $game_player,i))
     end
     #===================================================
     #  —¼ Compatibility with fukuyama's caterpillar script
     #===================================================
     if CATERPILLAR_COMPATIBLE and $game_party.characters!=nil
       for member in $game_party.characters
         for i in 0...$sun_spriteset.sun.size
           @sunlist.push(Sprite_Sun.new(viewport, member,i))
         end
       end
     end
     #===================================================
     #  —¼ End of the compatibility
     #===================================================
   end
   sun_initialize(viewport, @character)
end

alias sun_update update

def update
   sun_update
   if @sunlist!=[]
     for i in 0...@sunlist.size
       @sunlist[i].update
     end
   end
end 

end

#===================================================
#  –¼ CLASS Game_Event edit
#===================================================
class Game_Event
attr_accessor :id
end

#===================================================
#  –¼ CLASS Spriteset_Map edit
#===================================================
class Spriteset_Map
attr_accessor :sun
alias sun_initialize initialize

def initialize
   @sun=[]
   $sun_spriteset=self
   warn=false
   for k in $game_map.events.keys.sort
     warn=true if ($game_map.events[k].list!=nil and $game_map.events[k].list[0].code == 108 and ($game_map.events[k].list[0].parameters == ["sun"] or $game_map.events[k].list[0].parameters == ["o"]))
     params = XPML_read("Sun",k,2)
     $sun_spriteset.sun.push(params) if params!=nil
   end
   p "Warning : At least one event on this map uses the obsolete way to add a sun effect" if warn == true and SUN_WARN
   sun_initialize
end
end

#===================================================
#  –¼ XPML Definition, by Rataime, using ideas from Near Fantastica
#
#   Returns nil if the markup wasn't present at all,
#   returns [] if there wasn't any parameters, else
#   returns a parameters list with "int" converted as int
#   eg :
#   begin first
#   begin second
#   param1 1
#   param2 two
#   begin third
#   anything 3
#
#   p XPML_read("first", event_id) -> []
#   p XPML_read("second", event_id) -> [1,"two"]
#   p XPML_read("third", event_id) -> [3]
#   p XPML_read("forth", event_id) -> nil
#===================================================

def XPML_read(markup,event_id,max_param_number=0)
   parameter_list = nil
   event=$game_map.events[event_id]
   return if event.list==nil
     for i in 0...event.list.size
       if event.list[i].code == 108 and event.list[i].parameters[0].downcase == "begin "+markup.downcase
         parameter_list = [] if parameter_list == nil
         for j in i+1...event.list.size
           if event.list[j].code == 108
             parts = event.list[j].parameters[0].split
             if parts.size!=1 and parts[0].downcase!="begin"
               if parts[1].to_i!=0 or parts[1]=="0"
                 parameter_list.push(parts[1].to_i)
               else
                 parameter_list.push(parts[1])
               end
             else
               return parameter_list
             end
           else
             return parameter_list
           end
           return parameter_list if max_param_number!=0 and j==i+max_param_number
         end
       end
     end
   return parameter_list
end

Observação: se você gostou deste post ou ele lhe foi útil de alguma forma, por favor considere apoiar financeiramente a Gaming Room. Fico feliz só de ajudar, mas a contribuição do visitante é muito importante para que este site continua existindo e para que eu possa continuar provendo este tipo de conteúdo e melhorar cada vez mais. Clique aqui e saiba como. Obrigado!

Deixe um comentário

Inscreva-se na nossa newsletter!