Traducción terminada del Día 6, actualización del índice y documentos del Día 7 y Apéndice A añadidos.

This commit is contained in:
jota 2022-01-11 20:00:19 -03:00
parent 22323c4ab5
commit d0a1719f05
4 changed files with 509 additions and 49 deletions

View File

@ -51,7 +51,17 @@ también discutimos posibles estructuras para crear bucles y programas más comp
# día 6
¡proximamente!
aquí hablamos de cómo podemos integrar todo lo que hemos cubierto para crear subrutinas y programas más complejos para el ordenador varvara.
basamos nuestra discusión en una recreación del clásico juego pong.
además de utilizar estrategias y fragmentos de código anteriores, cubrimos estrategias para dibujar y controlar sprites de varios tiles, y para comprobar las colisiones.
{tutorial de uxn día 6}
# día 7
¡próximamente!
# índice tentativo

View File

@ -0,0 +1,3 @@
# apéndice A
¡proximamente! traducción en proceso. :)

View File

@ -45,7 +45,6 @@ empecemos con el siguiente programa como plantilla. incluye los datos para un sp
#01c0 .Sistema/g DEO2
#2ce5 .Sistema/b DEO2
BRK
@tile-fondo 1122 4488 1122 4488
@ -130,7 +129,7 @@ entremedio, podemos enviar nuestro byte de sprite para dibujar el tile.
&bucle-x
DUP2 .Pantalla/x DEO2 ( establecer coordenada x )
#03 .Pantalla/sprite DEO ( dibujar sprite de 1bpp con color 3 y 0 )
#0008 ADD2 ( incrementa x )
#0008 ADD2 ( incrementar x )
```
en este punto, la pila tiene la nueva x en la parte superior de la pila, y el ancho de la pantalla debajo.
@ -155,8 +154,8 @@ usando esta estrategia, obtendríamos el siguiente bucle:
#03 .Pantalla/sprite DEO ( dibujar sprite de 1bpp con color 3 y 0 )
#0008 ADD2 ( incrementa x )
GTH2k ( ¿es ese ancho mayor que x? aka ¿es x menor que el ancho? )
#0008 ADD2 ( incrementar x )
GTH2k ( ¿es ese ancho mayor que x? o también, ¿es x menor que el ancho? )
,&bucle-x JCN ( salta si x es menor que el límite )
POP2 POP2 ( eliminar x y el límite )
```
@ -197,8 +196,8 @@ lo siguiente muestra nuestro programa en contexto, llenando completamente la pri
&bucle-x
DUP2 .Pantalla/x DEO2 ( fijar coordenada x )
#03 .Pantalla/sprite DEO ( dibujar sprite de 1bpp con color 3 y 0 )
#0008 ADD2 ( incrementa x )
GTH2k ( ¿es ese ancho mayor que x? aka ¿es x menor que el ancho? )
#0008 ADD2 ( incrementar x )
GTH2k ( ¿es ese ancho mayor que x? o también, ¿es x menor que el ancho? )
,&bucle-x JCN ( salta si x es menor que el límite )
POP2 POP2 ( eliminar x y el límite )
BRK
@ -214,7 +213,7 @@ siguiendo la misma estrategia, podríamos hacer:
* dibujar la fila en y
* añadir 8 (el tamaño del tile) a y
* ¿es y menor que el límite? si lo es, repetir el procedimiento, en caso contrario terminar
* ¿es `y` menor que el límite? si lo es, repetir el procedimiento, en caso contrario terminar
### el bucle vertical
@ -232,17 +231,17 @@ podemos usar la misma estructura que antes, pero usando y:
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
.Pantalla/alto DEI2 MARGEN-PARED SUB2 ( establecer límite )
MARGEN-PARED ( establecer y inicial )
MARGEN-PARED ( establecer `y` inicial )
&bucle-y
DUP2 .Pantalla/y DEO2 ( establecer coordenada y )
( - dibujar fila aquí - )
#0008 ADD2 ( incrementa y )
GTH2k ( ¿es ese límite mayor que y? aka ¿es y menor que el límite? )
,&bucle-y JCN ( salta si y es menor que el límite )
POP2 POP2 ( eliminar "y" y el límite )
#0008 ADD2 ( )
GTH2k ( ¿es ese límite mayor que y? o también, ¿es `y` menor que el límite? )
,&bucle-y JCN ( salta si `y` es menor que el límite )
POP2 POP2 ( eliminar `y` y el límite )
```
### bucles anidados
@ -253,7 +252,7 @@ ahora que tenemos esta estructura, podemos sustituir el comentario "dibujar fila
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
.Pantalla/alto DEI2 MARGEN-PARED SUB2 ( establecer límite )
MARGEN-PARED ( establecer y inicial )
MARGEN-PARED ( establecer `y` inicial )
&bucle-y
DUP2 .Pantalla/y DEO2 ( establecer coordenada y )
@ -265,15 +264,15 @@ MARGEN-PARED ( establecer y inicial )
( dibujar sprite de 1bpp con color 3 y 0 )
#03 .Pantalla/sprite DEO
#0008 ADD2 ( incrementa x )
GTH2k ( ¿es ese ancho mayor que x? aka ¿es x menor que el ancho? )
#0008 ADD2 ( incrementar x )
GTH2k ( ¿es ese ancho mayor que x? o también, ¿es x menor que el ancho? )
,&bucle-x JCN ( salta si x es menor que el límite )
POP2 POP2 ( eliminar x y el límite )
#0008 ADD2 ( incrementa y )
GTH2k ( ¿es ese límite mayor que y? aka ¿es y menor que el límite? )
,&bucle-y JCN ( salta si y es menor que el límite )
POP2 POP2 ( eliminar y y el límite )
#0008 ADD2 ( )
GTH2k ( ¿es ese límite mayor que y? o también, ¿es `y` menor que el límite? )
,&bucle-y JCN ( salta si `y` es menor que el límite )
POP2 POP2 ( eliminar `y` y el límite )
```
observa cómo, al asegurarnos de que nuestro bucle interno deja limpia la pila al terminar, podemos ponerlo allí sin problemas: los valores correspondientes al bucle externo permanecen intactos en la pila.
@ -287,7 +286,7 @@ ahora podemos envolver estos bucles anidados dentro de una subrutina:
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
.Pantalla/alto DEI2 MARGEN-PARED SUB2 ( establecer límite )
MARGEN-PARED ( establecer y inicial )
MARGEN-PARED ( establecer `y` inicial )
&bucle-y
DUP2 .Pantalla/y DEO2 ( establecer coordenada y )
@ -299,15 +298,15 @@ ahora podemos envolver estos bucles anidados dentro de una subrutina:
( dibujar sprite de 1bpp con color 3 y 0 )
#03 .Pantalla/sprite DEO
#0008 ADD2 ( incrementa x )
GTH2k ( ¿es ese ancho mayor que x? aka ¿es x menor que el ancho? )
#0008 ADD2 ( incrementar x )
GTH2k ( ¿es ese ancho mayor que x? o también, ¿es x menor que el ancho? )
,&bucle-x JCN ( salta si x es menor que el límite )
POP2 POP2 ( eliminar x y el límite )
#0008 ADD2 ( incrementa y )
GTH2k ( ¿es ese límite mayor que y? aka ¿es y menor que el límite? )
,&bucle-y JCN ( salta si y es menor que el límite )
POP2 POP2 ( eliminar y y el límite )
#0008 ADD2 ( )
GTH2k ( ¿es ese límite mayor que y? o también, ¿es `y` menor que el límite? )
,&bucle-y JCN ( salta si `y` es menor que el límite )
POP2 POP2 ( eliminar `y` y el límite )
RTN
```
@ -387,7 +386,7 @@ pero añadamos también un byte de color para el byte del sprite:
recordemos que estamos utilizando la convención de añadir un signo de intercalación (^) después del nombre de un valor para indicar que es un corto, y un asterisco (*) para indicar que es un corto que funciona como un puntero (es decir, una dirección en la memoria del programa)
por un lado esta segunda versión nos permitiría cambiar de color cuando, por ejemplo, le demos a la bola, pero lo más importante es que esto nos permitirá limpiar la pala antes de moverla, como hemos hecho en días anteriores.
por un lado esta segunda versión nos permitiría cambiar de color cuando, por ejemplo, le demos a la pelota, pero lo más importante es que esto nos permitirá limpiar la pala antes de moverla, como hemos hecho en días anteriores.
en principio la subrutina debería ser sencilla: tenemos que establecer las coordenadas x e y de cada una de las fichas, relativas a las coordenadas x e y dadas, y dibujarlas con el color dado.
@ -424,7 +423,7 @@ adicionalmente, guardaré el color en la pila de retorno:
( guardar color )
STH
( establecer y y x iniciales )
( establecer `y` y x iniciales )
.Pantalla/y DEO2
.Pantalla/x DEO2
@ -518,7 +517,7 @@ un margen para separar las palas de los bordes podría ser agradable también:
%MARGEN { #0010 }
```
por último, recuperemos nuestra macro HALF2 de días anteriores:
por último, recuperemos nuestra macro MITAD2 de días anteriores:
```
%MITAD2 { #01 SFT2 } ( corto -- corto/2 )
@ -545,7 +544,7 @@ MARGEN SUB2 ANCHO-PALA SUB2
para centrar las coordenadas `y` podemos restar la altura de la pala a la altura de la pantalla, y luego dividir entre dos:
```
.Pantalla/alto DEI2 ALTO-PALA SUB2 HALF2
.Pantalla/alto DEI2 ALTO-PALA SUB2 MITAD2
DUP2
.izquierda/y STZ2
.derecha/y STZ2
@ -612,7 +611,7 @@ omitiendo la definición de las subrutinas dibuja-fondo y dibuja-pala, y como fo
.derecha/x STZ2
.Pantalla/alto DEI2 ALTO-PALA SUB2
HALF2 DUP2
MITAD2 DUP2
.izquierda/y STZ2
.derecha/y STZ2
@ -787,11 +786,11 @@ y luego en nuestra subrutina de configuración podemos asignarles valores, por e
( dentro de configuración )
( iniciar la pelota )
.Pantalla/ancho DEI2 TAM-PELOTA SUB2
HALF2
MITAD2
.pelota/x STZ2
.Pantalla/alto DEI2 TAM-PELOTA SUB2
HALF2
MITAD2
.pelota/y STZ2
```
@ -896,7 +895,7 @@ podemos hacer que la pelota se mueva hacia la derecha haciendo:
( dentro de actualiza-pelota )
.pelota/vel-x LDZ2 ( obtener vel-x )
.pelota/x LDZ2 ( obtener x )
ADD2 ( sumarlos )
ADD2 ( sumar ambas cosas )
.pelota/x STZ2 ( almacenar nueva x )
```
@ -969,7 +968,7 @@ y luego usamos exactamente el mismo código para actualizar la posición:
( dentro de actualiza-pelota )
.pelota/vel-x LDZ2 ( obtener vel-x )
.pelota/x LDZ2 ( obtener x )
ADD2 ( sumarlas )
ADD2 ( sumar ambas cosas )
.pelota/x STZ2 ( almacenar nueva x )
```
@ -990,12 +989,12 @@ basándonos en lo que acabamos de discutir, podemos empezar nuestra subrutina de
@actualiza-pelota ( -- )
( obtener velocidad-x y x )
.pelota/vel-x LDZ2 .pelota/x LDZ2
ADD2 ( sumarlos )
ADD2 ( sumar ambas cosas )
.pelota/x STZ2 ( guarda la nueva x )
( obtener velocidad-y e y )
.pelota/vel-y LDZ2 .pelota/y LDZ2
ADD2 ( sumarlos )
ADD2 ( sumar ambas cosas )
.pelota/y STZ2 ( almacenar nueva y )
RTN
```
@ -1006,9 +1005,9 @@ si complementamos nuestra rutina de configuración con las velocidades iniciales
( dentro de configuración )
( iniciar pelota )
.Pantalla/ancho DEI2 TAM-PELOTA SUB2
HALF2 .pelota/x STZ2
.pantalla/alto DEI2 TAM-PELOTA SUB2
HALF2 .pelota/y STZ2
MITAD2 .pelota/x STZ2
.Pantalla/alto DEI2 TAM-PELOTA SUB2
MITAD2 .pelota/y STZ2
( iniciar la velocidad de la pelota )
PELOTA-VEL-POS .pelota/vel-x STZ2
@ -1098,13 +1097,13 @@ nuestra subrutina de actualización de la pelota tiene el siguiente aspecto ahor
( actualizar x )
( obtener velocidad-x y x )
.pelota/vel-x LDZ2 .pelota/x LDZ2
ADD2 ( sumarlas )
ADD2 ( sumar ambas cosas )
.pelota/x STZ2 ( guardar la nueva x )
( actualizar y )
( obtener velocidad-y e y )
.pelota/vel-y LDZ2 .pelota/y LDZ2
ADD2 ( sumarlos )
ADD2 ( sumar ambas cosas )
.pelota/y STZ2 ( almacenar nueva y )
( comprueba las colisiones con las paredes )
@ -1121,7 +1120,7 @@ nuestra subrutina de actualización de la pelota tiene el siguiente aspecto ahor
&verif-pared-inf
.pelota/y LDZ2 TAM-PELOTA ADD2 ( y + tamaño de la pelota )
.pantalla/alto DEI2
.Pantalla/alto DEI2
MARGEN-PARED SUB2 ( altura - margen )
GTH2 ( ¿es la pelota-y mayor que la pared-y? )
,&establecer-vel-neg JCN
@ -1222,13 +1221,13 @@ todo el código x-en-izquierda terminaría pareciendo:
fin sería una etiqueta al final de la subrutina, y reset es una subrutina de la que hablaremos más adelante.
esta aproximación de comparar con 0000 es la más fácil, pero ten en cuenta que podría no funcionar si cambias la velocidad de la bola: podría ocurrir que cruzara la pared pero con una coordenada x que nunca fuera igual a 0.
esta aproximación de comparar con 0000 es la más fácil, pero ten en cuenta que podría no funcionar si cambias la velocidad de la pelota: podría ocurrir que cruzara la pared pero con una coordenada x que nunca fuera igual a 0.
realmente no podemos comprobar si la coordenada x es menor que 0, porque como hemos comentado anteriormente, eso sería en realidad un número cercano a ffff.
si comprobáramos que la coordenada x es menor que ffff, ¡entonces cada valor posible activaría la bandera de comparación!
este puede ser otro buen ejercicio para ti: ¿cómo comprobarías si la bola ha cruzado la pared izquierda independientemente de su velocidad?
este puede ser otro buen ejercicio para ti: ¿cómo comprobarías si la pelota ha cruzado la pared izquierda independientemente de su velocidad?
### pala derecha
@ -1238,7 +1237,7 @@ para la pala derecha haremos lo mismo que arriba, pero cambiando las comparacion
&verif-pala-der
.pelota/x LDZ2 TAM-PELOTA ADD2 ( pelota-x + tamaño-pelota )
.Pantalla/ancho DEI2 MARGEN SUB2 ANCHO-PALA SUB2
GTH2 ( ¿es la coordenada derecha de la bola mayor que el ancho de la pantalla - margen - ancho de la paleta? )
GTH2 ( ¿es la coordenada derecha de la pelota mayor que el ancho de la pantalla - margen - ancho de la pala? )
,&x-en-derecha JCN
&fin JMP
@ -1247,7 +1246,7 @@ para la pala derecha haremos lo mismo que arriba, pero cambiando las comparacion
.derecha/y LDZ2 TAM-PELOTA SUB2 GTH2 ( primera bandera ) STH
.derecha/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recupera la primera bandera )
AND ( juntar las dos banderas )
AND ( hacer AND en ambas banderas )
,&rebote-derecha JCN
.pelota/x LDZ2
@ -1256,7 +1255,7 @@ para la pala derecha haremos lo mismo que arriba, pero cambiando las comparacion
&reset-derecha
( aquí puedes aumentar la puntuación
de la paleta izquierda )
de la pala izquierda )
;reset JSR2
,&fin JMP
@ -1267,3 +1266,448 @@ para la pala derecha haremos lo mismo que arriba, pero cambiando las comparacion
&fin
RTN
```
¡eso debería ser todo! ¡puedes encontrar la subrutina de actualización de la pelota completa a continuación!
¡para poder ensamblar y ejecutar el juego, vamos a definir la subrutina reset!
## reset
aquí solo definiremos una subrutina de reinicio o "reset" que devuelva la pelota al centro de la pantalla sin alterar su velocidad:
```
@reset ( -- )
( iniciar pelota )
.Pantalla/ancho DEI2 TAM-PELOTA SUB2
MITAD2 .pelota/x STZ2
.Pantalla/alto DEI2 TAM-PELOTA SUB2
MITAD2 .pelota/y STZ2
RTN
```
sería interesante tener algún mecanismo para cambiar también la velocidad: tal vez basado en el conteo de cuadros, en la posición de las palas, o cualquier otra cosa que elijas.
# el programa completo
aquí está todo el código que hemos escrito hoy:
=> ./img/screencap_uxn-pong.gif animación que muestra el pong en acción: las palas se mueven, la pelota rebota en las paredes superior e inferior y en las palas, y la pelota se reinicia desde el centro cuando la pelota golpea cualquier lado.
## configuración
```
( hola-pong.tal )
( dispositivos )
|00 @Sistema [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ]
|20 @Pantalla [ &vector $2 &ancho $2 &alto $2 &auto $1 &pad $1
&x $2 &y $2 &direc $2 &pixel $1 &sprite $1 ]
|80 @Controlador [ &vector $2 &boton $1 &tecla $1 ]
( macros )
%RTN { JMP2r }
%MITAD2 { #01 SFT2 } ( corto -- corto/2 )
%DOBLE2 { #10 SFT2 }
( constantes )
%ANCHO-PALA { #0010 } ( 2 tiles )
%ALTO-PALA { #0018 } ( 3 tiles )
%COLOR-PALA { #c5 }
%VEL-PALA { #0001 }
%TAM-PELOTA { #0010 } ( 2 tiles )
%COLOR-PALA { #c5 }
%PELOTA-VEL-POS { #0001 }
%PELOTA-VEL-NEG { #ffff }
%COLOR-BORRAR { #40 }
%MARGEN { #0010 } ( izquierda y derecha )
%MARGEN-PARED { #0010 } ( arriba y abajo )
( página cero )
|0000
@izquierda [ &x $2 &y $2 ]
@derecha [ &x $2 &y $2 ]
@pelota [ &x $2 &y $2 &vel-x $2 &vel-y $2 ]
( configuración )
|0100
@configuracion ( -> )
( establecer colores del sistema )
#2ce9 .Sistema/r DEO2
#01c0 .Sistema/g DEO2
#2ce5 .Sistema/b DEO2
( establecer el vector de la pantalla )
;en-cuadro .Pantalla/vector DEO2
( dibujar fondo )
;dibujar fondo JSR2
( iniciar palas )
MARGEN .izquierda/x STZ2
.Pantalla/ancho DEI2
MARGEN SUB2 ANCHO-PALA SUB2
.derecha/x STZ2
.Pantalla/alto DEI2 ALTO-PALA SUB2
MITAD2 DUP2
.izquierda/y STZ2
.derecha/y STZ2
( iniciar pelota )
;reset JSR2
( iniciar velocidad de la pelota )
PELOTA-VEL-NEG .pelota/vel-x STZ2
PELOTA-VEL-POS .pelota/vel-y STZ2
BRK
```
## en-marco
```
@en-marco ( -> )
( borrar palas )
.izquierda/x LDZ2 .izquierda/y LDZ2 COLOR-BORRAR ;dibuja-pala JSR2
.derecha/x LDZ2 .derecha/y LDZ2 COLOR-BORRAR ;dibuja-pala JSR2
( borrar pelota )
COLOR-BORRAR ;dibuja-pelota JSR2
( actualizar palas )
;actualiza-palas JSR2
( actualizar pelota )
;actualiza-pelota JSR2
( dibujar palas )
.izquierda/x LDZ2 .izquierda/y LDZ2 COLOR-PALA ;dibuja-pala JSR2
.derecha/x LDZ2 .derecha/y LDZ2 COLOR-PALA ;dibuja-pala JSR2
( dibujar pelota )
COLOR-PELOTA ;dibuja-pelota JSR2
BRK
```
## reset
```
@reset ( -- )
( iniciar pelota )
.Pantalla/ancho DEI2 TAM-PELOTA SUB2
MITAD2 .pelota/x STZ2
.Pantalla/alto DEI2 TAM-PELOTA SUB2
MITAD2 .pelota/y STZ2
RTN
```
## relacionado con la pelota
### actualiza-pelota
```
@actualiza-pelota ( -- )
( obtener velocidad-x y x )
.pelota/vel-x LDZ2 .pelota/x LDZ2 ( obtener x )
ADD2 ( sumar ambas cosas )
.pelota/x STZ2 ( guardar la nueva x )
( obtener velocidad-y e y )
.pelota/vel-y LDZ2 .pelota/y LDZ2 ( obtener y )
ADD2 ( sumar ambas cosas )
.pelota/y STZ2 ( guardar la nueva y )
( comprobar colisiones con las paredes )
&verif-pared-sup
.pelota/y LDZ2
MARGEN-PARED
LTH2 ( ¿es la pelota-y menor que el margen? )
,&establecer-vel-pos JCN
,&verif-pared-inf JMP
&establecer-vel-pos
PELOTA-VEL-POS .pelota/vel-y STZ2
&continuar JMP
&verif-pared-inf
.pelota/y LDZ2 TAM-PELOTA ADD2 ( y + tamaño-pelota )
.Pantalla/alto DEI2 MARGEN-PARED SUB2 ( altura - margen )
GTH2
,&establecer-vel-neg JCN
,&continuar JMP
&establecer-vel-neg
PELOTA-VEL-NEG .pelota/vel-y STZ2
&continuar
( comprobar colisiones con las palas )
&verif-pala-izq
.pelota/x LDZ2
MARGEN ANCHO-PALA ADD2
LTH2 ( ¿es la pelota-x menor que el margen + ancho-pala? )
,&x-en-izquierda JCN
,&verif-pala-der JMP
&x-en-izquierda
.pelota/y LDZ2 DUP2
.izquierda/y LDZ2 TAM-PELOTA SUB2 GTH2 ( primera bandera ) STH
.izquierda/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recuperar la primera bandera )
AND ( hacer AND en ambas banderas )
,&rebote-izquierda JCN
.pelota/x LDZ2 #0000 NEQ2 ( ¿ha llegado a la pared? )
,&fin JCN
&reset-izquierda
( aquí puedes añadir un punto a la pala derecha )
;reset JSR2
,&fin JMP
&rebote-izquierda
PELOTA-VEL-POS .pelota/vel-x STZ2
,&fin JMP
&verif-pala-der
.pelota/x LDZ2 TAM-PELOTA ADD2
.Pantalla/ancho DEI2 MARGEN SUB2 ANCHO-PALA SUB2
GTH2 ( ¿es pelota-x + tamaño-pelota mayor que la anchura de la pantalla - margen - ancho-pala? )
,&x-en-derecha JCN
&fin JMP
&x-en-derecha
.pelota/y LDZ2 DUP2
.derecha/y LDZ2 TAM-PELOTA SUB2 GTH2 ( primera bandera ) STH
.derecha/y LDZ2 ALTO-PALA ADD2 LTH2 ( segunda bandera )
STHr ( recuperar la primera bandera )
AND ( hacer AND en ambas banderas )
,&rebote-derecha JCN
.pelota/x LDZ2
.Pantalla/ancho DEI2 NEQ2 ( ¿ha llegado a la pared? )
,&fin JCN
&reset-derecha
( aquí puedes añadir un punto a la pala izquierda )
;reset JSR2
,&fin JMP
&rebote-derecha
PELOTA-VEL-NEG .pelota/vel-x STZ2
,&fin JMP
&fin
RTN
```
### dibuja-pelota
```
@dibuja-pelota ( color -- )
( fijar x e y iniciales )
.pelota/x LDZ2 .Pantalla/x DEO2
.pelota/y LDZ2 .Pantalla/y DEO2
( dibujar tile 0 )
;pelota/sprite0 .Pantalla/direc DEO2
( el byte de color ya estaba en la pila )
DUP .Pantalla/sprite DEO
( mover a la derecha )
.Pantalla/x DEI2 #0008 ADD2 .Pantalla/x DEO2
( dibujar tile 1 )
;pelota-sprite/sprite1 .Pantalla/direc DEO2
DUP .Pantalla/sprite DEO
( mover hacia abajo )
.Pantalla/y DEI2 #0008 ADD2 .Pantalla/y DEO2
( dibujar tile 3 )
;pelota-sprite/tile3 .Pantalla/direc DEO2
DUP .Pantalla/sprite DEO
( mover a la izquierda )
.Pantalla/x DEI2 #0008 SUB2 .Pantalla/x DEO2
( dibujar tile 2 )
;pelota-sprite/tile2 .Pantalla/direc DEO2
.Pantalla/sprite DEO
RTN
```
## relacionado-a-palas
### actualiza-palas
```
@actualiza-palas ( -- )
&izquierda
( pala izquierda: botones arriba 10 y abajo 20 )
.Controlador/boton DEI
DUP #10 AND ( comprobar bit para arriba )
,&izquierda-arriba JCN
DUP #20 AND ( comprobar bit para abajo )
&izquierda-abajo JCN
&derecha JMP ( salta si no se ha pulsado ninguno de los dos )
&izquierda-arriba
.izquierda/y LDZ2 VEL-PALA SUB2 .izquierda/y STZ2
,&derecha JMP
&izquierda-abajo
.izquierda/y LDZ2 VEL-PALA ADD2 .izquierda/y STZ2
,&derecha JMP
&derecha
( pala derecha: botones ctrl/A 01 y alt/B 02 )
DUP #01 AND ( comprobar bit para A )
,&derecha-arriba JCN
DUP #02 AND ( comprobar bit para B )
&derecha-abajo JCN
&fin JMP ( salta si no se ha pulsado ninguno de los dos )
&derecha-arriba
.derecha/y LDZ2 VEL-PALA SUB2 .derecha/y STZ2
,&fin JMP
&derecha-abajo
.derecha/y LDZ2 VEL-PALA ADD2 .derecha/y STZ2
&fin
POP ( hacer POP al valor duplicado del botón )
RTN
```
## dibuja-pala
```
@dibuja-pala ( x^ y^ color -- )
( guardar color )
STH
( establecer `y` y x iniciales )
.Pantalla/y DEO2
.Pantalla/x DEO2
( dibujar tile 0 )
;pala-sprite/tile0 .Pantalla/direc DEO2
( copiar color de la pila de retorno: )
STHkr .Pantalla/sprite DEO
( añadir 8 a x: )
.Pantalla/x DEI2 #0008 ADD2 .Pantalla/x DEO2
( dibujar tile 1 )
;pala-sprite/tile1 .Pantalla/direc DEO2
STHkr .Pantalla/sprite DEO
( añadir 8 a y: )
.Pantalla/y DEI2 #0008 ADD2 .Pantalla/y DEO2
( dibujar tile 3 )
;pala-sprite/tile3 .Pantalla/direc DEO2
STHkr .Pantalla/sprite DEO
( restar 8 a x: )
.Pantalla/x DEI2 #0008 SUB2 .Pantalla/x DEO2
( dibujar tile 2 )
;pala-sprite/tile2 .Pantalla/direc DEO2
STHkr .Pantalla/sprite DEO
( añadir 8 a y: )
.Pantalla/y DEI2 #0008 ADD2 .Pantalla/y DEO2
( dibujar tile 4 )
;pala-sprite/tile4 .Pantalla/direc DEO2
STHkr .Pantalla/sprite DEO
( añadir 8 a x: )
.Pantalla/x DEI2 #0008 ADD2 .Pantalla/x DEO2
( dibujar tile 5 )
;pala-sprite/tile5 .Pantalla/direc DEO2
( obtener y no mantener el color de la pila de retorno: )
STHr .Pantalla/sprite DEO
RTN
```
## dibuja-fondo
```
@dibuja-fondo ( -- )
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
.Pantalla/alto DEI2 MARGEN-PARED SUB2 ( establecer límite )
MARGEN-PARED ( establecer `y` inicial )
&bucle-y
DUP2 .Pantalla/y DEO2 ( establecer coordenada `y` )
( dibujar fila )
.Pantalla/ancho DEI2 #0000 ( establecer límite `y` x inicial )
&bucle-x
DUP2 .Pantalla/x DEO2 ( fijar coordenada x )
#03 .Pantalla/sprite DEO ( dibujar sprite de 1bpp con color 3 y 0 )
#0008 ADD2 ( incrementar x )
GTH2k ( ¿es la anchura mayor que x? o también, ¿es x menor que la anchura? )
,&bucle-x JCN ( salta si x es menor que el límite )
POP2 POP2 ( eliminar x y el límite )
#0008 ADD2 ( incrementar y )
GTH2k ( ¿es el límite mayor que `y`? o también, ¿es `y` menor que el límite? )
,&bucle-y JCN ( salta si `y` es menor que el límite )
POP2 POP2 ( eliminar `y` y el límite )
RTN
```
## data
```
@tile-fondo 1122 4488 1122 4488
@pala-sprite
&tile0 [ 3f 7f e7 c3 c3 c3 c3 c3 00 00 18 3c 3c 3c 3c 3c ]
&tile1 [ fc fe ff ff ff ff ff ff 00 00 00 00 00 00 06 06 ]
&tile2 [ c3 c3 c3 c3 e7 ff ff ff 3c 3c 3c 3c 18 00 00 00 ]
&tile3 [ ff ff ff ff ff ff ff ff 06 06 06 06 06 06 06 06 ]
&tile4 [ ff ff ff ff ff ff 7f 3f 00 00 00 00 00 00 00 00 ]
&tile5 [ ff ff ff ff ff ff fe fc 06 06 06 06 06 1e 3c 00 ]
@pelota-sprite
&tile0 [ 03 0f 1f 39 70 70 f9 ff 00 00 00 06 0f 0f 06 00 ]
&tile1 [ c0 f0 f8 fc fe fe ff ff 00 00 00 00 08 0c 06 06 ]
&tile2 [ ff ff 7f 7f 3f 1f 0f 03 00 00 00 00 18 0f 01 00 ]
&tile3 [ ff ff fe fe fc f8 f0 c0 06 06 0c 1c 38 f0 c0 00 ]
```
¡wiuf! :)
# más posibilidades
aquí hay algunas posibilidades extra para que practiques y trates de implementar:
* contar y dibujar algún tipo de puntuación
* cambiar el color de la pelota y/o de la pala cuando chocan
* cambiar la dirección o el tipo de rebote dependiendo de la parte de la pala que golpea la bola
* iniciar el juego cuando se pulsa un botón
* posición "aleatoria" inicial de la pelota
* velocidad variable de la pelota y/o de las palas
* etc!
¡comparte lo que termines creando en base a todo esto! :)
# día 7
en el {tutorial de uxn día 7} hablamos de los dispositivos del ordenador varvara que aún no hemos cubierto: audio, archivo y fechatiempo o "datetime".
este debería ser un final ligero y tranquilo de nuestro recorrido, ya que tiene que ver menos con la lógica de programación y más con las convenciones de entrada y salida en estos dispositivos.
¡primero, te invito a tomar un descanso!
después, ¡sigue explorando y comparte tus descubrimientos!
# apoyo
si te ha gustado este tutorial y te ha resultado útil, considera compartirlo y darle tu {apoyo} :)

View File

@ -0,0 +1,3 @@
# día 7
¡proximamente! traducción en proceso. :)