martes, 6 de agosto de 2013

Leccion 2: Script de Cambio de sonido

Bienvenidos, estuve todo el rato haciendo conceptos basicos para hacer finalmente un script bastante facilito que parece complejo, no vamos a ver el video del usuario de siempre, sino de otra persona, podrán ver el video en ingles, y luego veremos como hacerlo, asi que finalmente, podremos ver algo para el juego que ya pueden implementar a su juego :)) ... un detalle es que por ahora esta explicado con el rgss3 que es del rmvx ace, despues se posteará el de vx... Comencemos




 El script que se explicará aca es que cuando el personaje no pueda pasar por algun lado, haga algún sonido de colision, vamos por partes...

 Primero crearemos un nuevo script en insertar, arriba de main, para saber como el personaje se detiene en el juego, tendremos que buscar en todos los script esa parte, para hacerlo mas facil haremos el buscar con la siquiente busqueda passable con esto nos saldrá la ventana de busqueda, como necesitamos saber como lo hace el personaje nos meteremos en la que dice Game_Characterbase (168)...

aca nos saldrá esto:

 def passable?(x, y, d)
    x2 = $game_map.round_x_with_direction(x, d)
    y2 = $game_map.round_y_with_direction(y, d)
    return false unless $game_map.valid?(x2, y2)
    return true if @through || debug_through?
    return false unless map_passable?(x, y, d)
    return false unless map_passable?(x2, y2, reverse_dir(d))
    return false if collide_with_characters?(x2, y2)
    return true
end

  Lo que hace esto es ver donde se ubica el personaje, que no se salga de los bordes y que no traspase las cosas que estan marcadas con la X cuando vemos los permisos en los tilesets... para eso copiaremos todo esto y lo pegaremos en nuestro nuevo script, antes del def copiaremos la class del Game_Player esta de aqui class Game_Player < Game_Character y la pegaremos encima... nos quedaria algo asi:

class Game_Player < Game_Character
 
  def passable?(x, y, d)
    x2 = $game_map.round_x_with_direction(x, d)
    y2 = $game_map.round_y_with_direction(y, d)
    return false unless $game_map.valid?(x2, y2)
    return true if @through || debug_through?
    return false unless map_passable?(x, y, d)
    return false unless map_passable?(x2, y2, reverse_dir(d))
    return false if collide_with_characters?(x2, y2)
    return true
  end

end

 Bien, como queremos modificar este metodo para que haga el sonido, no podemos modificarlo, tal cual esta, debido a que si lo hacemos podrias producirse un error, debido a que este script depende de otros más y está todos unidos.... para eso utilizaremos un alias que nos ayudará a mantener el script original y agregaremos parte del nuevo.

 Como se dijo antes utilizaremos un alias que queramos seguido del metodo puesto passable?, el mio será asi, mono_sonidocolision_gameplayer_passable  passable?,  como ya esta puesto, no será necesario lo que lleve puesto el metodo passable?, por lo tanto borraremos todo lo que tiene y pondremos nuestro alias sin el metodo que va despues del espacio, quedaría asi

class Game_Player < Game_Character
 
  alias mono_sonidocolision_gameplayer_passable  passable?
  def passable?(x, y, d)
    mono_sonidocolision_gameplayer_passable
  end

end

 Bien, ahora lo que haremos es que nuestro alias, que es el que lleva todo lo del script original, se guarde en una variable local, para que tenga todos los valores de si no podemos pasar, pasemos, etc... le pondremos a esta variable passable. Por lo que nos quedaria que passable =  mono_sonidocolision_gameplayer_passable y como vemos que el metodo passable? necesita de tres variables x, y  y  d, nuestro alias tambien deberá llevarlos o sino nos dará error, por lo tanto la variable local passable quedará asi
passable =  mono_sonidocolision_gameplayer_passable( x, y, d)

 Tenemos ya una idea de lo que puede pasar, como passable viene del ingles pasable, imaginemonos que pasaria si es verdad o sea que se puede pasar, y si es falso, o sea que no se puede pasar, para esto utilizaremos un if que nos maracara cuando hacer el sonido y cuando no lo hará.

 Para este if pondremos nuestra variable passable seguido de lo que nos importa, que no se pueda pasar, o sea, false . Si passable == false, entonces reproduciremos un SE del juego, este puede ser cualquiera pero le pondremos el de "Bite", nos quedaría hasta el momento asi

class Game_Player < Game_Character
 
  alias mono_sonidocolision_gameplayer_passable  passable?
  def passable?(x, y, d)
    passable = mono_sonidocolision_gameplayer_passable( x, y, d)
    if passable == false
      RPG::SE.new("Bite", 80, 100).play
    end
  end

end

 Lo de la musica lo veremos en el anexo...

 Luego terminamos nuestro script, pero falta algo importantisimo, que como este metodo funciona si ocurre algo, si lo dejamos asi, no estará devolviendo un valor al script original, por lo que necesitaremos devolver lo que esta haciendo, para esto utilizaremos un return que hará que lo que hicimos se vaya al juego, por asi decirlo, por lo que luego del end del if, pondremos que retorne la variable local passable, de esta manera:

class Game_Player < Game_Character
  
  alias mono_sonidocolision_gameplayer_passable  passable?
  def passable?(x, y, d)
    passable = mono_sonidocolision_gameplayer_passable( x, y, d)
    if passable == false
      RPG::SE.new("Bite", 80, 100).play
    end
    return passable
  end

end

 
 Listo tenemos nuestro script, preparado para funcionar.... pruebalo y dime que tal...


 ¿Hay algo que no te gusta cierto?, pues debe ser a que el sonido se repite muchas veces y no cada cierto tiempo... para eso arreglaremos el script, para que cada cierto tiempo se reproduzca.... sigamos entonces

generaremos un timer... para eso buscaremos el initialize de la class Game_Player, que es este de aca:

def initialize
    super
    @vehicle_type = :walk          
    @vehicle_getting_on = false 
    @vehicle_getting_off = false    
    @followers = Game_Followers.new(self)
    @transparent = $data_system.opt_transparent
    clear_transfer_info
  end

 y lo pegaremos encima del alias que generamos, a este initialize tambien le haremos un alias y borraremos lo que lleve dentro... ¿porque pegamos un initialize?, porque el initialize es el "inicial" del script, alli van todos los datos antes de.., y para eso, usaremos el initialize para generar el timer que controla el tiempo de reproduccion del SE.

bueno con esta explicacion el script deberia quedar asi:

class Game_Player < Game_Character
#--------------------------------------------------------------------
#------------------------- INITIALIZE -------------------------------
#--------------------------------------------------------------------
  alias mono_sonidocolision_gameplayer_initialize  initialize
  def initialize
    mono_sonidocolision_gameplayer_initialize
  end
#--------------------------------------------------------------------
#------------------------- MOVIBLE -------------------------------
#--------------------------------------------------------------------  
  alias mono_sonidocolision_gameplayer_passable  passable?
  def passable?(x, y, d)
    passable = mono_sonidocolision_gameplayer_passable( x, y, d)
    if passable == false
      RPG::SE.new("Bite", 80, 100).play
    end
    return passable
  end

end


 Generaremos el timer ahora.... para eso haremos una variable de metodo (@)  y le pndremos 
@timer_del_SE , a esta le asignaremos el valor 0 (@timer_del_SE = 0).

 Luego en la parte del sonido colocaremos esta variable y le colocaremos igual a 60, ¿porque?, esperemos al todo para tener la idea, quedaria algo asi:

class Game_Player < Game_Character
#--------------------------------------------------------------------
#------------------------- INITIALIZE -------------------------------
#--------------------------------------------------------------------
  alias mono_sonidocolision_gameplayer_initialize  initialize
  def initialize
    mono_sonidocolision_gameplayer_initialize
    @timer_del_SE = 0
  end
#--------------------------------------------------------------------
#------------------------- MOVIBLE -------------------------------
#--------------------------------------------------------------------  
  alias mono_sonidocolision_gameplayer_passable  passable?
  def passable?(x, y, d)
    passable = mono_sonidocolision_gameplayer_passable( x, y, d)
    if passable == false
      RPG::SE.new("Bite", 80, 100).play
      @timer_del_SE = 60
    end
    return passable
  end

end 

ahora que tenemos esto tenemos que asegurarnos de que el timer este en 0 para reproducir el sonido, ya que si no es 0, reproducira una y otra vez y otra vez  y no que parta el sonido desde 0, entonces en el if le pondremos que passable == false && @timer_del_SE == 0, para que se escuche el sonido.

 Bien ahora tenemos que el timer parte de 0, pero nunca volvera a 0 una vez que lo hagamos, porque no se borra solo, o sea de 0 pasa a 60, pero luego no vuelve a 0, sino que se queda en 60 todo el rato D:>  

 No se preocupen, ahora usaremos el metodo update, que se encargará de que le reste 1 al timer por cada frame del juego hasta que llegue a 0 nuevamente. Para esto buscaremos, nuevamente del script Game_Player , el metodo update, que es este de aca:

  def update
    last_real_x = @real_x
    last_real_y = @real_y
    last_moving = moving?
    move_by_input
    super
    update_scroll(last_real_x, last_real_y)
    update_vehicle
    update_nonmoving(last_moving) unless moving?
    @followers.update
  end

y lo pegaremos despues del initalize... le pondremos un alias nuevamente y borramos lo que tiene adentro y llamaremos a nuestro alias, quedando algo asi:

class Game_Player < Game_Character
#--------------------------------------------------------------------
#------------------------- INITIALIZE -------------------------------
#--------------------------------------------------------------------
  alias mono_sonidocolision_gameplayer_initialize  initialize
  def initialize
    mono_sonidocolision_gameplayer_initialize
    @timer_del_SE = 0
  end
#--------------------------------------------------------------------
#------------------------- UPDATE -----------------------------------
#--------------------------------------------------------------------
  alias mono_sonidocolision_gameplayer_update  update
  def update
    mono_sonidocolision_gameplayer_update
  end
#--------------------------------------------------------------------
#------------------------- MOVIBLE ----------------------------------
#--------------------------------------------------------------------  
  alias mono_sonidocolision_gameplayer_passable  passable?
  def passable?(x, y, d)
    passable = mono_sonidocolision_gameplayer_passable( x, y, d)
    if passable == false && @timer_del_SE == 0
      RPG::SE.new("Bite", 80, 100).play
      @timer_del_SE = 60
    end
    return passable
  end

end

Luego que tenemos esto pondremos la variable de metodo y le restaremos 1 por cada frame , y luego de este un unless que le dira al programa que no siga restando si la variable ya es igual a 0, quedando asi:

@timer_del_SE -= 1 unless @timer_del_SE == 0

 para que finalmente nuestro script quede de esta manera:

class Game_Player < Game_Character
#--------------------------------------------------------------------
#------------------------- INITIALIZE -------------------------------
#--------------------------------------------------------------------
  alias mono_sonidocolision_gameplayer_initialize  initialize
  def initialize
    mono_sonidocolision_gameplayer_initialize
    @timer_del_SE = 0
  end
#--------------------------------------------------------------------
#------------------------- UPDATE -----------------------------------
#--------------------------------------------------------------------
  alias mono_sonidocolision_gameplayer_update  update
  def update
    mono_sonidocolision_gameplayer_update
    @timer_del_SE -= 1 unless @timer_del_SE == 0
  end
#--------------------------------------------------------------------
#------------------------- MOVIBLE ----------------------------------
#--------------------------------------------------------------------  
  alias mono_sonidocolision_gameplayer_passable  passable?
  def passable?(x, y, d)
    passable = mono_sonidocolision_gameplayer_passable( x, y, d)
    if passable == false && @timer_del_SE == 0
      RPG::SE.new("Bite", 80, 100).play
      @timer_del_SE = 60
    end
    return passable
  end

end

 VENGA QUE HAY QUE PROBAR EL SCRIPT!!! CHAN CHAN CHAN :DDD, FELICITACIONES!!! TU PRIMER SCRIPT DEL JUEGO YA ESTA FUNCIONANDO!!! *aplausos*

 no queda más que felicitarte por leer todo esto jajaja, que igual es bastante, pero quedan las palabras claves muchisimas mas claras y ahi si que cumplen su funcion a la perfeccion, pero..... lamento arruinarte el momento feliz, pero es que hay algo importantisimo que todos los scripts deben tener.

 Que pasaria si yo estoy haciendo un juego y lo llevo muy avanzado y se me ocurre hacer un script para mejorarlo, y luego me meto en un juego guardado y veo el script, ooooooh ******* error!!!!!!! D:< 

 Para esto es que siempre los scripts deben asegurarse que sucede en caso de que antes no habia nada, por ejemplo en nuestro script, si guardamos y colocamos nuestro script despues, el juego guardado ya inicio con todos los initialize de los script y el de nosotros es uno nuevo, como intentara recuperarlo no encontrara nuestra variable de metodo y le restará - 1 cada frames a algo que no existe, entonces pensará, pero que ***** hago si no encuentro esto, entonces te aplaudirá frente a ti diciendo, que se te olvido arreglar eso...

 para eso es que nuestro script tenemos que editarlo para que se pueda utilizar en juegos ya guardados, se puede hacer una manera que es la más obvia, que seria sacar la variable de metodo del initialize y ponerla simplemente en el update y nos ahorramos el trabajo de generar algun problema, pues bien, haremos eso...

 Sacaremos esa variable y la pondremos en el metodo update y colocaremos el unless para que genere la variable si no estaba antes, con un nil (vacio).

@timer_del_SE = 0 unless @timer_del_SE != nil

 Como el initialize no tiene nada lo borramos, quedando asi:

class Game_Player < Game_Character
#--------------------------------------------------------------------
#------------------------- UPDATE -----------------------------------
#--------------------------------------------------------------------
  alias mono_sonidocolision_gameplayer_update  update
  def update
    mono_sonidocolision_gameplayer_update
    @timer_del_SE = 0 unless @timer_del_SE != nil
    @timer_del_SE -= 1 unless @timer_del_SE == 0
  end
#--------------------------------------------------------------------
#------------------------- MOVIBLE ----------------------------------
#--------------------------------------------------------------------  
  alias mono_sonidocolision_gameplayer_passable  passable?
  def passable?(x, y, d)
    passable = mono_sonidocolision_gameplayer_passable( x, y, d)
    if passable == false && @timer_del_SE == 0
      RPG::SE.new("Bite", 80, 100).play
      @timer_del_SE = 60
    end
    return passable
  end

end

Listo ahora si el script esta perfecto y no deberia tener ningun problema para utilizarlo :))

 hay cosas que los demas scripters hacen y es lo mejor, es que se pueden editar algunas cosas del script y le colocan un mensaje diciendo, aca puedes cambiar el fondo, el volumen, los personajes, el id del battler, etc.
 Lo hacen, haciendo que esos datos sean constantes (que no varian en el script), en nuestro script de sonido hay cosas que son constantes, por ejemplo la musica y los 60 frames al que llega el timer, podemos colocar estos datos como constantes, simplemente colocando antes que todo y despues de la class un nombre y el valor que cambiará (logicamente los valores constantes tendriamos que reemplazarlos con esos nombres)

 mostraré aca como cambie los valores del cambio de musica y del timer:

class Game_Player < Game_Character

  #------------ CAMBIO DE SONIDO -------------------
  Camb_sonido = [ "Bite" , 80, 100] # aca se cambia el sonido, el volumen, intensidad
  Tiempo_timer= 60                # duracion de espera del sonido
  
#--------------------------------------------------------------------
#------------------------- UPDATE -----------------------------------
#--------------------------------------------------------------------
  alias mono_sonidocolision_gameplayer_update  update
  def update
    mono_sonidocolision_gameplayer_update
    @timer_del_SE = 0 unless @timer_del_SE != nil
    @timer_del_SE -= 1 unless @timer_del_SE == 0
  end
#--------------------------------------------------------------------
#------------------------- MOVIBLE ----------------------------------
#--------------------------------------------------------------------  
  alias mono_sonidocolision_gameplayer_passable  passable?
  def passable?(x, y, d)
    passable = mono_sonidocolision_gameplayer_passable( x, y, d)
    if passable == false && @timer_del_SE == 0
      RPG::SE.new(*Camb_sonido).play
      @timer_del_SE = Tiempo_timer
    end
    return passable
  end

end

 Pues bien, este tutorial nos sirvio más que nada para ver como se utilizan bien las cosas y aprender a editar cosas de los scripts, espero que les sirva, haber si pueden hacer algo mas y nos estaremos viendo para algunos conceptos nuevos y el anexo II para la musica, por lo demás....



No hay comentarios:

Publicar un comentario