martes, 11 de julio de 2017

Programando juegos en Amstrad con la libreria 8BP y Locomotive Basic

Hola amigos de 8BP

Últimamente estoy trabajando poco en mejoras a la librería pero tengo ya una nueva versión que publicaré en breve (V31), con un par de nuevas e interesantes mejoras. Además, he empezado un nuevo juego de arcade que espero que os guste.
Una de las mejoras es la posibilidad de tener un juego de minicaracteres redefinibles para mode 0, de modo que podamos imprimir textos, marcadores etc., a un tamaño razonable y a mucha mayor velocidad que el comando PRINT de Basic, permitiendo que, por ejemplo, un texto pueda salir botando por la pantalla, o imprimir puntuaciones de un juego sin provocar esas indeseables pausas que provoca el comando PRINT. También ando trasteando con pseudo3D, a ver hasta donde llegamos.

Hoy os traigo un vídeo recientemente publicado por Retromadrid. Se trata de la conferencia que hice el día 29 de abril titulada "programando juegos en Amstrad con la librería 8BP y Locomotive Basic".

Además, he subido la presentación (powerpoint y pdf) de la conferencia a github (https://github.com/jjaranda13/8BP). La encontraréis en la carpeta de "documentacion", así como el folleto. De este modo podréis seguir y entender con mas claridad la conferencia. La presentación es un fichero muy pesado, de unos 72MB, porque incluye vídeos embebidos. Es muy completa, pero no es larga ni complicada.

Agradezco desde aquí a los amigos y organizadores de Retromadrid la oportunidad brindada para compartir esta iniciativa con los amantes de lo retro.





un abrazo y feliz verano!


lunes, 1 de mayo de 2017

8 BITS DE PODER estuvo en Retromadrid 2017

Hola amigos de 8 bits de poder


Así es, 8BP estuvo en Retromadrid. Una experiencia inolvidable. Un reencuentro con el significado de la palabra "juego", desprovista del gran poder computacional actual. Donde la palabra "jugabilidad" no se mezcla con gráficos en alta resolución ni sonido de alta fidelidad ni memorias gigantescas. Una vuelta a los orígenes. A la esencia de lo que significa "jugar"

Sistemas retro de toda clase, expositores de altísimo nivel, pasión desbordada, aroma a Z80, 6502 y 68000, emoción y calidad. Encuentros con representantes de la escena retro y con un público entrañable que daba una gran energía al acontecimiento. Gracias a Javy, Atila, Jose, Cesar...y tantos que nos habéis dado esta acogida tan cálida.  En una palabra, Retromadrid ha sido magnífico.



El Sábado, presenté una conferencia sobre 8BP en la que se mostraron los fundamentos y posibilidades de esta herramienta, ejemplos y explicaciones sobre lógicas masivas, manejo de sprites, layout, sobreescritura, técnicas de scroll y recomendaciones de programación.



La conferencia se apoyó en una presentación y diversos vídeos. La presentación la subiré al repositorio github de 8bp , para complementar el manual. Me consta que fue grabada en vídeo, de modo que cuando sea publicado dicho vídeo os lo haré saber.

Agenda de la conferencia sobre 8BP

Folleto que fue repartido entre los visitantes
El folleto lo podéis encontrar en este link : folleto_8BP_retromadrid
Y en primicia, se presentó sobre un CPC464 real, el nuevo juego "fresh fruits & vegetables". Un juego de plataformas, donde tu misión consiste en recoger todas las frutas para dejar a la población sin nada que comer, de modo que tengan que sacrificar a un pobre cerdo para alimentarse. Tanto "fresh fruits & vegetables" como "Nibiru" fueron expuestos para el disfrute de grandes y pequeños durante todo el dia
juegos hechos con 8BP sobre un CPC464 real durante Retromadrid


Os dejo con el video del nuevo juego "Fresh fruits & vegetables" que encontrareis en el directorio "gameExamples" del repositorio GitHub de 8BP, en https://github.com/jjaranda13/8BP





hasta la vista!!!



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!