Programación del Amstrad CPC usando la libreria 8BP ("8 bits de poder") desde BASIC
"Las limitaciones no son un problema, sino una fuente de inspiración"
Jose Javier Garcia Aranda
If you like 8BP, your help is welcome. Help me supporting this initiative (from 1€, whatever you want). Donations will be used for materials and 8BP disemination:
Ya tenéis disponible la versión V43 de la librería 8BP, descargable en github https://github.com/jjaranda13/8BP . Esta nueva versión incorpora varias funcionalidades nuevas y una nueva opción de ensamblaje. Además, en la opción de ensamblaje "cero" te da un poco mas de memoria libre.
Esta nueva versión supone una mejora y en parte es gracias a vosotros que me escribís con preguntas, dudas, ideas, etc.
las novedades son:
soporte de doble clipping horizontal: esta funcionalidad es interesante para implementar juegos con scroll estilo ghost n goblins. Estoy trabajando en ello para poder hacer una demostración.
nuevo flag y funcionalidad de borrado. Se activa con PRINTSP,33,1 y se desactiva con PRINTSP,33,0. Con el flag activo tanto PRINTSP como PRINTSPALL borran los sprites. Este mecanismo funciona también con sprites que tienen sobreescritura. Esta funcionalidad me la han pedido desarrolladores de juegos y se ha podido incorporar sin apenas gastar memoria.
nuevo modo de ensamblaje ASSEMBLING_OPTION = 4 que permite prescindir de layout y scroll, y que te deja 25300 bytes para tu codigo y 500 bytes mas para tus sprites
mas memoria disponible en el modo de ensamblaje cero. Antes eran 23500 y ahora son 23600 bytes
corregido bug en ANIMASP
dos nuevas demos: una de doble clipping y otra de flag de borrado
Estos son los 4 modos de ensamblaje disponibles en 8BP V43
El manual ha sido actualizado con todas estas cuestiones y ahora hay una versión del manual "V43". Las traducciones a otros idiomas se han quedado desactualizadas en "V42", pero es lo único que quedaría por actualizar.
Quiero dar las gracias en especial a "fito", por que me ha ayudado a estas mejoras con sus ideas
Espero que la disfrutéis y aprovecho para desearos un feliz verano!
Ya tenéis disponible la versión V42 de la libreria 8BP, descargable en github https://github.com/jjaranda13/8BP . Esta nueva versión incorpora varias funcionalidades nuevas pero ademas te deja mas memoria libre gracias a "opciones de ensamblaje". Un simple numero con el que especificas la opción y así no "malgastas" memoria en comandos de scroll si tu juego es de laberintos o viceversa.
Los cambios y mejoras han sido inspirados por vosotros, por programadores que me hacen consultas, me sugieren ideas y echan en falta cosas que poco a poco se han ido incorporando. Gracias a los que como Toni o Fito, me han sugerido ideas y me han ayudado con sus preguntas a comprender donde debía explicar un poco mas en el manual ciertos detalles.
librería: se han incorporado las siguientes funcionalidades:
"opciones de ensamblaje": con las que 8BP ahora te deja 1.5KB para música y hasta 25KB libres para tu listado. Ahora la librería 8BP dispone de varias opciones de ensamblaje que te permiten elegir las capacidades que deseas para tu juego y así dispones de más memoria disponible para el listado de tu juego. La opción de ensamblaje la debes especificar en el fichero Make_all_mygame.asm , el cual tiene una línea específica para asignar el valor del parámetro “ASSEMBLING_OPTION”. con la opcion para juegos de laberintos (1) tienes 25KB libres, con la de scroll (2) tienes 24.8 KB libres y con la pseudo3D (3) tienes 24 KB libres
1.5KB libres para música (antes eran 1.4 KB). El mapa de memoria ha cambiado ligeramente
imágenes de fondo: permite scroll sin parpadeos en objetos que pasan por debajo de tus sprites
secuencias de animación encadenadas: esto permite hacer secuencias de animación de cualquier numero de frames
manual: incorpora las siguientes mejoras:
explicación de las opciones de ensamblaje
nuevo mapa de memoria
explicación de las imágenes de fondo
explicación de las secuencias de animación encadenadas
revisión completa del manual con muchas mejoras en todos los capítulos
las demos han sido actualizadas para usar 8BP V42 y se ha añadido la demo 15, que muestra la utilidad de las imágenes de fondo en juegos con scroll
Espero que os guste y os ayude a programar vuestros juegos aun mejor
ya tenéis disponible la versión V38 de la libreria 8BP, descargable en github https://github.com/jjaranda13/8BP . Esta nueva versión incorpora las siguientes mejoras:
- detección de colisiones perfeccionada, sin limitaciones por coordenadas negativas
- comando MUSIC mejorado: ahora puedes decidir entra hacer sonar una musica en bucle o hacerla sonar una sola vez.
- el comando MUSICOFF ha sido reemplazado por MUSIC invocado sin parametros
- manual mejorado con capitulo de primeros pasos y diversas pequeñas mejoras
- la librería ocupa exactamente igual que antes (8KB) , dejándote 24 KB para tu lógica BASIC, 8.5 KB para gráficos y 1.4 KB para música
Estos son los primeros pasos con la librería 8BP. Te dejo con un vídeo explicativo y los mismos pasos por escrito, que ademas los tienes en el manual de 8BP que viene con la librería.
Lo primero que debes hacer es instalarte la última versión
de Winape, que es un emulador y a la
vez editor y ensamblador de Amstrad. Lo puedes descargar desde www.winape.net
Una vez instalado el Winape, familiarízate un poco con el,
probando algun juego de Amstrad y probando a cambiar la configuración. Trata de
abrir el assembler que lleva incorporado en el menú y edita un “hola mundo” en
la ventana de ensamblador. A continuación, copia y pega el texto en la ventana
de emulación. Veras como se pega carácter a caracter
Si haces un programa mas largo, para copiarlo en la ventana
de emulación es muy interesante la opción settings->high speed. Verás como
se copia rapidísimo.
Ahora vamos a hacer una primera toma de contacto con 8BP
viendo algunas demos. Entra en el directorio Demos. En el encontraras una serie
de subcarpetas : ASM, BASIC, DSK, MUSIC
Entra en DSK . Alli veras un fichero .dsk con las demos. Desde
winape ve al menú File->drive A-> insert Disc image y selecciona el
archivo de las demos
Una vez seleccionado, desde la ventana de emulación del
Amstrad escribe CAT para ver los archivos
Cada fichero .BAS es una demo donde podrás ver alguna de las
características de 8BP (no todas sus posibilidades se pueden ver con las demos
pero hay algunas representativas).
Ejecuta el comando RUN “LOADER.BAS”. Obtendrás el siguiente
menú:
Ya puedes elegir una demo y probarla. A disfrutar. En el
siguiente y ultimo paso empezaremos la creación de un juego
Hemos probado un fichero .dsk que contiene muchas demos, con
graficos y música. En el directorio Demos/ASM y en el Demos/MUSIC se encuentran
los graficos y la música de las demos que has probado. Sin embargo, si quieres
hacer tu propio juego o demo, es mejor que empieces con unos ficheros “limpios”
sin todos los graficos que requieren las demos que has probado.
Nos vamos al directorio raíz. Alli encontraras una carpeta
llamada 8BP_V38. Yo te recomiendo que hagas una copia de esta carpeta y la
renombres como “mi_juego”. De ese modo preservarás la carpeta 8BP_V38 original
aunque empieces a cambiar cosas
Dentro de la carpeta 8BP_V38 encontraras las carpetas ASM,
BASIC, DSK, MUSIC, TAPE, y output_spedit
Desde la ventana de ensamblador de winape abre el archivo
“ASM/make_all_mygame.asm” y
ejecútalo (simplemente en el menú de winape z80 assembler seleccionas Assemble
o pulsas Ctrl+F9). Esto comenzara a ensamblar (copiar en memoria) la librería y
los graficos en la memoria del Amstrad. En este caso vamos a ensamblar muy
pocos graficos, tan solo los indispensables para un pequeño juego. Los gráficos
se encuentran en images_mygame.asm
Tras ensamblar todo, obtendrás un mensaje como el que se
muestra a continuación:
Pulsas “ok” y desde la ventana de ensamblador vamos a abrir
otro archivo. En este caso vamos a abrir un fichero BASIC, concretamente
“tu_primer_juego.bas” que se encuentra en la carpeta BASIC. Tras abrirlo veras
el siguiente listado en pantalla, que contiene 32 lineas:
Selecciona todo y cópialo. Luego ve a la ventana de
emulación del CPC y pégalo usando el menú FILE->paste
Como el listado es algo mas largo que el “hola mundo”, usa settings->high speed para copiarlo y
luego vuelve al “normal speed”
Como ya esta ensamblada la librería y los gráficos, puedes
hacer RUN y el juego se ejecutará. Debes esquivar unas bolas que caen del cielo
para no morir, moviéndote a derecha e izquierda
Puedes probar a modificar el programa y ver sus efectos.
Poco a poco iras aprendiendo 8BP y podrás hacer modificaciones interesantes
tales como cambiar la frecuencia con la que salen bolas enemigas o su velocidad,
o reemplazar al soldado por una nave espacial y a las bolas por naves enemigas
con diversas trayectorias.
Por último, vamos a crear un disco con tu juego. Para ello,
tras tener el juego funcionanod debes dar estos pasos
·Crea un disco nuevo mediante winape: FILE->
drive A-> new Blanc Disc
·Formatealo:
FILE->drive A->Format Disc Image
·Tras haber creado tu fichero dsk , desde la
ventana de emulación ejecuta los siguientes comandos:
SAVE
“8BP.bin”, b, 24000,18620
SAVE
“juego.bas”
Ya casi hemos terminado. Ahora debes seleccionar otro disco
desde el menú de winape o salir de winape para que el .dsk que has creado se
haga realidad en el sistema de ficheros de windows.
Asi es, 8BP estuvo en la RUN"" AUA, como no podía ser de otro modo. Hubo un gran despliegue de maquinas y buena gente con la que compartimos aficiones y un gran intercambio de información, ideas y pasión por los 8 bits
El lugar del evento estuvo muy bien escogido: espacioso y acogedor, con sala de exposiciones y sala de conferencias. Enhorabuena a los organizadores de AUA. Os estamos muy agradecidos.
El stand de 8BP incluyó una maquina arcade con un emulador de Amstrad donde toda la familia, grandes y pequeños pudieron disfrutar de los juegos de 8BP, incluido el extraordinario "ERIDU", que ya podéis descargar desde https://github.com/jjaranda13/8BP . También llevamos un CPC 464 con el nuevo sistema DES y el cartucho de 8BP con todos los juegos disponibles. Y por supuesto folletos, información, el fabuloso póster de SPACE PHANTOM y la preview del nuevo "Happy Monty"
El stand de 8BP
Al stand acudieron público de todas las edades y fue un excelente momento para unir a toda la familia en torno a un concepto universal: el videojuego. Vivimos juntos momentos de acción y peligro, de aventuras y dificultades, pero siempre entrañables
Un Amstrad no puede faltar en ninguna familia
En el stand se congregaron publico de todas las edades pero como los juegos de 8BP suelen ser conceptualmente sencillos y se entienden sin dificultad, el publico infantil destacó notablemente. Especial mención he de hacer al videojuego "frogger eterno", que todo los niños pedían, aunque el juego "ERIDU" tuvo tanto o mas éxito que frogger. El juego ERIDU fue jugado una y otra vez por todos los visitantes usando la maquina arcade y su mando profesional nos proporcionaba una jugabilidad increíble.
Gran afluencia de selecto público infantil
Ademas de videojugadores, muchos informáticos y gente con conocimientos avanzados acudieron al stand y tuvimos interesantes conversaciones sobre construcción de videojuegos. La librería 8BP no deja indiferente, viendo el catálogo de juegos disponibles, era inevitable pensar el muchos posibles nuevos juegos y conversar sobre como se podrían construir. Durante la charla de 8BP pude inroducir muchos trucos y consejos que fueron devorados por los asistentes, un halago sin duda para este trabajo que con tanta pasión estamos llevando a cabo.
ilustres visitantes jugando a los juegos de 8BP
Durante la feria, algunos miembros de la AUA pudieron probar el juego "Happy Monty", aun en construcción pero que pronto vera la luz para disfrute de todos. un Juego en BASIC con 8BP que alcanza una velocidad endiablada de 25 FPS.
el nuevo juego "Happy Monty" en construcción
Una de las novedades presentadas por la AUA en la feria fue el nuevo DES con cartuchos estilo "gameboy advance" que permite crear cartuchos de bajo coste insertables en nuestro Amstrad para jugar de forma inmediata sin esperar la carga. En concreto pudimos ver el cartucho de 8BP con todos los juegos de 8BP en un menu, seleccionables y listos para disfrutar. Este formato tiene multiples ventajas, entre las que se encuentra la posibilidad de hacer juegos mas grandes, con muchas fases que no requieren esperar a cargar
El nuevo DES con el cartucho de 8BP
Junto con los amigos de AUA (https://auamstrad.es/) nos hicimos una foto de familia para recordar este gran encuentro. Todo buena gente, de lo mejor, os lo aseguro.
8BP y buenos amigos de la AUA
A la feria acudieron muchos nobles personajes de la escena y algunos buenos amigos, con los que nos inmortalizamos en una foto ( el buenazo de Javi y su mujer)
Fue un placer para mi compartir la charla de 8BP con todos los asistentes, la cual he subido al repositorio de 8BP en charla 8BP , Hubo una gran asistencia e interés, lo cual es una satisfacción para mi y me anima a seguir avanzando en esta librería 8BP, que le da vida a nuestro querido AMSTRAD
Como he anunciado por twitter, en la proxima feria de Amstrad Eterno, que tendra lugar el Sábado 30 de marzo en Barcelona. Es una gran feria, un punto de encuentro obligado para los amantes del Amtrad . En ella, 8BP tendra presencia con un stand en el que os mostraré novedades y juegos y donde podremos charlar sobre nuestro ordenador favorito.
Además, de 11:30 a 12:00 podreis aprender a programar el clasico "frogger" desarrollado por konami en 1981, pero usando 8BP. Os enseñare paso a paso como hacerlo y vereis lo facil que es programar cualquier juego con 8BP. Además, prepararé documentación detallada del juego para los asistentes, aparte de la conferencia/taller
Hablaré de las capacidades de 8BP y de la técnica de lógicas masivas pero a la vez podras comprobar como plasmar esos conceptos en un juego real, llamado "Frogger eterno", al que podrás jugar en el stand ese mismo dia. ¿te animas?
el juego frogger eterno será presentado en Amstrad Eterno 2019
Os dare mas noticias sobre esta contribución de 8BP a medida que nos acerquemos al evento. De momento os dire que tambien estarán disponibles gracias a STAR, ediciones físicas de los juegos de 8BP en dos volúmenes. Cada volumen contiene dos cintas cuidadosamente elaboradas. Las podeis adquirir en la boutique de STAR http://www.matranet.net/boutique/cpc/cpc.php
volumenes de 8BP
STAR realiza unas magnificas ediciones homebrew
En el stand podreis probar los juegos de 8BP, incluido el recientemente premiado "Space Phantom". Como sabeis es un juego de arcade 3D y si funciona rápido es gracias a la velocidad de los comandos 8BP y a la técnica de lógicas masivas de la que os contaré sus secretos. Alli estaré para el que quiera conocer los secretos de la programación de este juego.
Antes de despedirme quiero deciros que he subido una nueva versión del manual (V36_01), mejorada en algunos capitulos para explicar mejor como funciona todo, sobre todo el apartado de rutas de sprites, aunque hay mas mejoras.
Un abrazo y nos vemos en Amstrad Eterno 2019! no te lo pierdas!
Ya esta disponible la versión v27 de 8BP, en https://github.com/jjaranda13/8BP la cual sigue ocupando lo mismo, 6KB y trae dos nuevas funcionalidades (ambas están documentadas en el nuevo manual disponible en github):
Cambios de estado de un sprite forzados desde una ruta: esto nos va a permitir definir entre medias de los segmentos de una ruta, un cambio de estado. Muy útil para dar saltitos y para que por ejemplo desactivemos un disparo que ya esta fuera de la pantalla sin necesidad de controlar su posición desde BASIC
Nuevo comando RINK ("rotate Ink"): permite hacer animación por tintas
cambios de estado en rutas:
se definen con un 255 en la posición que ocuparía el numero de pasos del segmento. En lugar de interpretarse como un segmento, ROUTEALL lo interpretará como un cambio de estado. lo mejor es ver un ejemplo, que podemos usar para un lanzamiento de misil.
ROUTE3; disparo_dere
;-----------------
db 40,0,2 ; esto son 40 pasos hacia la derecha con vy=0, vx=2
db 255,0 ; esto es un cambio de estado, quedando el sprite desactivado (status=0)
db 1,0,0 ; esto es un paso sin movimiento
db 0
Tras ejecutar un cambio de estado hay que ejecutar algún paso porque los cambios de estado no son movimientos, por eso he puesto un paso sin movimiento. Este mecanismo permite que por ejemplo hagamos una ruta de salto y se la asociemos a nuestro personaje, el cual al comienzo del salto le asignaremos el flag de ruta y movimiento automático. Al terminal el salto, se fuerza un cambio de estado para desactivar el movimiento automático y continuamos andando normalmente.
animación por tintas
Existen juegos que requieren mover grandes bloques de memoria de pantalla para dar sensación de movimiento, como es el caso de las franjas laterales de los juegos de carreras o bloques grandes de ladrillos o tierra. El comando MAP2SP permite hacer todo eso pero la velocidad no es trepidante porque gasta mucha CPU moviendo sprites. La animación por tintas es el complemento perfecto en estos casos.
En ordenadores como el AMSTRAD con su potente paleta de 16 colores simultáneos, muchos juegos hacen uso de la animación por tintas. Un claro ejemplo son algunos juegos de coches cuyas franjas laterales de carretera se prestan a este tipo de animación.
animación de franjas laterales por tintas
La animación por tintas consiste en definir un conjunto de tintas sobre las que se va a hacer rotar un conjunto de colores. Vamos a ver un ejemplo con unas franjas blancas/grises:
concepto animación por tintas
Básicamente para dar sensación de movimiento lo que hay que hacer primeramente es asignar los colores a las tintas que van a rotar. En este caso los colores blanco (26) y gris (13) se asignan a las tintas t1..t8. vamos a suponer que la tinta t1 es la 8, de modo que la tinta t8 será la 15. El resto de tintas (0 a 7) las usaremos para los sprites. En cada instante de tiempo habrá que reasignar los valores de las 8 tintas para dar la sensación de rotación. Es precisamente lo que hace el comando RINK (abreviatura de rótate ink).
RINK te permite definir un patrón de colores a rotar sobre un conjunto de tintas. Una tinta no es un color. Una tinta es un identificador en el rango [0..15] que identifica a un color del rango [0..26]. Para definir el patrón de colores a rotar, usaremos el comando RINK del siguiente modo:
Esto indica que van a rotar 8 tintas comenzando por la tinta_inicial usando el patrón de colores que se indica.
Si queremos rotar solo un patrón de 4 colores (y asi gastar solo 4 tintas y dejar las demás para los sprites) basta con que indiquemos solo 4 colores en el patrón.
RINK,tinta_inicial, color1,color2, color3, color4
RINK te permite de este modo rotar un patrón de 4 colores (gastando 4 tintas) o de 8 colores (gastando 8 tintas).
Una vez establecido el patrón, podemos rotar las tintas mas o menos deprisa con
RINK,step
Encontrarás demos del nuevo comando RINK en la carpeta de demos, directorio DemoExamples/scroll_rink. verás un juego de coches de carreras y otro de un muñeco que avanza en un escenario con ladrillos, un castillo, un árbol y un pájaro que vuela. El ejemplo del castillo combina el uso de scroll basado en MAP2SP y la animación por tintas usando RINK
animación por tintas de ladrillos
os dejo con un vídeo con ejemplos de lo que puedes hacer en BASIC de amstrad usando 8BP v27
Ya está disponible en https://github.com/jjaranda13/8BP la version V24 de la libreria 8BP. Esta vez llega con la nueva funcionalidad de capacidad de scroll multidireccional. Esta nueva funcionalidad te va a permitir diseñar un “mapa del mundo” y hacer que tu personaje o tu nave se desplace por el, con tan solo una línea de código.
La documentación ha sido actualizada y tenéis la nueva versión del manual en github.
La nueva versión es retrocompatible, salvo por el comando MEMORY que hay que ejecutar al principio del juego, que esta vez es MEMORY 25999, es decir, que la nueva funcionalidad resta 1kB al programador, dejando 26KB libres para la lógica de tu programa BASIC (en esos 26KB no se incluyen los gráficos y música, eso se almacena en otro sitio, de modo que tu programa es mas grande realmente)
La idea para el scroll es sencilla: crearemos una lista de elementos que conforman el mapa del mundo (hasta 64 elementos a los que llamaremos “elementos de mapa” o “map ítems”). Cada elemento esta descrito por las coordenadas donde se ubica y la dirección de memoria donde se encuentra la imagen del elemento en cuestión (una casa, un árbol, etc). La imagen asociada a un elemento de mapa podrá tener el tamaño que quieras. Las coordenadas de cada elemento serán un numero entero positivo, desde 0 hasta 32000.
Una vez creado el mapa, invocaremos la función:
|MAP2SP, Yo, Xo
Esta función analiza la lista de los 64 elementos y determina cuales de ellos están siendo visualizados si el mundo se observa colocando la esquina inferior de la pantalla en las coordenadas (Yo, Xo). La función transforma en sprites los “map ítems”, ocupando las posiciones de la tabla de sprites de la cero en adelante. Esto puede consumir muchos o pocos sprites, dependiendo de la densidad de map ítems que tengas. En otra invocación posterior a la misma funcion, los map ítems que ya no estan presentes en la escena no consumiran sprites en la tabla, y otros map ítems tomarán el relevo. Esto significa que la funcion MAP2SP consume un número de sprites variable e indeterminado, que depende del número de map ítems visibles en pantalla en cada momento. En el ejemplo siguiente usaría 3 sprites al invocar a MAP2SP en las coordenadas señaladas
Si usas este mecanismo, tu personaje y los enemigos deben usar los sprites desde 31 hacia abajo, de ese modo evitaras posibles choques entre los sprites que usa el mecanismo de scroll y tus personajes.
Debes invocar MAP2SP en cada ciclo de juego o al menos cada vez que modifiques las coordenadas del punto de vista desde donde quieres visualizar el mundo.
Una vez aclarado el concepto vamos a revisar en detalle como se especifica el mapa del mundo y un ejemplo de uso de la funcion MAP2SP
La tabla donde daremos de alta todos los elementos del mapa se llama MAP_TABLE y se especifica en un fichero .asm llamado map_table_tujuego.asm
Esta tabla contiene las 64 entradas que definen las imágenes del mapa del mundo para tus juegos con scroll. La tabla se ensambla en la 26000 y contiene 3 parámetros globales (que ocupan 5 bytes en total) y una lista de "map items", los cuales están descritos por 3 parámetros cada uno (x, y, dirección de imagen)
La lista puede contener hasta 64 items pero se puede limitar con uno de los parámetros globales.
La lista ocupa los 5 bytes iniciales + 64 items x 6 bytes = 5+384=399 bytes
La tabla comienza con 3 parámetros:
- el alto máximo de cualquier map item
- ancho máximo de cualquier map ítem (debe expresarse como un número negativo)
- número de ítems
Los dos primeros parámetros son importantes para chequear cuando un sprite puede estar parcialmente apareciendo en pantalla, ya que la funcion MAP2SP no conoce ni averigua el ancho ni el alto de cada imagen. Tan solo conoce donde está situado el map ítem y suponiendo el alto y ancho máximos, averigua si ese ítem puede estar entrando en la pantalla. En caso de que asi sea, se crea un sprite a partir del map ítem. Si esos dos parámetros se ponen a cero, será necesario que la esquina superior izquierda del map ítem esté dentro de la pantalla para que dicho ítem sea transformado en un sprite.
Veamos un ejemplo del fichero llamado map_table_tujuego.asm
;MAP TABLE ;----------------------- dw 50; maximo alto de un sprite por si se cuela por arriba y ya hay que pintar parte de el dw -40; máximo ancho de un sprite por si se cuela por la izquierda (numero negativo) db 64; numero de elementos del mapa.como mucho debe ser 64 ; a partir de aqui comienzan los items dw 100,10,CASA; 1 dw 50,-10,CACTUS;2 dw 210,0,CASA;3 dw 200,20,CACTUS;4 dw 100,40,CASA;5 dw 160,60,CASA;6 dw 70,70,CASA;7 dw 175,40,CACTUS;8 dw 10,50,CASA;9 dw 250,50,CASA;10 dw 260,70,CASA;11 dw 290,60,CACTUS;12 dw 180,90,CASA;13 dw 60,100,CASA;14 …
Para diseñar tu mundo te recomiendo que cojas un cuaderno a cuadros y vayas dibujando sobre el los elementos que quieres que tenga tu mundo. Cada cuadradito del cuaderno puede representar una cantidad fija como 8 pixeles o 25 pixeles. El caso es que debes tomarte tu tiempo en dibujar el mundo que deseas y el modo en que se va a recorrer. Por ejemplo hay juegos tipo gaunlet multidireccionales y otros de scroll vertical como el comando. Tú eliges pero en cualquier caso hazlo con tiempo y paciencia y el resultado valdrá la pena. Cada mapa seria como una fase del juego. En 8BP puedes cambiar el mapa cuando quieras usando funciones POKE, o bien tener mapas grabados en archivos de 400 bytes que cargas en la dirección 26000, etc. Hay muchas soluciones para hacer diferentes fases sin necesidad de recurrir a ficheros en disco, ya que cada mapa ocupa 400 bytes como mucho y puedes tener varias fases en memoria RAM
Ahora vamos a ver un ejemplo de uso de la función MAP2SP. Básicamente hay que invocarla una vez en cada ciclo de juego con las nuevas coordenadas del origen desde donde se observa el mundo.
La función creará un numero de sprites variable desde el sprite 0 en adelante y al crearlos lo va a hacer con sus coordenadas de pantalla adaptadas. Es decir, aunque un map ítem tenga una coordenada x=100, si el origen móvil lo ubicamos en la posición x=90 entonces ese sprite será creado con la coordenada de pantalla x’=x-90=10. La coordenada en el eje Y tendrá en cuenta que el eje Y en el amstrad crece hacia abajo, mientras que el mapa del mundo crece hacia arriba. Por ello la coordenada Y es adaptada usando la ecuación Y'= 200-(Y-Yorig). Pero no te preocupes, esta adaptación ya la hace la funcion MAP2SP. Tu solo tienes que ir cambiando el origen móvil desde donde se debe visualizar el mapa del mundo.
En este minijuego se ha realizado un mundo compuesto de casas y cactus y nuestro personaje camina entre los elementos. En este ejemplo, en caso de colisión (detectado con COLSPALL), el personaje no podrá continuar. En un juego de aviones en el que los map ítems sean “sobrevolables”, podríamos parametrizar la colisión para que solo se detecten colisiones con enemigos y disparos y no con elementos de fondo, usando COLSP, 32, <sprite inicial>, <sprite_final>.
Ahora veamos el listado, como ves, es muy pequeño, pero lo tiene todo: scroll multidireccional, lectura de teclado, cambio de secuencias de animación del personaje, detección de colision, música…
10 MEMORY 25999 20 MODE 0 30 ON BREAK GOSUB 280 40 CALL &6B78 50 DEFINT a-z 60 INK 0,12 70 FOR y=0 TO 400 STEP 2 80 PLOT 0,y,10:DRAW 78,y 90 PLOT 640-80,y,10:DRAW 640,y 100 NEXT 110 x=0:y=0 120 |SETUPSP,31,0,&X100001 130 |SETUPSP,31,7,1:dir=1:' direccion inicial hacia arriba 140 |locatesp,31,100,36 150 |MUSIC,1,5 160 |SETLIMITS,10,70,0,199: |PRINTSPALL,0,1,0 170 col%=32:sp%=32:|COLSPALL,@sp%,@col% 180 |COLSP, 34, 0, 0: REM colision en cuanto hay un mnimo solape 190 'comienza ciclo de juego 200 IF INKEY(27)=0 THEN x=x+1:IF dir<>3 THEN dir=3:|SETUPSP,31,7,3: GOTO 220 210 IF INKEY(34)=0 THEN x=x-1:IF x<0 THEN x=0:ELSE IF dir<>4 THEN dir=4:|SETUPSP,31,7,4 220 IF INKEY(67)=0 THEN y=y+2:IF x=xa AND dir <> 1 THEN dir=1:|SETUPSP,31,7,1: GOTO 240 230 IF INKEY(69)=0 THEN y=y-2:IF y<0 THEN y=0:ELSE IF x=xa AND dir <>2 THEN dir=2:|SETUPSP,31,7,2: 240 IF xa=x AND ya=y THEN dir=0 ELSE |ANIMA,31 250 |MAP2SP,y,x:|COLSPALL: IF col<32 THEN x=xa:y=ya:|MAP2SP,y,x ELSE xa=x:ya=y 260 |PRINTSPALL 270 GOTO 200 280 |MUSICOFF:MODE 1: INK 0,0:PEN 1
Y esto es todo, ahora solo queda empezar a hacer juegos con scroll tipo nemesis, commando, 1943, rambo, gaunlet y todo que se nos pase por nuestra imaginación. Eso si, usando nuestro querido BASIC de amstrad
Además también se incluye una nueva versión del editor de sprites que incorpora esta nueva capacidad de diseño de sprites con sobreescritura y el manual de programación actualizado.
Los sprites ahora no solo son capaces de sobreescribirse sobre un fondo que van reponiendo mientras avanzan sino que se pueden ordenar por coordenada Y, de modo que los solapes entre sprites reflejan una profundidad propia de juegos como golden axe o double dragon.
los solapes, ademas de ordenados conservan la forma del sprite, no son rectangulares, tal como puedes ver en esta imagen.
Todo ello ha sido posible sin usar la conocida técnica de "doble buffer", por lo que aun dispones de 27KB para tu programa en BASIC. La libreria completa ocupa sólo 5250 bytes. He recortado el área de memoria para la música de 1.5KB a 1.25 KB, pero nada más.
A diferencia del "doble buffer", la solución adoptada en 8BP está inspirada en
el programador Paul Shirley (autor de “misión Genocide”), pero es ligeramente
diferente. Contaré directamente la de 8BP:
En el Amstrad un pixel de mode 0 es
representado con 4 bits, por lo que son posibles hasta 16 colores diferentes de
una paleta de 27.
Pues bien, si usamos un bit para el color de
fondo y 3 para los colores de los sprites, tendremos un total de 2 colores de
fondo + 7 colores + 1 color para indicar transparencia = 9 colores en total.
Esto nos va a permitir “esconder” el color de fondo en el color del sprite,
aunque pagamos el precio de reducir el número de colores de 16 a tan solo 9.
Además, el fondo solo podrá ser de dos colores. Sin embargo los elementos
ornamentales de la pantalla de juego pueden tener mas color, pues los sprites
no pasarán por encima, de modo que podemos conseguir cierta dosis de colorido
en nuestro juego. Aquí tenemos un ejemplo del resultado que se puede obtener
con esta técnica: suelo marrón y cielo azul son los colores del fondo, pero además hay arboles con hojas verdes y un tejado rojo y morado. los elementos ornamentales disponen de 9 colores, y los sprites de 7, es suficiente para dotar la escena de un colorido aceptable como podéis comprobar, y es muy rápido.
hay elementos que se pueden añadir a las escena dotándola de aun más color, como el caldero verde, que en realidad es un sprite.
Para que un sprite tenga sobreescritura simplemente hay que activar su bit 6 en su byte de status
De momento como aperitivo a esta nueva versión es suficiente, Poco a poco os iré contando el funcionamiento de la ordenación de sprites ultrarrápida y las tripas de la impresión con sobreescritura.
Para los programadores más avanzados, os diré que mi próxima mejora de la librería será un scroll supersuave, basado en programación avanzada del chip 6845 que es el controlador de vídeo del Amstrad. Posiblemente os quite 1KB , dejando la memoria disponible para programar en BASIC en 26KB (ahora son 27KB) pero ese será todo el perjuicio.
Ya esta listo el nuevo videojuego "Anunnaki", realizado en BASIC con la libreria 8BP.
Este es un juego de arcade y hace un uso intensivo de la técnica de lógicas masivas.
El juego hace uso de la técnica de lógicas masivas para manejar hasta 30 sprites entre naves y disparos. Todo ha sido posible en BASIC. Además, se utilizan técnicas para simular scroll, descritas en el manual de 8BP (version v21) que podeis encontrar en github
Además, esta disponible la version V21 de la libreria 8BP en github y esta nueva versión incorpora
SETUPSP,5,Vy,Vx: con un solo comando ahora actualizamos la Vy y la Vx, ahorrando casi 3 milisegundos
STARS: comando mejorado, ahora realiza mejor el calculo cuando una estrella se sale por un limite y debe entrar por el lado opuesto
herramienta SPEDIT v5: ahora puedes "espejar" tus sprites sobre un eje central imaginario, una ayuda para dibujar sprites simetricos
explicación mas detallada de la tecnica de logicas masivas
nuevos consejos de programación eficiente en memoria y velocidad
código del videojuego anunnaki
nuevos consejos sobre como editar musica para no tener problemas
Ya esta disponible la versión v20 de la libreria 8BP, totalmente retrocompatible
He actualizado el repositorio de github https://github.com/jjaranda13/8BP con los siguientes cambios (coherentes entre la documentación y la librería). Con estas mejoras los juegos arcade ahora funcionan aun más rapido. Se incluye la demo de annunaki donde podéis comprobar el uso de estas mejoras. Las mejoras son:
posibilidad de definir la sensibilidad de la colisión entre sprites
nuevo comando COLSPALL que acelera la detección de colisión
Posibilidad de definir la sensibilidad de la colisión entre sprites COLSP : ahora puedes definir la sensibilidad de la colision (grado de solape entre sprites) Es posible ajustar la sensibilidad del comando COLSP, decidiendo si el solape entre sprites debe ser de varios pixels o de uno solo, para considerar que ha habido colisión. Para ello se puede configurar el número de pixels (pixels en dirección Y, bytes en dirección X) de solape necesario tanto en la dirección Y como en la dirección X, usando el comando COLSP y especificando el sprite 34 (que no existe) |COLSP, 34, dy, dx La librería 8BP no usa “pixels” en la coordenada X, sino bytes, de modo que debes tener en cuenta que una colisión de 1 byte, en realidad son 2 pixels y esa es la mínima colisión posible cuando ajustas dx=0. En la coordenada Y, la librería trabaja con líneas de modo que dy=0 significa una colisión de un solo pixel. Una colisión estricta, útil para disparos sería aquella que no tolera ningún margen, considerando colisión en cuanto hay un mínimo solape entre sprites (1 pixel en dirección Y o un byte en dirección X)
|COLSP, 34, 0, 0: rem colision en cuanto hay un mínimo solape
Sin embargo, si estamos haciendo un juego en MODE 0, donde los pixels son mas anchos que altos, es quizás mas adecuado dar algo de margen en Y y nada en X. Por ejemplo
|COLSP, 34, 2, 0 : rem colision con 3 pix en Y y 1 byte en X Mi recomendación es que si hay disparos estrechos o pequeños, ajustes la colision con (dy=1, dx=0) mientras que si solo hay personajes grandes puedes dejarla con mas margen (dy=2, dx=1). También debes considerar que si tus sprites tienen un “margen” de borrado alrededor para desplazarse borrándose a si mismos, dicho margen no debería formar parte de la consideración de colisión por lo que tiene sentido que tanto dy como dx no sean cero. En cualquier caso es algo que decidirás en función del tipo de juego que hagas Nuevo comando COLSPALL que acelera la colisión entre sprites y simplifica tu programa BASIC
Con la funcion COLSP que hemos visto hasta ahora, es posible la detección de colisión de un sprite con todos los demás. Sin embargo si tenemos un disparo múltiple, donde por ejemplo nuestra nave puede disparar hasta 3 disparos simultáneamente, tendríamos que detectar la colisión de cada uno de ellos y adicionalmente la de nuestra nave, resultando en 4 invocaciones a COLSP. Debemos tener presente que cada invocación atraviesa la capa de análisis sintáctico, por lo que 4 invocaciones resulta costoso. Para ello disponemos de un comando adicional: COLSPALL Esta funcion funciona en dos pasos, primero debemos especificar que variables van a almacenar el sprite colisionador y el colisionado |COLSPALL, @colisionador%, @colisionado% Y posteriormente, en cada ciclo de juego simplemente invocamos la funcion sin parámetros: |COLSPALL La función va a considerar como sprites “colisionadores” aquellos que tengan el flag de colisionador a “1” en el byte de estado (es el bit 5), y como “colisionados” aquellos sprites que tengan a “1” el flag de colision (bit 1) del byte de estado. Los sprites colisionadores deberán ser nuestra nave y nuestros disparos
La función COLSPALL empieza comprobando el sprite 31 (si es colisionador) y va descendiendo hasta el sprite 0, invocando internamente a COLSP para cada sprite colisionador. En cuanto detecta una colisión, interrumpe su ejecución y retorna el valor del colisionador y el colisionado. Por ello es importante que nuestra nave tenga un sprite superior a nuestros disparos. De ese modo, si nos alcanzan, lo detectaremos aunque hayamos alcanzado a un enemigo con un disparo en el mismo instante. En cada ciclo de juego solo se podrá detectar una colisión, pero es suficiente. No es una limitación importante que en cada fotograma solo pueda empezar a “explotar” un enemigo. Si, por ejemplo, tiras una granada y hay un grupo de 5 soldados afectados, cada soldado comenzará a morir en un fotograma distinto, y en 5 fotogramas estarán todos explotando. Usando COLSPALL no explotarán todos a la vez, pero tu juego será más rápido y en un arcade es algo muy importante.
Espero que os gusten estas mejoras. Yo voy a intentar centrarme en avanzar en el videojuego "Annunaki",el cual hace uso de estas mejoras por ser un arcade espacial. En cuanto lo tenga listo lo compartiré con todos vosotros