Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.
Conectarse

Recuperar mi contraseña

Últimos temas
» Gameplay - Mansión Rybi - RMVXA.
por Miky Joe 2018-12-10, 08:36

» The Town of The Lost Witch [Horror/Suspense] - Enero 2019
por rstudios 2018-12-10, 01:20

» muchas dudas
por DiegoArancibia 2018-12-09, 16:55

» Galería Miky Art [Bocetos y más]
por Miky Joe 2018-12-09, 09:16

» Hemos vuelto
por alex1633 2018-12-08, 23:17

» [MV] Precognition
por franciscojapones 2018-12-08, 07:06

» (AJUDA) Conpatibilidade de 2 scripts simples
por orochii 2018-12-08, 03:14

» ("TCG") Que RPG Maker es el recomendado?
por orochii 2018-12-08, 03:03

» BOAS VINDAS
por orochii 2018-12-08, 02:58

» Script de mensaje de Wecoc
por orochii 2018-12-07, 23:43

Afiliados

[XP] Múltiples Animaciones

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP [XP] Múltiples Animaciones

Mensaje por Wecoc el 2016-02-14, 04:37

Éste script lo empecé hace un tiempo (me sorprende que no publicara nada al respecto, pero según parece no lo hice)
Hoy después de tanto tiempo decidí terminarlo. Permite aplicar múltiples animaciones simultáneas a un battler o character.

También incluye como atajo animation y loop_animation en Game_Battler y Game_Character de modo que por ejemplo se puede llamar así desde el editor:

$game_player.animation(4, true) # (id de animación, hit)

Código:
#==============================================================================
# ** [XP] Multiple Animations
#------------------------------------------------------------------------------
# Autor: Wecoc (no requiere créditos)
#==============================================================================

#==============================================================================
# * Sprite_Animation
#==============================================================================

class Sprite_Animation
  
  attr_reader   :sprite
  attr_reader   :viewport
  attr_reader   :animation
  attr_reader   :hit
  attr_reader   :sprites
  attr_reader   :fixed
  
  attr_accessor :frame_index
  
  def initialize(animation, hit, sprite = nil, fixed = false)
    @sprite = sprite
    @viewport = @sprite.viewport
    @animation = animation
    @hit = hit
    @fixed = fixed
    animation_name = @animation.animation_name
    animation_hue = @animation.animation_hue
    bitmap = RPG::Cache.animation(animation_name, animation_hue)
    @sprites = []
    @frame_index = 0
    for i in 0..15
      sprite = Sprite.new(viewport)
      sprite.bitmap = bitmap
      sprite.visible = false
      @sprites.push(sprite)
    end
  end
  
  def dispose
    @sprites.each do |sprite|
      sprite.bitmap.dispose
      sprite.dispose
      sprite = nil
    end
  end
  
  def update
    update_sprites
    for timing in @animation.timings
      if timing.frame == @frame_index
        update_process_timing(timing)
      end
    end
    @frame_index += 1
  end
  
  def update_sprites
    cell_data = @animation.frames[@frame_index].cell_data
    position = @animation.position
    for i in 0..15
      sprite = @sprites[i]
      pattern = cell_data[i, 0]
      if sprite == nil or pattern == nil or pattern == -1
        sprite.visible = false if sprite != nil
        next
      end
      sprite.visible = true
      sprite.src_rect.set(pattern % 5 * 192, pattern / 5 * 192, 192, 192)
      if position == 3
        if self.viewport != nil
          sprite.x = self.viewport.rect.width / 2
          sprite.y = self.viewport.rect.height - 160
        else
          sprite.x = 320
          sprite.y = 240
        end
      else
        sprite.x = @sprite.x - @sprite.ox + @sprite.src_rect.width / 2
        sprite.y = @sprite.y - @sprite.oy + @sprite.src_rect.height / 2
        sprite.y -= @sprite.src_rect.height / 4 if position == 0
        sprite.y += @sprite.src_rect.height / 4 if position == 2
      end
      sprite.x += cell_data[i, 1]
      sprite.y += cell_data[i, 2]
      sprite.z = 2000
      sprite.ox = 96
      sprite.oy = 96
      sprite.zoom_x = cell_data[i, 3] / 100.0
      sprite.zoom_y = cell_data[i, 3] / 100.0
      sprite.angle = cell_data[i, 4]
      sprite.mirror = (cell_data[i, 5] == 1)
      sprite.opacity = cell_data[i, 6] * @sprite.opacity / 255.0
      sprite.blend_type = cell_data[i, 7]
    end
  end
  
  def update_process_timing(timing)
    if (timing.condition == 0) or
       (timing.condition == 1 and @hit == true) or
       (timing.condition == 2 and @hit == false)
      if timing.se.name != ""
        se = timing.se
        Audio.se_play("Audio/SE/" + se.name, se.volume, se.pitch)
      end
      case timing.flash_scope
      when 1
        @sprite.flash(timing.flash_color, timing.flash_duration * 2)
      when 2
        if self.viewport != nil
          self.viewport.flash(timing.flash_color, timing.flash_duration * 2)
        end
      when 3
        @sprite.flash(nil, timing.flash_duration * 2)
      end
    end
  end
end

#==============================================================================
# * RPG::Sprite
#==============================================================================

module RPG
  class Sprite < ::Sprite
    
    attr_accessor :animations
    attr_accessor :loop_animations
    
    def initialize(viewport = nil)
      super(viewport)
      @_whiten_duration = 0
      @_appear_duration = 0
      @_escape_duration = 0
      @_collapse_duration = 0
      @_damage_duration = 0
      @_blink = false
      @animations = []
      @loop_animations = []
    end
    
    def effect?
      @_whiten_duration > 0 or
      @_appear_duration > 0 or
      @_escape_duration > 0 or
      @_collapse_duration > 0 or
      @_damage_duration > 0 or
      @animations.size > 0
    end
    
    def animation(animation, hit, fixed = false)
      if animation == nil
        return
      end
      animation = Sprite_Animation.new(animation, hit, self, fixed)
      @animations.push(animation)
    end
    
    def loop_animation(animation, hit = false)
      if animation == nil
        dispose_loop_animations
        return
      end
      animation = Sprite_Animation.new(animation, hit, self, false)
      @loop_animations.push(animation)
    end
    
    def update
      super
      update_whiten
      update_appear
      update_escape
      update_collapse
      update_damage
      if Graphics.frame_count % 2 == 0
        update_animation
        update_loop_animation
      end
      update_blink
    end
    
    def update_whiten
      if @_whiten_duration > 0
        @_whiten_duration -= 1
        self.color.alpha = 128 - (16 - @_whiten_duration) * 10
      end
    end
    
    def update_appear
      if @_appear_duration > 0
        @_appear_duration -= 1
        self.opacity = (16 - @_appear_duration) * 16
      end
    end
    
    def update_escape
      if @_escape_duration > 0
        @_escape_duration -= 1
        self.opacity = 256 - (32 - @_escape_duration) * 10
      end
    end
    
    def update_collapse
      if @_collapse_duration > 0
        @_collapse_duration -= 1
        self.opacity = 256 - (48 - @_collapse_duration) * 6
      end
    end
    
    def update_damage
      if @_damage_duration > 0
        @_damage_duration -= 1
        case @_damage_duration
        when 38..39
          @_damage_sprite.y -= 4
        when 36..37
          @_damage_sprite.y -= 2
        when 34..35
          @_damage_sprite.y += 2
        when 28..33
          @_damage_sprite.y += 4
        end
        @_damage_sprite.opacity = 256 - (12 - @_damage_duration) * 32
        if @_damage_duration == 0
          dispose_damage
        end
      end
    end
    
    def update_blink
      if @_blink
        @_blink_count = (@_blink_count + 1) % 32
        if @_blink_count < 16
          alpha = (16 - @_blink_count) * 6
        else
          alpha = (@_blink_count - 16) * 6
        end
        self.color.set(255, 255, 255, alpha)
      end
    end
    
    def update_animation
      @animations.each do |animation|
        animation.update
        if animation.frame_index == animation.animation.frame_max
          animation.dispose
          @animations.delete(animation)
        end
      end
    end
    
    def update_loop_animation
      @loop_animations.each do |loop_animation|
        loop_animation.update
        if loop_animation.frame_index == loop_animation.animation.frame_max
          loop_animation.frame_index = 0
        end
      end
    end
    
    def dispose_loop_animations
      @loop_animations.each do |loop_animation|
        loop_animation.dispose
        @loop_animations.delete(loop_animation)
      end
      @loop_animations = []
    end
    
    def x=(x)
      sx = x - self.x
      if sx != 0
        @animations.each do |animation|
          if animation.fixed == false
            animation.sprites.each do |frame|
              frame.x += sx
            end
          end
        end
        @loop_animations.each do |loop_animation|
          if loop_animation.fixed == false
            loop_animation.sprites.each do |frame|
              frame.x += sx
            end
          end
        end
      end
      super
    end
    
    def y=(y)
      sy = y - self.y
      if sy != 0
        @animations.each do |animation|
          if animation.fixed == false
            animation.sprites.each do |frame|
              frame.y += sy
            end
          end
        end
        @loop_animations.each do |loop_animation|
          if loop_animation.fixed == false
            loop_animation.sprites.each do |frame|
              frame.y += sy
            end
          end
        end
      end
      super
    end
  end
end

#==============================================================================
# * Game_Battler
#==============================================================================

class Game_Battler
  
  attr_accessor :animations
  attr_accessor :loop_animations
  

  alias web_multi_ani_ini initialize unless $@
  def initialize
    web_multi_ani_ini
    @animations = []
    @loop_animations = []
  end
  
  def animation(animation, hit, fixed = false)
    if animation.is_a?(Integer)
      animation = $data_animations[animation]
    end
    @animations.push([animation, hit, fixed])
  end
  
  def loop_animation(animation, hit = false)
    if animation.is_a?(Integer)
      animation = $data_animations[animation]
    end
    @loop_animations.push([animation, hit])
  end  
end

#==============================================================================
# * Game_Character
#==============================================================================

class Game_Character
  
  attr_accessor :animations
  attr_accessor :loop_animations

  alias web_multi_ani_ini initialize unless $@
  def initialize
    web_multi_ani_ini
    @animations = []
    @loop_animations = []
  end
  
  def animation(animation, hit, fixed = false)
    if animation.is_a?(Integer)
      animation = $data_animations[animation]
    end
    @animations.push([animation, hit, fixed])
  end
  
  def loop_animation(animation, hit = false)
    if animation.is_a?(Integer)
      animation = $data_animations[animation]
    end
    @loop_animations.push([animation, hit])
  end
end

#==============================================================================
# * Sprite_Battler
#==============================================================================

class Sprite_Battler < RPG::Sprite
  def update
    super
    if @battler == nil
      self.bitmap = nil
      loop_animation(nil)
      return
    end
    if @battler.battler_name != @battler_name or
       @battler.battler_hue != @battler_hue
      @battler_name = @battler.battler_name
      @battler_hue = @battler.battler_hue
      self.bitmap = RPG::Cache.battler(@battler_name, @battler_hue)
      @width = bitmap.width
      @height = bitmap.height
      self.ox = @width / 2
      self.oy = @height
      if @battler.dead? or @battler.hidden
        self.opacity = 0
      end
    end
    if @battler.damage == nil and
       @battler.state_animation_id != @state_animation_id
      @state_animation_id = @battler.state_animation_id
      loop_animation($data_animations[@state_animation_id])
    end
    if @battler.is_a?(Game_Actor) and @battler_visible
      if $game_temp.battle_main_phase
        self.opacity += 3 if self.opacity < 255
      else
        self.opacity -= 3 if self.opacity > 207
      end
    end
    if @battler.blink
      blink_on
    else
      blink_off
    end
    unless @battler_visible
      if not @battler.hidden and not @battler.dead? and
         (@battler.damage == nil or @battler.damage_pop)
        appear
        @battler_visible = true
      end
    end
    if @battler_visible
      if @battler.hidden
        $game_system.se_play($data_system.escape_se)
        escape
        @battler_visible = false
      end
      if @battler.white_flash
        whiten
        @battler.white_flash = false
      end
      for i in 0...@battler.animations.size
        animation = @battler.animations[i]
        animation(*animation)
        @battler.animations[i] = nil
      end
      @battler.animations = []
      for i in 0...@battler.loop_animations.size
        animation = @battler.loop_animations[i]
        loop_animation(*animation)
        @battler.loop_animations[i] = nil
      end
      @battler.loop_animations = []      
      if @battler.damage_pop
        damage(@battler.damage, @battler.critical)
        @battler.damage = nil
        @battler.critical = false
        @battler.damage_pop = false
      end
      if @battler.damage == nil and @battler.dead?
        if @battler.is_a?(Game_Enemy)
          $game_system.se_play($data_system.enemy_collapse_se)
        else
          $game_system.se_play($data_system.actor_collapse_se)
        end
        collapse
        @battler_visible = false
      end
    end
    self.x = @battler.screen_x
    self.y = @battler.screen_y
    self.z = @battler.screen_z
  end
end

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

class Sprite_Character < RPG::Sprite
  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
      sy = (@character.direction - 2) / 2 * @ch
      self.src_rect.set(sx, sy, @cw, @ch)
    end
    self.x = @character.screen_x
    self.y = @character.screen_y
    self.z = @character.screen_z(@ch)
    self.opacity = @character.opacity
    self.blend_type = @character.blend_type
    self.bush_depth = @character.bush_depth
    for i in 0...@character.animations.size
      animation = @character.animations[i]
      animation(*animation)
      @character.animations[i] = nil
    end
    @character.animations = []
    for i in 0...@character.loop_animations.size
      animation = @character.loop_animations[i]
      loop_animation(*animation)
      @character.loop_animations[i] = nil
    end
    @character.loop_animations = []
  end
end

#==============================================================================
# * Interpreter
#==============================================================================

class Interpreter
  #--------------------------------------------------------------------------
  # * Show Animation
  #--------------------------------------------------------------------------
  def command_207
    character = get_character(@parameters[0])
    if character == nil
      return true
    end
    character.animation($data_animations[@parameters[1]], true)
    return true
  end
  #--------------------------------------------------------------------------
  # * Show Battle Animation
  #--------------------------------------------------------------------------
  def command_337
    iterate_battler(@parameters[0], @parameters[1]) do |battler|
      if battler.exist?
        battler.animation($data_animations[@parameters[2]], true)
      end
    end
    return true
  end
end

#==============================================================================
# * Scene_Battle
#==============================================================================

class Scene_Battle
  def update_phase4_step3
    if @animation1_id == 0
      @active_battler.white_flash = true
    else
      @active_battler.animation($data_animations[@animation1_id], true)
    end
    @phase4_step = 4
  end
  
  def update_phase4_step4
    for target in @target_battlers
      hit = (target.damage != "Miss")
      target.animation($data_animations[@animation2_id], hit)
    end
    @wait_count = 8
    @phase4_step = 5
  end
end
avatar
Wecoc
Administrador
Administrador



Créditos 12314

Gracias : 655

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Múltiples Animaciones

Mensaje por kyonides-arkanthos el 2016-02-14, 14:10

Noté esto en su código...
Código:
   for i in 0..15
      sprite = Sprite.new(viewport)
      sprite.bitmap = bitmap
      sprite.visible = false
      @sprites.push(sprite)
    end

Me parece que puede quedar así sin problemas, pero se lo dejo a su discreción.
Código:
   for i in 0..15
      @sprites << sprite = Sprite.new(viewport)
      sprite.bitmap = bitmap
      sprite.visible = false
    end

Pero lo que me causa curiosidad es saber si asignarle la misma animación a los 15 cuadros es realmente necesario. ¿No tenía efectos adversos al hacer pruebas con su script? ¿O el contenido del bitmap era reemplazado posteriormente y en su totalidad las quince veces que eran necesarias? Lo pregunto porque la primera impresión es que todos los sprites son uno solo repetido 15 veces.

¿Ha llegado a idear una forma de predefinir las diferencias entre los 15 cuadros? Digo eso porque tal vez sea posible no calcular sus posiciones en plena ejecución de la animación sino solo leer las referencias calculadas al crear dicha animación.
avatar
kyonides-arkanthos
Principiante
Principiante

0/3

Créditos 585

Gracias : 86

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Múltiples Animaciones

Mensaje por Wecoc el 2016-02-14, 14:23

Las dos opciones son homólogas, y la primera es un poco más entendedora así que la dejaré tal cual.

En realidad lo de los 16 sprites está descrito así por defecto en RPG::Sprite, solo lo pasé a Sprite_Animation. Eso es así porque el editor de animaciones de la base de datos permite un máximo de 16 sprites por frame, además no concatenados, puedes usar el 1 y el 7 y ninguno en medio. No digo que cargarlos todos de buenas a primeras sea la forma más límpia a nivel de rendimiento del maker (la mayoría de animaciones no usan los 16) pero creo que sí que es la más límpia a nivel de código.

Lo que sí pasa (aunque ya pasaba sin el script) es que al irse a otra escena, por ejemplo el menú, y luego volver al mapa las animaciones desaparecen. Habría que hacer un script adicional que arregle eso tanto por defecto como en éste. Creo que es cuestión de almacenar las animation y loop_animation en $game_temp para luego cargarlas de nuevo, pero como eso sería para cada evento + jugador no es tan fácil... También cabe destacar que éste bug usando WSSB no ocurre.
avatar
Wecoc
Administrador
Administrador



Créditos 12314

Gracias : 655

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Múltiples Animaciones

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.