Curso online (AUA) de 8BP:
- descubre-8-bits-de-poder
- programando-una-maquina-de-1984
- arquitectura-y-memoria
- que-necesitas-para-empezar
- creando-un-juego-paso-a-paso
- crear-disco-cinta
- ciclo-de-juego
- editar-sprites
- sprite-flipping-y-la-sobreescritura-de-sprites
- sprites tras el fondo y tabla de atributos
- sprites con sobreescritura y mas colorido
- colisiones-entre-sprites/
- ajuste-sensibilidad-colision-sprites
- programar-un-disparo-multiple
- tabla-de-secuencias-de-animacion
- imprimir-los-sprites-ordenados-en-pantalla
- tu-primer-juego-con-8bp
- layout-y-tilemap-en-8bp
- programacion-avanzada-con-logicas-masivas
- una-sola-logica-para-gobernar-pantallas
- pacman-con-8bp
- ahorrar-memoria-en-layouts
- programacion-avanzada-8bp
- tecnica-de-logicas-masivas
- 32-sprites-con-logicas-masivas
- ejecucion-alternada-logica-cascada
- movimiento-de-sprites en bloque
- ejemplo-con-logicas-masivas/
- una-logica-para-gobernar
- evitar-if-innecesarios
- optimizar-el-codigo-del-juego/
- rutas-de-sprites
- trayectorias-complejas
- usar-routesp
- gestion-del-teclado
- rutas-avanzadas
- cambios-de-estado-forzados-entre-rutas
- cambios-de-secuencia-forzados-entre-rutas
- cambios-imagen-forzados-entre-rutas/
Video Tutoriales 8BP
- Tema 1: primeros pasos
- Tema 2: crear y usar sprites
- Tema 3: mover sprites
- Tema 4: detección de colisiones y rutas de sprites
- Tema 5: Scroll en 8BP
- Tema 6: programar en C con 8BP
- Tema 7: Sprites con sobreescritura
- Tema 8: Medir los FPS de tu juego
Algunos consejos de programación
Una de las técnicas fundamentales a aplicar es la técnica de "lógicas masivas" , a la cual se dedica una página específica (ver lógicas masivas).Esta técnica consiste fundamentalmente en ejecutar menos lógica en cada ciclo de juego (lo que se denomina “reducir la complejidad computacional”) y para ello hay varias opciones:
- Usar una sola lógica que afecta a muchos sprites a la vez (usando los flag de movimiento automático y/o relativo)
- Ejecutar varias tareas, pero solo una de ellas o unas pocas en cada ciclo del juego, usando aritmética modular (u operaciones binarias) en cascada.
- Introducir limitaciones en el juego que no sean importantes o no afecten a la jugabilidad, para reducir el numero de tareas que se ejecutan en cada ciclo de juego o simplificar las tareas de modo que se ejecuten mas rápido.
- Como norma general, reduce el numero de instrucciones por las que pasa tu programa en cada ciclo de juego, reemplazando a veces algoritmos por precálculos o poniendo mas instrucciones para lograr (paradójicamente) que se ejecuten menos cada ciclo.
Todos los consejos están orientados a reducir memoria (complejidad espacial) o CPU (complejidad temporal) . Muchos de los consejos y trucos los iré posteando en la pagina principal del blog. Aqui, aparte de hacer una recopilación de consejos, pondré links a cada consejo especifico.
Técnicas de reducción de tiempo de ejecución
- Mide el consumo en tiempo que consume cada instrucción. Descubrirás cosas sorprendentes, como que un GOTO es mas rápido que un REM, o que un REM es mas rápido que su versión abreviada, la comilla simple. Usa un programa como este para medir:
10 MEMORY 26999
140 PRINT "el comando tarda ";((b!-a!)/300 -0.47);"milisegundos"
140 PRINT "el comando tarda ";((b!-a!)/300 -0.47);"milisegundos"
- Usa el menor número de parámetros en las invocaciones a los comandos de 8BP. cada parámetro consume tiempo y cada milisegundo es importante en un juego, sobre todo de arcade
- Prueba versiones alternativas de una misma operación, consulta aqui
- A=A+1:IF A>4 then A=0 : REM esto consume 2.6ms
- A=A MOD 3 +1 : REM esto consume 1.84 ms
- A=1+A AND 4 : REM esto consume 1.60 ms
- Precalcula cualquier cosa que puedas precalcular y almacenar en un array en lugar de calcularla durante el juego
- Simplifica: una lógica compleja es una lógica lenta.Si quieres hacer algo complicado, una trayectoria compleja, un mecanismo de inteligencia artificial...no lo hagas, trata de "simularlo" con un modelo de comportamiento mas sencillo pero que produzca el mismo efecto visual. Por ejemplo un fantasma que es inteligente y te persigue, en lugar de que tome decisiones inteligentes, haz que trate de tomar la misma dirección que tu personaje, sin ninguna lógica. Ello hará que parezca que es listo (solo es una idea)
- No uses coordenadas negativas si necesitas actualizar la posición de tu nave o personaje de forma muy rápida. El comando POKE (el de BASIC) es muy veloz pero solo soporta números positivos , al igual que PEEK. en caso de usarlas, usa |POKE y |PEEK (comandos de 8BP). Reserva el uso de |LOCATESP para cuando vayas a modificar ambas coordenadas y puedan ser positivas y negativas.
- Si necesitas comprobar algo, no lo hagas en todos los ciclos de juego. A lo mejor basta que compruebes ese "algo" cada 2 o 3 ciclos, sin ser necesario que lo compruebes en cada ciclo. Para poder elegir cuando ejecutar algo, haz uso de la "artitmética modular". En BASIC dispones de la instrucción MOD que es una excelente herramienta. Por ejemplo para ejecutar una de cada 5 veces puedes hacer : IF ciclo MOD 5 = 0 THEN ...
- Al programar un disparo múltiple (una nave que puede disparar 3 proyectiles simultáneamente) usa la técnica de lógicas masivas y reduce la lógica. Si en cada fotograma solo puede morir un enemigo, reducirás mucho el número de instrucciones a ejecutar. consulta este post: como-programar-un-disparo-multiple.html y usa por favor el comando COLSPALL, eso aun te permitirá programar más eficientemente
- Haz uso de las "secuencias de muerte". Ello te permitirá ahorrar instrucciones para comprobar si un sprite que está explotando ha llegado a su último fotograma de animación para desactivarlo. consulta este post: secuencias de muerte
- gestiona el teclado ejecutando el menor numero de instrucciones posibles. Esto puede aumentar un poco el listado pero reducir el numero de instrucciones por las que pasa tu programa lo acelerará. consulta el manual para aprender mas sobre como hacer esto
- elimina las lineas REM o escribelas en lugares por los que no pasa tu programa
- define rutas avanzadas que manipulen el estado para evitar detectar colision con todos los sprites vivos a la vez o si el enemigo no se mueve en todos los fotogramas, manipula su estado para que no sea imprimible cuando no se mueve.
Técnicas de reducción del uso de memoria
- Reutiliza las lineas de código que gobiernan la lógica de un enemigo, mediante los comandos GOSUB/RETURN, y el uso de parámetros asi no tendrás que escribir la misma rutina para el enemigo1, para el enemigo2, etc. solo una rutina compartida para todos
- En caso de usar layouts, no los almacenes completos sino una versión simplificada que luego proceses y generes el layout final. Por ejemplo si en una pantalla solo hay dos plataformas, no es necesario gastar memoria para decir que en todos los espacios vacíos restantes hay "nada". mejor simplemente guardas únicamente la ubicación de esas dos plataformas
- otra forma de ahorrar memoria en layouts es usar bloques grandes, por ejemplo de 8x16 pixels, como se hace en el videojuego happy monty. En ese juego cada pantalla ocupa solo 160 bytes
Mas color en tus sprites
- para usar mas de 9 colores con sobreescritura puedes leer este post: http://8bitsdepoder.blogspot.com.es/2018/02/usa-mas-colores-en-8bp-con.html
Hola, no creo que tenga interés pero en la página 20 del manual, donde dice "No te puedo asegurar cual es la zona de memoria donde el intérprete BASIC...", creo que esa dirección es &AE70. Cada llamada de GOSUB 100 guarda 6 bytes a partir de esa zona, hasta llegar a la llamada 83 y almacena a partir de la posición &B062 los últimos 6 bytes. En la llamada 84 peta. Al contrario de lo que pueda parecer es una pila que crece hacia zonas superiores de la memoria y no hacia zonas bajas.
ResponderEliminarexcelente información!! muchas gracias. La incorporaré al manual
ResponderEliminar