› Foros › Multiplataforma › Desarrollo
realbrucest escribió:Buenas a todos. Hace un par de meses empecé a conversionar el juego Dynamite Dan a Megadrive usando para ello las librerías SGDK. El compi jordigahan en la logística y ripeando como un cosaco y yo dándole forma un código, un tanto deleznable pero hasta donde llegué relativamente funcional. Mes y pico con tiempo y ganas, luego mes y pico de mucho menos tiempo para ponerme con ello y de ganas así así, además de que por querer actualizarme a la última versión del SGDK me dejó de compilar.
Describo el proceso del bicho:
Librerías y entorno de desarrollo
SGDK y Code:blocks.
Tuto en la web de sgdk para configuarlo.
Básicamente no es más que descargar las librerías y guardarlas en una ruta corta sin espacios (la mía es D:\Bru\sgdk).
Creas dos variables de entorno que hagan referencia a la ruta de las librerías tal como indica el tuto
Y en el Code:blocks configurar un nuevo compilador que será el que usemos con nuestros proyectos para megadrive. En el tuto detallado.
Para saber si todo está bien configurado, o tiramos del clásico Hello World:#include <genesis.h>
int main()
{
VDP_drawText("Hello World!", 10, 13);
return (0);
}
O compilamos alguno de los ejemplos incluidos.
Los gráficos
Imagenesis y algo de PaintshopPRO para corregir paletas.
Jordigahan ha conseguido extraer todos los fondos y sprites del juego original de spectrum.
Empiezo con los fondos.
Se toma el imagenesis, se carga el bitmap correspondiente al fondo y tras indicar un parámetro relativo a cómo queremos generar el mapa de tiles y el tileset, "click and play". El imagenesis no exporta correctamente los gráficos de los tiles si se le requiere que lo haga en formato C, para ello me creé un programita que tomándolo en formato BASIC lo convertía como se requiere.
Los sprites son un poco más coñazo porque ahí sí que no me aclaraba con el imagenesis y me estuve dedicando a recolocar tile a tile el gráfico para que cuando se lo pasase me saliera como me interesaba. En todo caso están la mayoría ya integrados en el código. Aunque lo suyo sería encontrar la manera cómoda y buena de hacerlo pensando en que esto sirva para sacar adelante un remake o plataformas con gráficos más curradetes.
De sonido
nanai del la China por el momento. Los sonidos en wav sí que están ripeados a la espera de poder meterle mano.
Estado del juego / POR HACER
- Terminar de implementar las plataformas móviles
- Implementar los ítems que ofrecen ventajas como inmunidad o te permite caer al agua sin perder todas las vidas.
- Implementar la animación final cuando se escapa con el objetivo cumplido
- Menús de opciones
- Sonido
- Testear a saco y corregir, tanto interacción con ciertas pantallas como la rutina de salto y colisión.
- Ajustar paletas de colores
Estado último (versión alpha) (el binario de megaupload, no la imagen enrejillada ):
http://www.megaupload.com/?d=VTFZHJ4A
- Implementadas las cuarenta y ocho pantallas (8 horizontales por 6 verticales). Algunas han de ser corregidas.
- La mayor parte de los enemigos se encuentran disponibles en el código aunque sólo algunos se han colocado en esta versión con el propósito de realizar pruebas de colisiones.
- El salto y las colisiones necesitan mejorarse.
- Teletransportadores y rayos funcionales aunque han de recolocarse y redefinir la longitud
- El elevador quedó a medio programar como se puede ver, falta corregirlo y programar la balsa de las pantallas inferiores, otra plataforma móvil.
La "des"ordenación del código:
Último estado del código (no compila tal cual debido a los conflictos con las últimas librerías)
main.c contiene el bucle principal del juego, las llamadas a todas las librerías y otros archivos de código dedicados a tareas específicas.
macros.h básicamente macros para aclarar-castellanizar el código.
Ejemplo (fragmento)//Estados del pad de control ...............................
#define PULSAR(x) (state & (x))
#define SOLTAR(x) (changed & (x))
//Constantes aplicalbles al protagonista ...................
#define PLAYERWIDTH 16
#define PLAYERHEIGHT 24
#define PLAYERSPEED 256
enemy.h funciones que inicializan los enemigos y que se encargan de gestionar su movimiento. En el estado actual del código, los enemigos de la pantalla se inicializan-cargan de la siguiente manera://Enemigos de la pantalla ....................................................
enemigo_pato00( 4,12, SPEED2, 4, PALETA_SPRITES1, NUEVO);
enemigo_pato00(12,10, SPEED2, 4, PALETA_SPRITES2, COPIA);
enemigo_pato00(20, 4, SPEED2, 4, PALETA_SPRITES3, COPIA);
enemigo_pato00(20,10, SPEED2, 4, PALETA_SPRITES1, COPIA);
enemigo_pato00(20, 8, SPEED2, 4, PALETA_BASICA, COPIA);
enemigo_cucara(20,16, SPEED2, 4, PALETA_SPRITES3, NUEVO);
enemigo_bicefa(25, 8, SPEED2, 4, PALETA_SPRITES1, NUEVO);
enemigo_balon0( 8, 8, SPEED2, 4, PALETA_SPRITES2, NUEVO);
nomasEnemigos();
Los primeros dos parámetros corresponden a las coordenadas en tiles (a una resolución de 32 horizontales por 16 verticales -los 4 inferiores corresponden a la barra de estado-). Luego la velocidad de movimiento del enemigo, un rango de tiles a partir del cual invertirá su dirección, la paleta -a elegir entre cuatro-, y si ha de copiarse el gráfico a la memoria de vídeo -"NUEVO"- o si ya se encuentra -"COPIA"-.
items.h (sin efecto actual) aquí debe de incluirse el código encargado de distribuir aleatoriamente los ítems por el escenario en cada partida. Tenía pensado almacenar dos o tres posiciones posibles donde pueden aparecer, pero no lo llegué a tener decidido del todo.
map.h contiene las funciones dedicadas a los elementos interactivos del mapa. Funciones de inicialización y actualización-movimiento de los rayos, teletransportadores y plataformas móviles, así como las de carga -en el array de ámbito global mapa[]- y dibujo del escenario.
player.h funciones de inicialización y movimiento del jugador (controles al margen, la gestión del joystick está en main.c). Aquí se encuentran las funciones encargadas de gestionar las colisiones, una de ellas es la especial que se encarga de variar el valor que indica la pantalla activa según por qué parte de la pantalla haya salido el protagonista (la variable global id_pantalla).
tile.h funciones genéricas para detectar colisiones con los tiles (siempre en relación a las coordenadas del personaje). Las funciones de colisión de player.h hacen uso de éstas.
tilemap.h funciones de carga de las distintas pantallas, así como de los enemigos que corresponden a éstas (eso quedó a medio hacer). Básicamente lo que hacen todas es rellenar el array mapa[] con los nuevos valores correspondientes a la pantalla que se va a inicializar, además de cargar enemigos. Seguro segurísimo que había una forma más elegante de hacerlo pero como aficionadete malo que soy no se me ocurrió.
tileset.h por cada pantalla creé una función encargada de mandar a la VRAM los tiles que necesita. Aparte tengo void tilesetGeneral(void) la cual deja de forma permanente en la memoria de vídeo los tiles más comunes para aligerar carga. Es una forma chusquera de hacerlo pero al ser tan simple los gráficos podía permitirme falta de eficiencia mientras iba aprendiendo sobre la marcha.
Y por aquí lo dejo de momento. Echadle un ojo aunque sea al binario (la alpha del juego) y ya me contáis.
Saludos y ¡viva el homebrew!