martes, 31 de enero de 2017

Disponible versión V28 de la librería 8BP

hola amigos de 8 bits de poder

Ya esta disponible la versión v28 de 8BP,  en https://github.com/jjaranda13/8BP la cual sigue ocupando lo mismo, 6KB y trae nuevas funcionalidades para la definición de rutas de sprites
(todo está documentado en el nuevo manual disponible en github):

estos nuevos mecanismos los estoy usando para programar un nuevo juego de plataformas:


Para empezar os recordaré lo que es una ruta: básicamente es un conjunto de segmentos que definen la trayectoria de un sprite. Cada segmento posee un numero de pasos , una Vy y una Vx, es decir una ruta es algo asi:

ROUTE0
    db 10,2,1 ; diez pasos con Vy=2, Vx=1
    db 5,1,-1; cinco pasos con Vy=1, Vx=-1
    db 0: fin de la ruta, al llegar aqui se empieza de nuevo

En mitad de una ruta, o al final nos puede interesar cambiar el estado del sprite. Por ejemplo eso es útil en un disparo que queremos que se desactive "solo" tras avanzar suficiente como para estar seguros de que se ha salido de la pantalla. Pues bien, también puede ser interesante hacer mas cambios en un sprite durante la ruta. Las cosas que ahora podemos hacer son 3

- Cambio de estado del sprite
- Cambio de secuencia de animación del sprite
- Cambio de imagen (útil si no tiene secuencia asociada)

Cambio de estado forzado desde una ruta
Consiste en que podemos forzar un cambio de estado en mitad de una ruta. Para
ello indicaremos que deseamos un cambio de estado indicando como valor de número de pasos del segmento = 255.
El cambio de estado es un segmento más y es importante que mantengas el mismo número de parámetros por segmento, es decir, 3 bytes. Un cambio de estado a status=13 podria escribirse como:

    255,13,0

El tercer parámetro (el cero) no significa nada, es solo un “relleno” para que el segmento mida 3 bytes, pero es imprescindible.
El valor 255 le indicará al comando ROUTEALL que lo que debe hacer esta vez es cambiar el estado del sprite, asignándole el que se indique a continuación. El cambio de estado se ejecuta sin consumir un paso, por lo que siempre se ejecutará el siguiente paso al cambio de estado. Si no queremos que el sprite se mueva mas, simplemente definiremos un segmento de un paso sin movimiento en X ni en Y justo después del cambio de estado. Veamos un ejemplo:

ROUTE3; disparo_dere
;-----------------
db 40,0,2; cuarenta pasos a la derecha con Vx=2
db 255,0,0; cambio de estado a cero
db 1,0,0; quieto Vy=0, Vx=0
db 0
ROUTE4; disparo_izq
;-----------------
db 40,0,-2; cuarenta pasos a la izquierda con Vx=-2
db 255,0,0; cambio de estado a cero
db 1,0,0; quieto Vy=0, Vx=0
db 0

Estas dos rutas las vamos a usar para disparar con nuestro personaje. La primera de ellas, tras recorrer 40 pasos en los que avanza 2 bytes en X, sufre un cambio de estado y el sprite pasa a estado 0, es decir, desactivado. El siguiente segmento solo tiene un paso y no hay movimiento (vy=0, vx=0).
Con este mecanismo podemos disparar y que los disparos se desactiven solos cuando se salen de la pantalla. Ello ahorra lógica de BASIC y acelera nuestros juegos.

Los cambios de estado se pueden forzar en cualquier segmento de la ruta, no necesariamente al final, aunque en el caso de un disparo es muy lógico hacerlo al final de la ruta.


Cambios de secuencia de animación forzados desde rutas
Podemos cambiar la secuencia de animación de un sprite usando un segmento especial. Cuando pongamos 254 en el valor del número de pasos, el comando ROUTEALL interpretará que se debe realizar un cambio de secuencia de animación en el sprite. Ejemplo:
254,10,0
Este segmento cambia la secuencia de animación del sprite, estableciendo la secuencia número 10. El tercer parámetro (el cero) no significa nada, es solo un “relleno” para que el segmento mida 3 bytes, pero es imprescindible.
Al igual que con el cambio de estado, el cambio de secuencia se ejecuta sin consumir un paso, por lo que siempre se ejecutará el siguiente paso al cambio de secuencia.


Cambios de imagen forzados desde rutas: boing, boing!!!
Hemos visto como enrutar sprites con ROUTEALL o aun mejor, con AUTOALL,1
A menudo no queremos enrutar un sprite a través de una trayectoria sino algo más cotidiano: dar un salto con un personaje


Para no tener que controlar si el personaje ha llegado al punto cenital del salto, podemos usar un segmento especial que indica cambio de imagen. Al igual que cualquier otro segmento, consume 3 bytes, pero en este caso el primero es el indicador de cambio de imagen (un valor 253) y los dos siguientes se corresponden con la dirección de memoria de la imagen. MUCHA ATENCION, deberás usar “dw” antes del nombre de la imagen que quieres asignar, por lo que este segmento de cambio de imagen lo tendrás que escribir en dos líneas. Un “db” para el 253 y un “dw” para la dirección de memoria de la imagen.

  db 253
  dw SOLDADO_R1_UP

En el ejemplo siguiente tenemos un muñeco que salta. Al subir el muñeco que se borra a sí mismo por abajo mientras que al bajar se borra a sí mismo por arriba. Para que no haya discontinuidad en el movimiento, justo al cambiar una imagen por otra es necesario realinear verticalmente al soldado, subiendo la imagen de bajada exactamente 5 lineas, para hacerla coincidir con el soldado que estaba subiendo.


Usaremos dos rutas, una para saltar a la derecha y otra a la izquierda. Este sería el fichero routes_mygame.asm
;
; LISTA DE RUTAS
;================
;pon aqui los nombres de todas las rutas que hagas
ROUTE_LIST
dw ROUTE0
dw ROUTE1
dw ROUTE2
dw ROUTE3
dw ROUTE4
; DEFINICION DE CADA RUTA
;==========================
ROUTE0; jump_right
db 253
dw SOLDADO_R1_UP
db 1,-5,1
db 2,-4,1
db 2,-3,1
db 2,-2,1
db 2,-1,1
db 253
dw SOLDADO_R1_DOWN
db 1,-5,1; subo para que UP y down encajen
db 2,1,1
db 2,2,1
db 2,3,1
db 2,4,1
db 1,5,1
db 253
dw SOLDADO_R1
db 1,5,1; baja una mas
db 255,13,0; nuevo estado, ya sin flag de ruta y con flag de animacion
db 254,32,0; macrosecuencia 32
db 1,0,0; quietooo.!!!!
db 0

Y esto es todo. Os dejo con un video de preview del juego que estoy haciendo




Cuando tenga avances en el juego de plataformas publicaré mas
hasta pronto!



martes, 3 de enero de 2017

Análisis del uso combinado de CPCBASIC compiler y 8BP

hola amigos de 8BP

Hoy os traigo una curiosidad interesante. Existe un compilador de BASIC para amstrad CPC que corre bajo windows, llamado "BASIC3" o "CPC basic compiler". lo podéis encontrar en http://www.cpcbasic.tk/


Esta herramienta es útil en dos casos:
- tanto si quieres compilar tu juego para no mostrar el listado de tu programa
 -como si quieres ganar algo de velocidad (sobre todo tiene sentido en arcade)


Dicho compilador no es compatible 100% con locomotive BASIC pero con pocos cambios se puede hacer funcionar un programa. Es parecido a la herramienta "fabacom", que compila locomotive BASIC, pero a diferencia de esta, no genera un ejecutable gigante (fabacom mete una sobrecarga de 10KB)

He compilado el mini-invaders y aqui tenéis el resultado. Va mas deprisa como era de esperar. ten en cuenta que al compilar, se esta ejecutando el juego en código máquina. ya no es interpretado. Como puedes ver en el vídeo, la mejora es perceptible.
Yo seguiré programando en BASIC intepretado y compartiré el código fuente de mis juegos pero esta opción no es mala ya que a diferencia de fabacom, no consume mucha RAM. El binario que ha generado son 4KB, mientras que el listado BASIC ocupa 3KB.  Es algo más pero es razonable. Posteriormente he compilado Nibiru (el cual no compila si no se hacen muchos cambios), de 17KB y ha generado un binario de 22kB, es decir, una sobrecarga de 5KB. Probablemente cuanta mas variedad de instrucciones de BASIC se usen, mayor es la sobrecarga pero 5KB sigue siendo razonable.


Es realmente importante la ganancia? hablamos de un 50% de aumento de la velocidad como mucho, en el mejor caso. Es decir que es como pasar de 100Km/h a 150Km/h. Esto no esta mal, pero piensa que hemos pasado del BASIC interpretado al código máquina y normalmente se dice que la velocidad se debe multiplicar al menos por 100  (hablaríamos de un incremento del 10000% ). Sin embargo  sólo hemos ganado un 50%. El motivo de tan "pobre" ganancia es que las instrucciones de 8BP ya hacen todo el trabajo duro y en realidad el compilador solo ha traducido a código máquina la parte menos pesada, la lógica del juego.

En resumen, está bien, pero no esperes un milagro. Sólo tiene sentido si a tu juego le falta velocidad. Cuando necesites mas velocidad, hay estrategias explicadas en el manual de 8BP para acelerar tu juego en BASIC, como la técnica de lógicas masivas, o sencillos ajustes finales tales como eliminar lineas REM o sustituir las invocaciones RSX por CALL XXXX, o eliminar las invocaciones a RND y cambiarlas por un array pseudoaleatorio, etc. Es decir, hay cierto margen para aumentar la velocidad y sólo si aun así es insuficiente, tendrá sentido compilar, ya que lo que vas a ganar es "sólo" un 50%


hasta la vista!

miércoles, 28 de diciembre de 2016

Cómo hacer un juego tipo "space invaders" en BASIC para Amstrad usando la librería 8BP

Hola amigos de 8 bits de poder

Esta vez os traigo un pequeño tutorial de introducción para hacer un juego tipo "space invaders" en unos minutos. El tutorial está disponible en el canal de vídeos de 8BP https://www.youtube.com/watch?v=6OcB_hjuYiU




Y el juego "mini-invaders" lo encontrareis en la carpeta "Game Examples" del proyecto Github en https://github.com/jjaranda13/8BP


Os adjunto aquí el listado del juego. Como complemento a las explicaciones del vídeo os daré algunas pinceladas sobre el listado BASIC del juego que adjunto.

- el juego usa 32 sprites
- la nave es el sprite 31 
- los disparos que puedes lanzar con la nave son el 29 y el 30
- los invaders disparan usando el sprite 28 
- los invaders usan los sprites del 0 al 27 (28 invaders en total)
los sprites 31,30 y 29 tienen flag de colisionador activo
- el resto de sprites son "colisionados" y tienen flag de colisionado activo
- los invasores tienen flag de movimiento automatico activo y se les asocia la ruta "0" que los mueve de derecha a izquierda y hacia abajo, lo típico de los invasores
- los disparos de la nave y de los invaders usan una característica de la V27. recorren la pantalla y al salir se desactivan automáticamente con un cambio de estado definido al final de su ruta, simplificando de este modo la lógica de BASIC y por consiguiente acelerando el juego

a continuación teneis el listado

10 MEMORY 25999
20 dir=42540:FOR star=0 TO 40
30 POKE dir+star*2,RND*200
40 POKE dir+star*2+1,RND*80
50 NEXT
60 DEFINT A-Z: CALL &6B78:' install RSX
70 |PRINTSPALL,0,1,0:|AUTOALL,1:MODE 0
80 ON BREAK GOSUB 810
90 CALL &BC02:'restaura paleta por defecto     
100 INK 0,0:BORDER 1: vidas=3: puntos=0
110 CLS: |STARS,0,10,4,2,0: ciclo=0:counter=0
120 ENT -5,7,10,1,7,-10,1:ENV 1,1,15,1,15,-1,1:
130 'nave
140 |SETUPSP,31,9,16:|SETUPSP,31,0,33:|SETUPSP,31,7,0
150 x=40:y=192:|LOCATESP,31,192,40

160 'fire [29,30]
170 FOR i=29 TO 30:|SETUPSP,i,9,18:|SETUPSP,i,0,0:NEXT
180 disp=0

190 'fire invaders [28]
200 |SETUPSP,28,9,19:|SETUPSP,28,0,0

210 ' invaders [0..27]
220 i=0:FOR yi=0 TO 3
230 FOR xi=0 TO 6
240 |SETUPSP,i,7,1
250 |LOCATESP,i,yi*16+10,xi*8
260 |SETUPSP,i,0,143
270 |SETUPSP,i,15,0
280 i=i+1:NEXT:NEXT

290 'setup colision ------------
300 collider=0:collided=0:|COLSP,34,4,0
310 |COLSPALL,@collider,@collided:|COLSP,32,0,28

320 'WAIT SPACE TO START --------
330 PLOT 1,382:DRAW 640,382:|SETLIMITS,1,80,10,200:|PRINTSPALL
340 LOCATE 1,1:PRINT "SCORE";puntos:LOCATE 12,1:PRINT "LIVES:";vidas
350 SOUND 1,25,80,12,,5
360 IF INKEY(47)<>0 THEN  360
370 SOUND 1,100,7,15

380 'ciclo de juego ------------

390 GOSUB 520:'lectura teclado y movimiento nave y/o disparo
400 GOSUB 630:'disparo invaders
410 ciclo=ciclo+1: IF ciclo>=1048 THEN 110
420 |STARS,0,10,4,1,0
430 |AUTOALL:|PRINTSPALL:|COLSPALL
440 IF collided=32 THEN 390
450 IF collider=31 THEN vidas=vidas-1: IF vidas=0 THEN 690 ELSE 730
460 |SETUPSP,collided,7,2:puntos=puntos+1
470 |SETUPSP,collider,9,17:'borrado del disparo
480 |SETUPSP,collider,15,3
490 SOUND 7,1000,20,15,,,15:LOCATE 7,1:PRINT puntos
500 GOTO 390

510 ' rutina de movimiento nave -----
520 IF INKEY(27)=0 THEN x=x+1:GOTO 540
530 IF INKEY(34)=0 THEN x=x-1
540 IF counter+8<=ciclo THEN IF INKEY(47)=0 THEN counter=ciclo:GOSUB 580
550 |LOCATESP,31,y,x
560 RETURN

570 ' disparo nave ---------------
580 disp=1+disp MOD 2
590 |LOCATESP,28+disp,y,x+2:|SETUPSP,28+disp,0,169:|SETUPSP,28+disp,15,1:|SETUPSP,28+disp,9,18
600 SOUND 1,25,20,12,,5
610 RETURN

620 ' rutina disparo invaders ----
630 IF PEEK(27448)<>0 THEN RETURN
640 invader=RND*28:dirinvader=invader*16+27000
650 IF PEEK (dirinvader)=0 THEN RETURN
660 |LOCATESP,28,PEEK(dirinvader+1),PEEK(dirinvader+3):|SETUPSP,28,0,139:|SETUPSP,28,15,2
670 SOUND 1,250,20,12,,5
680 RETURN

690 ' GAME OVER
695 |SETUPSP,31,7,3:|SETUPSP,31,0,143:|LOCATESP,31,186,x
700 LOCATE 7,12:PEN 7:PRINT "GAME OVER"
701 for i=0 to 27:|setupsp,i,0,0:next
702 |PRINTSPALL
710 IF INKEY(47)<>0 THEN  702 ELSE RUN

730 ' rutina muerte nave
740 SOUND 7,1000,20,15,,,15
750 BORDER 7,0
760 |SETUPSP,31,7,3:|SETUPSP,31,0,143:|LOCATESP,31,186,x
770 |PRINTSPALL
780 IF INKEY(47)<>0 THEN  770
790 BORDER 1
800 GOTO 110


810 MODE 2: INK 0,0:PEN 1:BORDER 0: END


Por último os adjunto un video tutorial de programación del juego

hasta la vista!

viernes, 23 de diciembre de 2016

Cómo hacer un juego mini-pong en BASIC usando la libreria 8BP

hola amigos de 8BP

Os traigo un pequeño tutorial de introducción para hacer un juego tipo "pong" en unos minutos. El tutorial está disponible en el canal de vídeos de 8BP  https://www.youtube.com/channel/UCThvesOT-jLU_s8a5ZOjBFA


Y el juego "mini-pong" lo encontrareis en la carpeta "Game Examples" del proyecto Github en https://github.com/jjaranda13/8BP

Os adjunto aquí el listado del juego. Como complemento a las explicaciones del video os diré que la barra del oponente (el ordenador) comienza a tomar decisiones cuando la pelota sobrepasa la mitad del campo, por lo que es posible ganarle. Si le ponemos a tomar decisiones antes llega un momento que es imposible ganar.

Algunas pinceladas sobre el juego:
- COLSPALL : para detectar colisiones entre el "colisionador" (la pelota) y los "colisionados" (las barras). En el byte de estado de los sprites se activa el flag de colisionador para la pelota (sprite 29) y se activa el flag de colisionado en el 31 (nuestra barra) y el 30 (barra del oponente)
- Usa sobreescritura en la pelota para respetar la raya blanca del campo y no borrarla al pasar. Para ello se usa una paleta con sobreescritura y se activa el flag de sobreescritura en el byte de estado del sprite de la pelota (el 29)
- solo hay dos imágenes (la pelota=17 y la barra=16) que se asignan a los 2 sprites (a los sprites 30 y 31 se les asigna la imagen 16 y al sprite 29 se le asigna la imagen 17)
- los sprites usan movimiento automático. Para ello tienen activado el flag de movimiento automático y la instruccion AUTOALL los mueve (les cambia sus coordenadas) de acuerdo a su velocidad
- todos los sprites se imprimen con PRINTSPALL en cada ciclo de juego

Sin más, os dejo con el video tutorial y el listado del videojuego

felices fiestas!


10 MEMORY 25999
20 DEFINT A-Z: CALL &6B78:' install RSX
21 |PRINTSPALL,0,0:|AUTOALL,0:mode 0
22 on break gosub 2800
26 CALL &BC02:'restaura paleta por defecto     
27 INK 0,9
28 INK 1,26
29 INK 4,1
30 ink 6,20: ink 7,20
31 puntosplayer=0
32 puntoscomputer=0
33 LOCATE 5,1:PEN 7:PRINT puntosplayer
34 LOCATE 15,1:PEN 1:PRINT puntoscomputer
35 PLOT 320,0,1:DRAW 320,400: plot 0,300:draw 16,300:draw 16,100:draw 0,100:
36 plot 640,300:draw 640-16,300:draw 640-16,100:draw 640,100
37 border 0

40 'barra del jugador
41 |SETUPSP,31,9,16:|SETUPSP,31,0,11:|LOCATESP,31,80,4
50 ' pelota
51 |SETUPSP,29,9,17:|SETUPSP,29,0,41+64:|LOCATESP,29,90,38:vyp=1:vxp=1
52 collided=0:collider=0:|COLSP,32,30,31:|COLSP,34,4,0
53 |COLSPALL,@collider,@collided
60 'barra computer
61 |SETUPSP,30,9,16:|SETUPSP,30,0,11:|LOCATESP,30,80,74:|SETUPSP,30,5,0,0
62 yc=90
80 |PRINTSPALL
81 env 1,1,15,1,15,-1,1:SOUND 1,100,25,15,1:SOUND 1,100,25,15,1:SOUND 1,100,50,15,1
82 IF INKEY(47)<>0 THEN  82
83 SOUND 1,100,7,15

90 'ciclo de juego------------
100 GOSUB 220:'lectura teclado y movimiento barra
110 GOSUB 310:'pelota
120 GOSUB 410:'computer
130 |AUTOALL:|PRINTSPALL
140 GOTO 100

200 ' rutina de movimiento barra
220 IF INKEY(67)=0 THEN vy=-5:GOTO 250
230 IF INKEY(69)=0 THEN vy=5:GOTO 250
240 if vy>0 then vy=vy-1 else if vy<0 then vy=vy+1
250 |SETUPSP,31,5,vy
260 RETURN

300 ' rutina movimiento pelota
310 xp=PEEK(27467)
311 IF xp>6 THEN IF xp<70 THEN 345
320 IF xp>=80 THEN GOSUB 500: CLS:GOTO 33:'vxp=-vxp: REM AQUI HAY QUE HACER GOSUB GOL
321  |COLSPALL: IF collider=32 THEN 345
341 IF collided=31 THEN SOUND 1,200,7,15:IF vxp<0 THEN vxp=-vxp:IF vy>0 THEN IF vyp<4 THEN vyp=vyp+1 ELSE ELSE IF vy<0 THEN IF vyp>-4 THEN vyp=vyp-1
342 IF collided=30 THEN SOUND 1,200,7,15:|SETUPSP,30,5,0:IF vxp>0 THEN vxp=-vxp: IF vyp=0 THEN vyp=1
343 pongs=pongs+1: if pongs=10 then vxp=vxp*2
345 yp=PEEK(27465) 
346 IF yp<=16 THEN vyp=-vyp:SOUND 1,600,7,15 ELSE IF yp>=192 THEN vyp=-vyp: SOUND 1,600,7,15
347 |SETUPSP,29,5,vyp,vxp
350 RETURN

400 ' rutina movimiento computer
410 IF vxp<0 THEN RETURN:'|SETUPSP,30,5,0:return
411 IF xp<40 THEN RETURN 
420 |PEEK,27481,@yc: yc=yc+21
430 IF yc<yp-5 THEN vyc=5: GOTO 450
440 IF yc>yp+5 THEN vyc=-5: goto 450
441 if vyc>0 then vyc=vyc-1 else if vyc<0 then vyc=vyc+1
450 |SETUPSP,30,5,vyc
460 RETURN

500 ' rutina puntos
510 |PEEK,27467,@xp
511 IF xp>40 THEN puntosplayer=puntosplayer+1 ELSE puntoscomputer=puntoscomputer+1
512 pongs=0
520 RETURN

2800 MODE 2: INK 0,0:PEN 1: END

lunes, 19 de diciembre de 2016

Disponible versión V27 de la librería 8BP

hola amigos de 8 bits de poder

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:

   RINK,tinta_inicial, color1,color2, color3, color4, color4, color5, color6, color7,color 8

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



hasta la vista!!! y felices fiestas!





domingo, 30 de octubre de 2016

Nuevo videojuego "Nibiru"

Hola amigos de 8 bits de poder

ya esta disponible para descarga el videojuego "Nibiru", programado en BASIC y usando la librería 8BP , versión V26b
Lo encontrarás en la carpeta "GameExamples" de https://github.com/jjaranda13/8BP

El juego funciona en CPC464 y en CPC6128. tanto el archivo ".dsk" como el ".wav" están disponibles.

El juego pone a prueba muchas de las características de 8BP y de la técnica de programación de "lógicas masivas", y tiene detalles como un gráfico de carga lujoso y tres melodías durante el juego, así como una tabla de scores que no se pierde aunque reinicies el juego y otros aspectos técnicos avanzados como scroll paralax, rutas, macrosecuencias, etc. El listado BASIC ocupa poco mas de 16KB, de modo que aun sobrarían 10 KB para hacer un juego mucho mayor (con 8BP los juegos en BASIC pueden ocupar 26KB, sin contar gráficos ni música).



Eres el piloto de una nave destructora y debes vencer al planeta Nibiru y a su lider, "Gorgo", un reptil milenario casi invencible. Debes destruir a los pajaros galácticos que viven en sus lunas y una vez que llegues al planeta te debes enfrentar a sus peligros antes de poder luchar con Gorgo.

El Juego consiste en tres fases y utiliza el mecanismo de scroll de 8BP basado en el comando MAP2SP y también usa enrutamiento de sprites y macrosecuencias de animación. Todo desde BASIC! gracias a 8BP y a la técnica de "lógicas masivas".


Aaunque la impresión con sobreescritura sea mas lenta que la "normal", la segunda fase demuestra que aun así es posible un juego de arcade con sobreescritura. Música, scroll, detección de colisiones, sprites con sobreescritura, enrutamiento de sprites, todo a la vez es posible con 8BP


En la tercera fase podrás ver un scroll paralax, donde las montañas se mueven a diferente velocidad que el mar. impresionante, verdad? piensa que es un juego hecho en BASIC!!!



Pronto publicaré un articulo sobre como lo he programado, explicando algunos detalles técnicos. También actualizaré la documentación con esta información y nuevos consejos.

Os dejo con un vídeo del juego:


Hasta la próxima!!






domingo, 9 de octubre de 2016

Disponible versión V26 de la librería 8BP

Hola amigos de 8 bits de poder

Ya esta disponible la versión V26 de la librería 8BP. Como novedad mas importante ahora es compatible con WYZtracker 2.0.1.0, el cual funciona mucho mejor (no he detectado ningún bug en el player). La librería 8BP sigue ocupando lo mismo, apenas 6KB. Librería y manual actualizado esta disponible en https://github.com/jjaranda13/8BP


WYZ tracker es el secuenciador de música con el que puedes hacer tus músicas y hacerlas sonar dentro de tus juegos hechos con 8BP. El WYZtracker ha sido creado por el excelente programador Augusto Ruiz https://github.com/AugustoRuiz/WYZTracker



El nuevo player de WYZtracker ocupa algo mas de memoria y he tenido que hacer algunos ajustes en el mapa de memoria de 8BP

Las novedades en la V26 son :

  • El mapa de memoria de 8BP te sigue dejando libres 26KB para BASIC pero ahora la zona de memoria donde se almacena el mapa del mundo y la zona donde se almacena el layout es el mismo área. Ello implica que no se pueden usar ambas cosas a la vez (lo cual tiene mucho sentido porque un juego con scroll usa mapa del mundo y no layout y viceversa)
  • Puesto que en la V25 el área de memoria de las imágenes comenzaba con las secuencias y las rutas, cada vez que creabas una secuencia o una ruta, las imágenes se ensamblaban en otras direcciones y era un rollo consultar las direcciones cuando quieres usar las imágenes en los comandos |SETUPSP,#,9,image_address o bien |SETUPSQ. Por ello he creado una lista llamada IMAGE_LIST que se incluye en el fichero images_tujuego.asm y donde puedes apuntar imágenes que quieras usar desde esos comandos usando números constantes desde 16 hasta 255 y que no cambian aunque las imágenes se re-esamblen en direcciones diferentes. Esto facilita la vida al programador de BASIC
  • Ahora hay una opción nueva en el comando |MOVER. si indicas el sprite 32 (que no existe), entonces puedes definir las direcciones de memoria de las variables BASIC, de modo que en la siguiente invocación sin estos parámetros se usaran dichas variables. Esto aplica tanto a |MOVER como a |MOVERALL. Es decir MOVER,32,@dy,@dx la ventaja de este mecanismo es ahorrar paso de parámetros y así ganar un milisegundo en sprites que muevas con movimiento relativo

Vamos a ver un ejemplo que aparece en la demo juegosimple. Primeramente muestro un fragmento del fichero donde almacenas tus imágenes
IMAGE_LIST
;---------------------------------------------------------------------------------------------
; pondremos aqui una lista de las imagenes que queremos usar sin especificar la direccion de memoria desde basic
; de este modo el comando |SETUPSP,<id>,9,<address> se transforma en |SETUPSP,<id>,9,<numero>
; la ventaja de no usar direcciones de memoria en basic es que si ampliamos los graficos o se reensamblan en 
; direcciones diferentes, el numero que asignemos no cambiara
; NO tienen que tener todas un numero, solo aquellas que vamos a usar con |setupsp, id, 9,<num>
; se empiezan a numerar en 16
; podemos usar hasta 255 imagenes especificadas de este modo 
; no hace falta que la lista tenga 255 elementos. es de longitud variable, incluso puede estar vacia
;----------------------------------------------------------------------------------------------
dw SOLDADO_R0; 16
dw SOLDADO_R1;17
dw SOLDADO_R2;18
dw SOLDADO_L0;19
dw SOLDADO_L1;20
dw SOLDADO_L2;21

; ahora las imagenes
IMAGE0
;------ BEGIN SPRITE --------
SOLDADO_R0
db 6 ; ancho
db 24 ; alto
db 0 , 0 , 0 , 0 , 0 , 0 
db 0 , 0 , 0 , 0 , 0 , 0 
...

A continuación dos formas diferentes de crear secuencias en BASIC

60 |SETUPSQ,9,&839E,&8430,&84C2,&8430,0,0,0,0: REM soldado derecha    
70 |SETUPSQ,10,19,20,21,20,0,0,0,0: REM soldado izq

la segunda forma es mucho mas "clara" y tiene la ventaja de no requerir consultar las direcciones de memoria en las que se han ensamblado las imágenes. Se puede usar también en el comando |SETUPSP para especificar la imagen de un sprite (parámetro 9).

Por último tenemos la mejora en los comandos de movimiento relativo de sprites. 
Hay una forma de usar el comando |MOVER sin especificar ni “dy” ni “dx”. Para ello indicaremos el sprite 32, que no existe, y pondremos como parámetros las direcciones de memoria de las variables que queremos usar para almacenar tanto “dy” como a “dx”.
La dirección de memoria de una variable se obtiene simplemente anteponiendo el símbolo “@”

|MOVER,32,@dy,@dx

A partir de este momento podremos usar

|MOVER, id

Y con ello el sprite “id” se moverá según indiquen las variables dy, dx. Este mecanismo también funciona con |MOVERALL

Si no se especifican parámetros, se usarán las variables especificadas en la invocación de MOVER con sprite 32, es decir:

|MOVER,32,@dy,@dx
|MOVERALL

Es equivalente a |MOVERALL, dy, dx

Este uso “avanzado” del comando evita el paso de parámetros en cada invocación y por lo tanto es más rápido, lo cual es fundamental en nuestros programas BASIC

y de momento esto es todo en la V26. he actualizado el manual en español y poco a poco haré lo mismo con el de inglés.

hasta la vista!