Registrarse

[Essentials] Vídeos/Cinemáticas en Pokemon Essentials

Pableroski

Novato - Rpg en desarrollo
En esta guía explico cómo poder "reproducir" vídeos en Pokemon Essentials. (Probado en v16.2 - Creo que es compatible otras versiones)

Hace poco me encontré con el script "Scene_Movie" que viene en el Essentials, que en teoría permitía reproducir vídeos. No logré que funcionara, y por más que investigué no encontré solución. Viendo en versiones posteriores, vi que eliminaron el script así que supongo, era inutilizable.

Entonces decidí hacerlo por mi cuenta. A grandes rasgos, se trata de poner en la pantalla, fotograma a fotograma, las imágenes del vídeo, y a la vez que vaya sonando la música por separado. Esto plantea varios problemas, como que se descuadre y el sonido vaya por delante de la imagen, ya que el ordenador no tarda lo mismo en hacer las operaciones. Siempre hay una pequeña diferencia de tiempo que termina atrasando al fotograma. Ese problema está solucionado con un pequeño script.

Tiene ciertos inconvenientes, como que el peso de tu carpeta aumente (aunque el tamaño del game.exe apenas cambie). También, si intentas reproducir vídeos demasiado largos, al tener que buscar entre tantos archivos el juego se ralentizará. Por eso, aunque podrías reproducir vídeos de cualquier duración (a continuación dejo enlace a uno de 6:20 min que corre perfectamente), recomiendo usarlo para pequeñas cinemáticas. Puede ser la medalla colocándose en el estuche al estilo blanco y negro, la entrada a una zona determinada, e incluso he pensado en tener una verdadera intro del juego.

Divido el mini tutorial en 3 partes: la preparación de los fotogramas, la creación del evento y la explicación del script

Dejo el enlace al vídeo de muestra. Todo son escenas ingame: https://drive.google.com/file/d/1cN5-fdCgMdnQZNw0E2CAyl9H5_fz-Rra/view?usp=sharing


PREPARACIÓN DE FOTOGRAMAS
Esto puede resultar muy sencillo o muy tedioso. Dos cosas en cuenta: duración y dimensiones del vídeo, así como la cantidad de fotogramas.

DIMENSIONES: 512x384. Esa es la dimensión de la pantalla, y si no queréis que solo se vea un cuarto de imagen, hay que poner todos los fotogramas con ese tamaño. También está la opción de cambiar el zoom de la imagen en el mismo evento, pero yo prefiero hacerlo todo a la vez.

DURACIÓN: Esto es muy importante. Recordemos que el audio y la imagen van por separado. El Essentials necesita una pausa mínima de un frame (1/20 segundo) para mostrar una imagen. En otras palabras, el vídeo debe estar a 20 fps (fotogramas por segundo). Eso según la teoría, pero de nada sirve grabar un vídeo a 20 fps. Por lo general, cuando extraigas los fotogramas, tendrás más que lo que dura el sonido.

CANTIDAD DE FOTOGRAMAS: Por las limitaciones del Essentials, un fotograma= un frame. 20 frames= 1 segundo.
Cuando extraigas los fotogramas, tendrás que eliminar algunos (muchos) de ellos, más cuanto mayor sea la duración del vídeo.
El objetivo es que te queden tantos fotogramas como frames dure el sonido. Si os preocupa que el vídeo vaya dando saltos, tranquilos, el ojo humano a partir de 12 fps no distingue imágenes, sino movimiento.

Ejemplo: Tengo un vídeo de 38 segundos, y al extraer todos los fotogramas me salen 952 fotogramas (952 frames). Como dura 38 segundos (760 frames), me sobran 192 frames (192 fotogramas). La mejor manera de eliminarlos sin afectar a la fluidez del vídeo es ver cuántas veces hay 192 fotogramas en 952 (952/192=4,958...). Significa que debo quitar un fotograma cada 5 que me encuentre.
Esta parte es la más tediosa. Hacerlo a mano es una tortura. Con mis conocimientos de programación en C me hice un par de programas para hacer esto. Si alguien está interesado se los paso.

Una vez tengas los fotogramas necesarios (cuanto más exacto sea el número, mayor sensación de fluidez), queda renombrarlos. Por lo general, los programas que extraen fotogramas suelen añadir el número del orden en el que van. Pero al reducir fotogramas, hay huecos entre ellos. A lo mejor salta del 4 al 6 y cosas así. Tienes que volver a renombrarlos. Si estás en windows, selecciona todos los archivos (CTRL + E) y dale a cambiar nombre. Pon el nombre que quieras y te renombrará todos, con el número de fotograma entre paréntesis. Eso es lo que vamos buscando.

Ya solo queda extraer el audio del vídeo (cualquier programa de edición te hace esto, e incluso páginas online). Si no recuerdo mal, Essentials permite mp3, wav y ogg.

Para terminar este apartado, guardarlo todo en la carpeta correspondiente. Las imágenes dentro de la carpeta \\Graphics\\Pictures (dentro de esta carpeta podéis guardarla en una nueva carpeta si queréis, para no mezclarlas con las demás). El audio en cualquiera de las subcarpetas que tenga. Yo lo trato como un SE (sound effect) y todas las explicaciones están basadas en eso, pero intuyo que puedes ponerlo en cualquiera siempre que indiques correctamente dónde está.


CREACIÓN DEL EVENTO
Nos metemos ya en el Essentials.

Tutorial evento.PNG


Variables necesarias: 107 (controlará los fotogramas); 108 (hora de inicio de reproducción); 109 (hora de última llamada a script);

El número de las variables obviamente podéis cambiarlos, pero tendréis que cambiar el número que usa el script (3er apartado).

El evento puedes configurarlo de dos maneras: La primera, que no te importe que se te descuadre la imagen con el sonido, o que sea una cinemática muda. Si ese es el caso, puedes saltarte los tres párrafos siguientes, así como el script, pues no lo necesitas. Debes borrar todo lo que ponga "Time.now", y quedarte algo así:
1642252814548.png


-Si quieres corregir el desajuste:

inicio variables.PNG

Comenzamos poniendo las variables en orden. La variable 108 guarda el tiempo en el que se inicia la reproducción. La 109 en este momento también, pero solo para que no haya fallos cuando entre en el condicional. A continuación, comienzas a reproducir el sonido


ciclo pequeño.PNG

Cuando la cinemática es pequeña, el vídeo y el audio no suelen desajustarse demasiado, no es perceptible a simple vista al menos. Sin embargo, pienso que es mejor ponerlo siempre. Permite refrescar el fotograma. Si el ordenador se te atrasa, sea porque el sonido va demasiado rápido, sea porque se queda colgado unos segundos, terminará actualizándose al fotograma correcto. También soluciona el problema de pinchar fuera de la ventana o de minimizarla y que la imagen se congele mientras el sonido sigue. Cuando vuelvas a pinchar dentro de la ventana, se actualizará

Entra en ese condicionante si la diferencia entre el tiempo actual y la última llamada a la función "pbAutoregulador" es >=5. Este parámetro lo puedes cambiar. Cuanto más bajo sea el número, más rápido llamará a la función de refresco y se actualizará cada menos tiempo. Yo lo he dejado en 5 segundos, es un número que no suele darme problemas. Ahora bien, ¿cómo sabe la variable 109 la hora de la última llamada a la función? Esto lo explico más adelante, pero se actualiza en el mismo script.
Si puede entrar en el condicionante, llama a la función y devuelve el fotograma en el que debería estar.

-Igual ya para todos:

1642253251249.png


Lo siguiente es llamar a la imagen, esperar el tiempo adecuado, y borrarla. Yo la tengo puesta como imagen 12 por gusto, puede ser cualquiera, siempre que utilicéis el mismo número tanto para llamarla como para borrarla.

Para que fuera más sencillo el indicar la imagen mediante script, tuve que cambiar una cosa del código. En el editor de scripts, vais a "Game_Picture", y donde ponga "attr_reader :name" , lo cambiáis por "attr_accessor :name"

1642253512679.png


Siguiendo con la imagen anterior, tenemos el script:

name = '\\Videos\\BT\\AvsP\\IvsE (' +
pbGet(107).to_s+')'

$game_screen.pictures[12].show(name, 0,
0, 0, 100, 100, 255, 0)

name tendrá la ruta, así como el nombre del archivo. En mi caso, tengo los fotogramas en una carpeta llamada AvsP , que está dentro de otra carpeta llamada BT, que a su vez está dentro de Videos, que está en Pictures. Podéis meter las imágenes directamente en Pictures y solo tendríais que poner name= 'nombre_archivo_sin_extension (' + pbGet(107).to_s+')' Es importante que no os olvidéis las comillas simples.

Lo que está entre comillas simples ' ' es el nombre del archivo. Para que el bucle funcione correctamente, la variable de los fotogramas (107 en mi caso) irá dando un número distinto a la vez, y esa es la forma de ponerlo dentro de una variable. Para los entendidos en programación, name es un string y la variable es un entero, hay que convertirlo, de ahí el .to_s. Los "+" son simplemente para añadir más caracteres al string.

Mi archivo se llama IvsE (1). El paréntesis sale por lo que expliqué en la preparación de fotogramas al cambiarle el nombre a todos a la vez.
Si tuviéseis el archivo como IvsE 1 , sería simplemente, suponiendo que está en la misma ruta,

name = '\\Videos\\BT\\AvsP\\IvsE ' + pbGet(107).to_s

Es importante fijarse dónde ponéis las comillas simples. Entre mi E y el paréntesis hay un espacio, luego tengo que dejarlo también en el script


Ya queda $game_screen.pictures[12].show(name, 0, 0, 0, 100, 100, 255, 0), que viene siendo el "mostrar imagen" de la pantalla de comandos.

Entre corchetes va el número de la imagen (OJO: No el del fotograma). Aquí podéis poner el número que os de la gana, siempre que al borrar imagen le pongáis el mismo número, o de lo contrario no se borrará y fallará.

Name se deja tal cual, "name", con minúsculas, porque es lo que hemos declarado antes. Eso, cuando se ejecute, será remplazado por el nombre del archivo y con su ruta en caso de estar en una subcarpeta de Pictures.

El primer 0 es si lo quieres "arriba-izquierda" (0) o centrado (1). Pienso que es mejor dejarlo en 0

El segundo y tercer 0, son "x" e "y", respectivamente. Con eso ya jugáis vosotros, según dónde queréis que salga. Yo lo dejo en 0,0.

Los dos 100 a continuación son el zoom de la imagen, tanto en ancho como en alto, en %. Por defecto está en 100, si queréis una imagen más pequeña, que el número sea <100; si la queréis más grande, >100. En mi caso, redimensioné los fotogramas al principio para adaptarlos a las dimensiones de la pantalla. Si os saltásteis ese paso, tendréis que ajustarlo aquí manualmente con el zoom.

El 255 es la opacidad de la imagen

Y el último 0 es la paleta. Dejad esta siempre en 0.


Después del script viene "esperar 1 frame". Esto es necesario. La velocidad del Essentials es un arma de doble filo, aquí es tan rápido que no ves las imágenes. Aviso: si os saltáis la espera de un frame por cada imagen, no saldrá nada en la pantalla.

Finalmente, borrar imagen, para que no se quede en la pantalla.

1642254930042.png


Para terminar este apartado, el condicional que nos saca del ciclo una vez hayamos terminado los fotogramas. En mi caso son 7618, cambiad ese número según los vuestros. Si se da el caso, entramos y rompe ciclo, terminando con la reproducción.

Después de ese condicional, sumamos +1 a la variable de los fotogramas, para que muestre el siguiente. Y llega al fin del ciclo grande, y todo el proceso se repetirá. Así se logra pasar por todos los fotogramas uno a uno, sin necesidad de poner un "mostrar imagen" por fotograma, como tuve que hacer al principio. También podría hacerse así, pero puedo aseguraros que no es agradable, además de que perderéis una cantidad muy considerable de tiempo y esfuerzo.


EXPLICACIÓN DEL SCRIPT
Lo primero de todo, decir que mis conocimientos de programación son de C, no he dado POO, así que el ruby se me viene grande en algunas cosas. Quizás haya una forma más simple de programarlo, o una más óptima. Si alguien encuentra una manera más eficaz de actualizar el fotograma lo actualizaré

"
def pbAutoregulador()

hora_inicio=$game_variables[108]

hora_actual=Time.now

diferencia=(hora_actual-hora_inicio)*20 #20 frames corresponde a 1 seg

#Redondeo

diferencia_entera= diferencia.to_i

diferencia_entera=diferencia_entera.to_f

if diferencia-diferencia_entera>=0.5
diferencia_entera=diferencia_entera+1
end

$game_variables[107]=diferencia_entera.to_int

$game_variables[109]=Time.now

return $game_variables[107]
end

"

Es un script sencillo. Mira la diferencia entre la hora actual y la del inicio de reproducción (variable 108). Dicha diferencia la multiplica por 20, los frames por segundo que hay, para así tener el fotograma al que debería ir la reproducción.

Problema: el tiempo es un flotante, y el fotograma es un entero. Tuve que buscar una forma de pasarlo a entero de manera que se perdiera la menor información posible, o de lo contrario el salto entre fotogramas sería mayor. Esta es la parte a la que me refiero que es mejorable. Todavía pierdo unos pocos decimales, aunque no es gran cosa y apenas se distingue la diferencia.

Cuando acaba el redondeo, convierte a entero la variable de fotogramas y le da a la variable de la última llamada la hora actual.



Y eso es todo. Dejo enlace al script por si alguien quiere descargarlo, aunque simplemente puede copiar y pegar. Como siempre, colocar encima del main. https://www.mediafire.com/file/baoyam4nxzw8wkt/pbAutorregulador.txt/file

Un saludo.


CRÉDITOS
Fiel a mis principios, no necesito ningún crédito si alguien llegara a implementar esto en su proyecto. Lo importante es que te sea útil y ayude a mejorar el producto final
 
Última edición:
Arriba