Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

[Script fallido] Animación con viewport restringida

Ver el tema anterior Ver el tema siguiente Ir abajo

[Script fallido] Animación con viewport restringida

Mensaje por Wecoc el 2015-01-25, 22:34

Hice un script de animaciones con viewport restringida, de modo que sólo se ve en el recuadro del sprite. Lo posteo (como otros scripts fallidos que he posteado indicándolo explícitamente xD) para animar a scripters a hacer algo a partir de ésto.

Problemas:

- Se ve en el recuadro del sprite, no SOLO en el sprite. Para ello se necesitarían viewports (o mask) no rectangulares para poderlo cuadrar bien y así poder hacer una animación tipo pokémon. También se podría hacer sobre viewports rectangulares de 1x1px con su "mini-sprite" correspondiente. No probé esa opción porque se huele el lag desde aquí.
- En batalla no hay problema porque los battlers són estáticos, pero en mapa si mueves el sprite, se mueve el chara y la animación, pero no la viewport por lo que no se ve bien si mueves el chara durante una animación. Se puede actualizar la viewport en cada frame para evitar eso pero se huele el lag desde aquí.
- En batalla no hay problema pero en mapa la z del chara durante la animación se descoloca.
- Incompatibilidad alta puesto que Sprite_Character y Sprite_Battler pasan a depender de Sprite_Handler.

Objetivo:
Hacer animaciones fijadas al sprite, como algunas de las que salen en juegos comerciales como Pokémon.


Código:
#==============================================================================
# ** Sprite_Handler version ALFA
#==============================================================================

class Sprite_Handler
  def initialize(viewport=nil)
    @sprite = RPG::Sprite.new(viewport)
    @viewport = viewport
    @ani_wait_count = 0
    @fix_sprite = false
  end
 
  def method_missing(method, *args)
    @sprite.send(method, *args)
  end
 
  def x=(value)
    if @fix_sprite == true
      @sprite.x = value - @viewport_x
    else
      @sprite.x = value
    end
  end
 
  def y=(value)
    if @fix_sprite == true
      @sprite.y = value - @viewport_y
    else
      @sprite.y = value
    end
  end
 
  def fix_sprite
    x = @sprite.x
    y = @sprite.y
    z = @sprite.z
    opacity = @sprite.opacity
    zoom_x = @sprite.zoom_x
    zoom_y = @sprite.zoom_y
    ox = @sprite.ox
    oy = @sprite.oy
    blend_type = @sprite.blend_type
    angle = @sprite.angle
    visible = @sprite.visible
    mirror = @sprite.mirror
    bitmap = @sprite.bitmap.clone
    color = @sprite.color.clone
    scr_rect = @sprite.src_rect.clone
    tone = @sprite.tone.clone
    @sprite.dispose
    @sprite = nil
    @fix_sprite = true
    viewport = Viewport.new(x - ox, y - oy, scr_rect.width, scr_rect.height)
    viewport.z = @viewport.z
    @viewport_x = x - ox
    @viewport_y = y - oy
    @sprite = RPG::Sprite.new(viewport)
    @sprite.z = z
    @sprite.opacity = opacity
    @sprite.zoom_x = zoom_x
    @sprite.zoom_y = zoom_y
    @sprite.ox = ox
    @sprite.oy = oy
    @sprite.blend_type = blend_type
    @sprite.angle = angle
    @sprite.visible = visible
    @sprite.mirror = mirror
    @sprite.bitmap = bitmap
    @sprite.color = color
    @sprite.src_rect = src_rect
    @sprite.tone = tone
    return @sprite
  end
 
  def default_sprite
    x = @sprite.x
    y = @sprite.y
    z = @sprite.z
    opacity = @sprite.opacity
    zoom_x = @sprite.zoom_x
    zoom_y = @sprite.zoom_y
    ox = @sprite.ox
    oy = @sprite.oy
    blend_type = @sprite.blend_type
    angle = @sprite.angle
    visible = @sprite.visible
    mirror = @sprite.mirror
    bitmap = @sprite.bitmap.clone
    color = @sprite.color.clone
    scr_rect = @sprite.src_rect.clone
    tone = @sprite.tone.clone
    @sprite.dispose
    @sprite = nil
    @fix_sprite = false
    @sprite = RPG::Sprite.new(@viewport)
    @sprite.x = @viewport_x
    @sprite.y = @viewport_y
    @sprite.z = z
    @sprite.opacity = opacity
    @sprite.zoom_x = zoom_x
    @sprite.zoom_y = zoom_y
    @sprite.ox = ox
    @sprite.oy = oy
    @sprite.blend_type = blend_type
    @sprite.angle = angle
    @sprite.visible = visible
    @sprite.mirror = mirror
    @sprite.bitmap = bitmap
    @sprite.color = color
    @sprite.src_rect = src_rect
    @sprite.tone = tone
    return @sprite
  end
 
  def fix_animation(animation, hit)
    fix_sprite
    @sprite.animation(animation, hit)
    @ani_wait_count = animation.frame_max * 2
  end
 
  def update
    @sprite.update
    if @ani_wait_count > 0
      @ani_wait_count -= 1
      if @ani_wait_count == 0
        default_sprite
      end
    end
  end
end

class Game_Battler
  attr_accessor :fix_animation_id
  alias fix_ani_initialize initialize unless $@
  def initialize
    fix_ani_initialize
    @fix_animation_id = 0
  end
end

class Game_Character
  attr_accessor :fix_animation_id
  alias fix_ani_initialize initialize unless $@
  def initialize
    fix_ani_initialize
    @fix_animation_id = 0
  end
end
 
class Sprite_Character < Sprite_Handler
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :character                # character
  #--------------------------------------------------------------------------
  # * Object Initialization
  #    viewport  : viewport
  #    character : character (Game_Character)
  #--------------------------------------------------------------------------
  def initialize(viewport, character = nil)
    super(viewport)
    @character = character
    update
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If tile ID, file name, or hue are different from current ones
    if @tile_id != @character.tile_id or
      @character_name != @character.character_name or
      @character_hue != @character.character_hue
      # Remember tile ID, file name, and hue
      @tile_id = @character.tile_id
      @character_name = @character.character_name
      @character_hue = @character.character_hue
      # If tile ID value is valid
      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
      # If tile ID value is invalid
      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
    # Set visible situation
    self.visible = (not @character.transparent)
    # If graphic is character
    if @tile_id == 0
      # Set rectangular transfer
      sx = @character.pattern * @cw
      sy = (@character.direction - 2) / 2 * @ch
      self.src_rect.set(sx, sy, @cw, @ch)
    end
    # Set sprite coordinates
    self.x = @character.screen_x
    self.y = @character.screen_y
    self.z = @character.screen_z(@ch)
    # Set opacity level, blend method, and bush depth
    self.opacity = @character.opacity
    self.blend_type = @character.blend_type
    self.bush_depth = @character.bush_depth
    # Animation
    if @character.animation_id != 0
      animation = $data_animations[@character.animation_id]
      animation(animation, true)
      @character.animation_id = 0
    end
    if @character.fix_animation_id != 0
      animation = $data_animations[@character.fix_animation_id]
      fix_animation(animation, true)
      @character.fix_animation_id = 0
    end
  end
end

class Sprite_Battler < Sprite_Handler
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :battler                  # battler
  #--------------------------------------------------------------------------
  # * Object Initialization
  #    viewport : viewport
  #    battler  : battler (Game_Battler)
  #--------------------------------------------------------------------------
  def initialize(viewport, battler = nil)
    super(viewport)
    @battler = battler
    @battler_visible = false
  end
  #--------------------------------------------------------------------------
  # * Dispose
  #--------------------------------------------------------------------------
  def dispose
    if self.bitmap != nil
      self.bitmap.dispose
    end
    super
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If battler is nil
    if @battler == nil
      self.bitmap = nil
      loop_animation(nil)
      return
    end
    # If file name or hue are different than current ones
    if @battler.battler_name != @battler_name or
      @battler.battler_hue != @battler_hue
      # Get and set bitmap
      @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
      # Change opacity level to 0 when dead or hidden
      if @battler.dead? or @battler.hidden
        self.opacity = 0
      end
    end
    # If animation ID is different than current one
    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 actor which should be displayed
    if @battler.is_a?(Game_Actor) and @battler_visible
      # Bring opacity level down a bit when not in main phase
      if $game_temp.battle_main_phase
        self.opacity += 3 if self.opacity < 255
      else
        self.opacity -= 3 if self.opacity > 207
      end
    end
    # Blink
    if @battler.blink
      blink_on
    else
      blink_off
    end
    # If invisible
    unless @battler_visible
      # Appear
      if not @battler.hidden and not @battler.dead? and
        (@battler.damage == nil or @battler.damage_pop)
        appear
        @battler_visible = true
      end
    end
    # If visible
    if @battler_visible
      # Escape
      if @battler.hidden
        $game_system.se_play($data_system.escape_se)
        escape
        @battler_visible = false
      end
      # White flash
      if @battler.white_flash
        whiten
        @battler.white_flash = false
      end
      # Animation
      if @battler.animation_id != 0
        animation = $data_animations[@battler.animation_id]
        animation(animation, @battler.animation_hit)
        @battler.animation_id = 0
      end
      if @battler.fix_animation_id != 0
        animation = $data_animations[@battler.fix_animation_id]
        fix_animation(animation, @battler.animation_hit)
        @battler.fix_animation_id = 0
      end
      # Damage
      if @battler.damage_pop
        damage(@battler.damage, @battler.critical)
        @battler.damage = nil
        @battler.critical = false
        @battler.damage_pop = false
      end
      # Collapse
      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
    # Set sprite coordinates
    self.x = @battler.screen_x
    self.y = @battler.screen_y
    self.z = @battler.screen_z
  end
end


Instrucciones:
Las animaciones pueden ir como siempre.
Para poner animaciones normales en un evento usad:

$game_player.fix_animation_id = 1
$game_map.events[1].fix_animation_id = 1


Para probarlo en batalla también va igual, aunque es más cómodo sustituir las animaciones normales por esas para testearlo. Para ello solo hay que cambiar la línea:
def fix_animation(animation, hit)
por ésta:
def animation(animation, hit)

Scripters, si os gustan los retos enfrentaos a éste xD
avatar
Wecoc
Administrador
Administrador



Créditos 12208

Gracias : 632

Volver arriba Ir abajo

Re: [Script fallido] Animación con viewport restringida

Mensaje por orochii el 2015-01-25, 23:22

Los problemas de posiciones X/Y y la Z creo que son solucionables. Para la X/Y, sería hacer por decir algo,
viewport.rect.x = x

Y la z es más fácil, simplemente pones
viewport.z

Esas dos cosas se pueden actualizar cada frame sin problema de lag, creo. CREO.
avatar
orochii
Reportero

0/3

Créditos 7722

Gracias : 436

Volver arriba Ir abajo

Re: [Script fallido] Animación con viewport restringida

Mensaje por Wecoc el 2015-01-26, 00:15

Había pensado en trabajar a nivel de viewport.rect como alternativa, eso simplifica ciertas partes del script relacionadas con el Sprite, pero luego al actualizar otras cosas de la Viewport como el color o el tono sería más complicado puesto que ya no se está usando la viewport "global" si no una específica para el sprite.

Pongo la alternativa aquí.

Código:
#==============================================================================
# ** Sprite_Handler version ALFA
#==============================================================================

class Sprite_Handler
  def initialize(viewport=nil)
    @viewport = viewport
    viewport = Viewport.new(0, 0, 640, 480)
    viewport.z = @viewport.z
    @sprite = RPG::Sprite.new(viewport)
    @ani_wait_count = 0
    @fix_sprite = false
  end
 
  def method_missing(method, *args)
    @sprite.send(method, *args)
  end
 
  def x=(value)
    if @fix_sprite == true
      @sprite.x = value - @viewport_x
    else
      @sprite.x = value
    end
  end
 
  def y=(value)
    if @fix_sprite == true
      @sprite.y = value - @viewport_y
    else
      @sprite.y = value
    end
  end
 
  def fix_sprite
    @fix_sprite = true
    x = @sprite.x
    y = @sprite.y
    ox = @sprite.ox
    oy = @sprite.oy
    scr_rect = @sprite.src_rect
    @sprite.viewport.rect.x = x - ox
    @sprite.viewport.rect.y = y - oy
    @sprite.viewport.rect.width = scr_rect.width
    @sprite.viewport.rect.height = scr_rect.height
    @viewport_x = x - ox
    @viewport_y = y - oy
    return @sprite
  end
 
  def default_sprite
    @fix_sprite = false
    x = @sprite.viewport.rect.x
    y = @sprite.viewport.rect.y
    @sprite.viewport.rect.x = 0
    @sprite.viewport.rect.y = 0
    @sprite.viewport.rect.width = 640
    @sprite.viewport.rect.height = 480
    @viewport_x = 0
    @viewport_y = 0
    return @sprite
  end
 
  def fix_animation(animation, hit)
    fix_sprite
    @sprite.animation(animation, hit)
    @ani_wait_count = animation.frame_max * 2
  end
 
  def update
    @sprite.update
    if @ani_wait_count > 0
      @ani_wait_count -= 1
      if @ani_wait_count == 0
        default_sprite
      end
    end
  end
end

class Game_Battler
  attr_accessor :fix_animation_id
  alias fix_ani_initialize initialize unless $@
  def initialize
    fix_ani_initialize
    @fix_animation_id = 0
  end
end

class Game_Character
  attr_accessor :fix_animation_id
  alias fix_ani_initialize initialize unless $@
  def initialize
    fix_ani_initialize
    @fix_animation_id = 0
  end
end
 
class Sprite_Character < Sprite_Handler
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :character                # character
  #--------------------------------------------------------------------------
  # * Object Initialization
  #    viewport  : viewport
  #    character : character (Game_Character)
  #--------------------------------------------------------------------------
  def initialize(viewport, character = nil)
    super(viewport)
    @character = character
    update
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If tile ID, file name, or hue are different from current ones
    if @tile_id != @character.tile_id or
      @character_name != @character.character_name or
      @character_hue != @character.character_hue
      # Remember tile ID, file name, and hue
      @tile_id = @character.tile_id
      @character_name = @character.character_name
      @character_hue = @character.character_hue
      # If tile ID value is valid
      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
      # If tile ID value is invalid
      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
    # Set visible situation
    self.visible = (not @character.transparent)
    # If graphic is character
    if @tile_id == 0
      # Set rectangular transfer
      sx = @character.pattern * @cw
      sy = (@character.direction - 2) / 2 * @ch
      self.src_rect.set(sx, sy, @cw, @ch)
    end
    # Set sprite coordinates
    self.x = @character.screen_x
    self.y = @character.screen_y
    self.z = @character.screen_z(@ch)
    # Set opacity level, blend method, and bush depth
    self.opacity = @character.opacity
    self.blend_type = @character.blend_type
    self.bush_depth = @character.bush_depth
    # Animation
    if @character.animation_id != 0
      animation = $data_animations[@character.animation_id]
      animation(animation, true)
      @character.animation_id = 0
    end
    if @character.fix_animation_id != 0
      animation = $data_animations[@character.fix_animation_id]
      fix_animation(animation, true)
      @character.fix_animation_id = 0
    end
  end
end

class Sprite_Battler < Sprite_Handler
  #--------------------------------------------------------------------------
  # * Public Instance Variables
  #--------------------------------------------------------------------------
  attr_accessor :battler                  # battler
  #--------------------------------------------------------------------------
  # * Object Initialization
  #    viewport : viewport
  #    battler  : battler (Game_Battler)
  #--------------------------------------------------------------------------
  def initialize(viewport, battler = nil)
    super(viewport)
    @battler = battler
    @battler_visible = false
  end
  #--------------------------------------------------------------------------
  # * Dispose
  #--------------------------------------------------------------------------
  def dispose
    if self.bitmap != nil
      self.bitmap.dispose
    end
    super
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    # If battler is nil
    if @battler == nil
      self.bitmap = nil
      loop_animation(nil)
      return
    end
    # If file name or hue are different than current ones
    if @battler.battler_name != @battler_name or
      @battler.battler_hue != @battler_hue
      # Get and set bitmap
      @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
      # Change opacity level to 0 when dead or hidden
      if @battler.dead? or @battler.hidden
        self.opacity = 0
      end
    end
    # If animation ID is different than current one
    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 actor which should be displayed
    if @battler.is_a?(Game_Actor) and @battler_visible
      # Bring opacity level down a bit when not in main phase
      if $game_temp.battle_main_phase
        self.opacity += 3 if self.opacity < 255
      else
        self.opacity -= 3 if self.opacity > 207
      end
    end
    # Blink
    if @battler.blink
      blink_on
    else
      blink_off
    end
    # If invisible
    unless @battler_visible
      # Appear
      if not @battler.hidden and not @battler.dead? and
        (@battler.damage == nil or @battler.damage_pop)
        appear
        @battler_visible = true
      end
    end
    # If visible
    if @battler_visible
      # Escape
      if @battler.hidden
        $game_system.se_play($data_system.escape_se)
        escape
        @battler_visible = false
      end
      # White flash
      if @battler.white_flash
        whiten
        @battler.white_flash = false
      end
      # Animation
      if @battler.animation_id != 0
        animation = $data_animations[@battler.animation_id]
        animation(animation, @battler.animation_hit)
        @battler.animation_id = 0
      end
      if @battler.fix_animation_id != 0
        animation = $data_animations[@battler.fix_animation_id]
        fix_animation(animation, @battler.animation_hit)
        @battler.fix_animation_id = 0
      end
      # Damage
      if @battler.damage_pop
        damage(@battler.damage, @battler.critical)
        @battler.damage = nil
        @battler.critical = false
        @battler.damage_pop = false
      end
      # Collapse
      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
    # Set sprite coordinates
    self.x = @battler.screen_x
    self.y = @battler.screen_y
    self.z = @battler.screen_z
  end
end


Es decir, el script de arriba lo que hace es usar los sprites de siempre con su viewport, luego en el momento de la animación cambiar de sprite por otro igual pero con la viewport recortada (de momento rectangular) y al terminar la animación vuelve al sprite que toca.

La segunda opción hace que el sprite tenga una viewport propia para él solo, de ese modo en el momento de la animación ésta viewport es "recortada" al rectángulo que toca, y al terminar la animación vuelve a como antes, todo sin cambiar de sprite. Eso simplifica el código pero el problema de hacerlo así es que veo más difícil implementar viewports no cuadradas luego... aunque ni idea, así que mejor me callo xD
avatar
Wecoc
Administrador
Administrador



Créditos 12208

Gracias : 632

Volver arriba Ir abajo

Re: [Script fallido] Animación con viewport restringida

Mensaje por Metalero el 2015-01-26, 03:38

Hacer lo que queres hacer, usando solo ruby, no solo es dificil, si no que estoy bastante seguro de que no se puede hacer de forma eficiente (siempre va a ser necesario hacer manipulaciones a nivel pixel en cada frame... y todos sabemos que en el maker eso no sirve)

Una opcion un poco "out of the box" que se me ocurre, y que tiene muchas limitantes, pero deberia funcionar, es crear un sprite "mascara" por encima del sprite al que se quiere aplicar este efecto, con una "copia" del fondo.

Quedaria entonces: (en orden de menor Z, a mayor Z)

Background, Battler, Animacion, Mascara.

No se si se entiendo mas o menos la idea. Aca un intento de croquis:

Código:

Background      Battler      Animacion      Máscara         ->      Resultado
      
................      XX      SASDASD      ......   .......         ......SDA.....
................       X      SASDASD      ....... ........         .......D........
................      XXXX      SADASDA      ....        ....         ....ASDAS....
................       X      ASDASDA      .......  .......         .......A.......
................   X  X      ASDASDA      ....  ....  ....         ....D....S.....




La mascara deberia generarse cuando se inicia la batalla (tal vez produzca un poco de lag, pero solo seria al principio)

Se que es una solucion fea... pero si no la unica otro solucion que puede funcionar, necesita alguna DLL para manipular rapidamente los bitmaps, y ya es mucho mas complicado.

PD: el croquis se me deformó todo, pero creo que aun asi se entiende la idea.

_________________
avatar
Metalero
Administrador
Administrador



Créditos 1710

Gracias : 100

Volver arriba Ir abajo

Re: [Script fallido] Animación con viewport restringida

Mensaje por Wecoc el 2015-01-27, 17:57

Si lo he entendido, esa máscara sería como una copia del fondo, pero en la parte que ocuparía el sprite sería transparente... Suena interesante, pero no lo veo claro xD No sé cómo se haría para "pillar" el fondo y pasarlo a la bitmap, si es que es eso. ¿Y en ese caso no se requiere también set_pixel, para captar qué parte es transparente? Si el personaje se mueve estamos en las mismas, get_pixel cada frame xD Y todo porque el puñetero maker no tiene shaders. ¡Maldita sea su estampa! xD

Igualmente para hacer eso habría que fijarlo al rect del sprite (para que la máscara tenga el tamaño justo y aún así la animación no la sobrepase) por lo que la parte que puse arriba seguiría siendo necesaria, ¿no? :'(

En el caso de los charas con color bajo tiles de prioridad alta (link) usaste get_pixel y set_pixel y tampoco había tanto lag, puesto que los charas son mucho más pequeños que los battlers. Quizá suene muy chapuza pero como los battlers no se mueven y los charas sí, quizá lo mejor sería "refrescar" la máscara en mapa y no hacerlo en batalla xDD
avatar
Wecoc
Administrador
Administrador



Créditos 12208

Gracias : 632

Volver arriba Ir abajo

Re: [Script fallido] Animación con viewport restringida

Mensaje por Metalero el 2015-01-27, 19:53


Suena interesante, pero no lo veo claro xD No sé cómo se haría para "pillar" el fondo y pasarlo a la bitmap, si es que es eso. ¿Y en ese caso no se requiere también set_pixel, para captar qué parte es transparente? Si el personaje se mueve estamos en las mismas, get_pixel cada frame xD Y todo porque el puñetero maker no tiene shaders. ¡Maldita sea su estampa! xD



Si, es eso. Primero, general la mascara es facil, hay que calcular a que "rect" del fondo corresponde cada battler (sumas y restas). Con eso, si, hay que genera el bitmap usando get_pixel y set_pixel.
Es cierto que es lento, pero si solo se hace una vez, no deberia molestar.

Y si, si el pj se mueve, o el fondo se mueve o cambia, o cualquier caso donde no esten las "formas" estaticas, ya no sirve mas (por eso puse que tenia muchas limitantes)


Igualmente para hacer eso habría que fijarlo al rect del sprite (para que la máscara tenga el tamaño justo y aún así la animación no la sobrepase) por lo que la parte que puse arriba seguiría siendo necesaria, ¿no? :'(



Al decir "fijarlo a rect" te referias al viewport?
En este momento ya no me acuerdo bien como organiza el maker los viewports y sprites, pero hacerlo o no en el vierport no cambia mucho, calculo que usando el viewport del battler (si tiene) es mas sencillo.


En el caso de los charas con color bajo tiles de prioridad alta (link) usaste get_pixel y set_pixel y tampoco había tanto lag, puesto que los charas son mucho más pequeños que los battlers. Quizá suene muy chapuza pero como los battlers no se mueven y los charas sí, quizá lo mejor sería "refrescar" la máscara en mapa y no hacerlo en batalla xDD



Pfff.... ni me acordaba de eso (me estoy volviendo viejo)
ni me acuerdo muy bien como funcionaba, pero si, usa get_pixel y set_pixel.

No se habria que probar usando set_pixel y get_pixel, pero para mi no va a funcionar bien.

Lo ultimo, de refrescar la mascara en el mapa, no entendi que quiciste decir

_________________
avatar
Metalero
Administrador
Administrador



Créditos 1710

Gracias : 100

Volver arriba Ir abajo

Re: [Script fallido] Animación con viewport restringida

Mensaje por orochii el 2015-01-27, 23:27

¿Qué tal si en lugar de hacer un chorro de get/set_pixel, se copiara el alfa de un bitmap a otro?

Buscando si se podía acceder a la información directamente, me encontré esto, que no usa DLLs nuevos por así decirlo (?). El método es técnicamente lo que hacen con DLLs xD, que es usar un puntero a una dirección y trabajar con los bytes en memoria, en éste caso usando el kernel32.dll (en C sería menos chapuza xD, digo, ahí está llamando una y otra vez a un DLL, y en C se podría hacer directamente, sin intermediarios :V, casteando y así, como en el XPA Tilemap que ví un rato el Tilemap_C, y usaba unos structs y cosas así para castear un puntero a esas estructuras).
Quiza con los métodos que se usan ahí se pueda copiar canales alfa de un bitmap a otro xD.
Link a post original
Link a script en Dropbox

En fin, yo no sé xD.
avatar
orochii
Reportero

0/3

Créditos 7722

Gracias : 436

Volver arriba Ir abajo

Re: [Script fallido] Animación con viewport restringida

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.