Merge pull request 'Traducción de la actualización: Día 2 y Día 6' (#11) from jotaemese/compudanzas:traducción_tutorial_de_uxn_día_6 into main

Reviewed-on: https://codeberg.org/sejo/compudanzas/pulls/11
This commit is contained in:
sejo 2022-04-30 20:42:08 +02:00
commit 1be7ceddcc
2 changed files with 145 additions and 161 deletions

View File

@ -209,28 +209,28 @@ como recapitulación: mencionamos que el dispositivo de pantalla solo puede most
¡ahora hablemos del dispositivo de pantalla y empecemos a usarlo!
## entradas y salidas
## puertos de dispositivo
en los programas uxntal para el ordenador varvara puedes encontrar las etiquetas correspondientes a este dispositivo de la siguiente manera:
en los programas uxntal para el ordenador varvara puedes encontrar las etiquetas correspondientes a los puertos de este dispositivo de la siguiente manera:
```
|20 @Pantalla [ &vector $2 &ancho $2 &alto $2 &pad $2 &x $2 &y $2 &direc $2 &píxel $1 &sprite $1 ]
|20 @Pantalla [ &vector $2 &ancho $2 &alto $2 &auto $1 &pad $1 &x $2 &y $2 &direc $2 &píxel $1 &sprite $1 ]
```
las entradas que podemos leer de este dispositivo son:
estos son los puertos en formato de lista:
* vector (2 bytes)
* anchura de la pantalla (2 bytes)
* altura de la pantalla (2 bytes)
y los puertos de salida de este dispositivo son:
* auto (1 byte)
* coordenada x (2 bytes)
* coordenada y (2 bytes)
* dirección de memoria (2 bytes)
* píxel (1 byte)
* sprite (1 byte)
hablaremos sobre el corto vector en el {tutorial de uxn día 4} y sobre el byte auto en el {tutorial de uxn día 6}.
## primer plano y plano de fondo
el dispositivo de pantalla tiene dos capas superpuestas del mismo tamaño, el primer plano y el plano de fondo.

View File

@ -4,7 +4,7 @@ esta es la sexta sección del {tutorial de uxn}! aquí hablamos de cómo podemos
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.
además de utilizar estrategias y fragmentos de código anteriores, cubrimos estrategias para dibujar y controlar sprites de varios tiles con el byte auto de pantalla y para comprobar las colisiones.
# lógica general
@ -16,6 +16,8 @@ abordaremos los siguientes elementos en orden:
* dibujo y movimiento de las palas
* dibujo y rebote de la pelota
antes de adentrarnos en dibujar las palas y la pelota vamos a cubrir el byte auto de pantalla que mencionamos en el {tutorial de uxn día 2}, pues nos ayudara a dibujar estos elementos.
# dibujando el fondo: repitiendo un tile
en el {tutorial de uxn día 5} hablamos de una forma de crear un bucle para repetir un tile de 1bpp varias veces seguidas.
@ -324,6 +326,96 @@ en el {tutorial de uxn apéndice a} puedes encontrar una discusión detallada de
se habla de varias posibilidades para usar uxntal de esa manera abstracta: yo diría que es muy interesante, pero está definitivamente fuera del alcance para hacer el juego :)
# el byte auto de pantalla
el byte auto de pantalla es una característica avanzada del dispositivo de pantalla que nos permite dibujar fácilmente múltiples sprites con una sola llamada.
no lo cubrimos en el {tutorial de uxn día 2} para evitar añadir más complejidad, y también porque realmente brilla cuando se utiliza el modo mantener que acabamos de discutir en el {tutorial de uxn día 5}.
# campos
el nibble izquierdo del byte corresponde a la longitud del byte auto.
los cuatro bits restantes, numerados de derecha a izquierda y de 0 a 3, son banderas que indican lo siguiente:
+ <table>
+ <tr><th>bit</th><th>flag</th></tr>
+ <tr><td class="num">3</td><td>sin usar</td></tr>
+ <tr><td class="num">2</td><td>dirección automática</td></tr>
+ <tr><td class="num">1</td><td>auto y</td></tr>
+ <tr><td class="num">0</td><td>auto x</td></tr>
+ </table>
& * 3: sin usar
& * 2: dirección automática
& * 1: auto y
& * 0: auto x
## incrementando la posición
la primera aplicación del byte auto de pantalla es incrementar automáticamente las coordenadas x o y del dispositivo de pantalla después de dibujar un sprite.
### sin el byte auto
por ejemplo, sin el byte auto, si quisiéramos dibujar un sprite justo a la derecha de otro, haríamos algo como lo siguiente, leyendo la coordenada x de la pantalla, incrementándola, y luego guardándola de nuevo:
```
;cuadrado .Pantalla/direc DEO2 ( establecer dirección del sprite )
#41 .Pantalla/sprite DEO ( dibujar sprite )
( incrementar Pantalla/x por 8 píxeles: )
.Pantalla/x DEI2 #0008 ADD2 .Pantalla/x
#41 .Pantalla/sprite DEO ( dibujar sprite de nuevo )
```
la operación para incrementar la Pantalla x es sencilla, pero es tan común que el byte auto la internaliza.
## sin el byte autom
para replicar el mismo comportamiento podemos activar la bandera auto x, y en su lugar hacer:
```
;cuadrado .Pantalla/direc DEO2 ( establecer dirección del sprite )
( establecer byte auto: auto x )
#01 .Pantalla/auto
#41 .Pantalla/sprite DEO ( dibujar sprite )
#41 .Pantalla/sprite DEO ( dibujar sprite de nuevo )
```
si no hubiéramos puesto el auto byte las dos últimas líneas serían redundantes. sin embargo, ahora que lo hemos incluido, cada una de ellas dibuja un tile en una posición diferente.
### byte auto y modo mantener
notemos cómo en el código anterior estamos empujando en la pila (dos veces) el color y la dirección del puerto del sprite de la pantalla.
¡con el modo mantener podemos usar esos valores pero sin sacarlos de la pila!
por lo tanto, las dos últimas líneas del ejemplo anterior podrían ser escritas en su lugar usando DEOk:
```
#41 .Pantalla/sprite DEOk ( dibujar sprite y mantener valores )
DEO ( dibujar sprite de nuevo )
```
## incrementando la dirección
como veremos con las palas y la pelota del juego, en muchas ocasiones tiene sentido dibujar sprites formados por varios tiles.
adicionalmente, tiene sentido almacenar estos tiles contiguamente en memoria, como hemos hecho antes.
la bandera de dirección auto nos permitirá incrementar el corto de la dirección de pantalla para que apunte a la siguiente dirección en memoria del tile que se acaba de dibujar.
si lo que dibujamos fue un tile de 1bpp, la dirección se incrementará en 8 bytes, y si dibujamos un tile de 2bpp la dirección se incrementará en 16 bytes.
## múltiples sprites
por último, el campo de longitud del byte auto nos permitirá establecer cuántos sprites extra, además del original, queremos dibujar en una fila.
¡para reiterar, con las palas y la pelota de abajo veremos como todos estos campos pueden ser aplicados para dibujar sprites multi-tile!
# las palas
podemos pensar en las dos palas del juego como dos rectángulos, cada uno con sus propias coordenadas x e `y` y ambos con la misma anchura y altura.
@ -390,18 +482,7 @@ por un lado esta segunda versión nos permitiría cambiar de color cuando, por e
en principio la subrutina debería ser directa: 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.
hay muchas maneras de hacerlo, dependiendo del gusto.
podríamos por ejemplo dibujar los tiles en el siguiente orden, con las siguientes operaciones:
* dibujar el tile 0, luego añadir 8 a x
* dibujar el tile 1, luego añadir 8 a y
* dibujar el tile 3, luego restar 8 a x
* dibujar el tile 2, luego añadir 8 a y
* dibujar el tile 4, luego añadir 8 a x
* dibujar el tile 5
o podríamos hacerlo de forma más tradicional:
si no quisiéramos utilizar el byte auto de pantalla podríamos hacer algo como lo siguiente:
* dibujar el tile 0, luego añadir 8 a x
* dibujar el tile 1, luego restar 8 a x y añadir 8 a `y`
@ -410,13 +491,9 @@ o podríamos hacerlo de forma más tradicional:
* dibujar el tile 4, luego añadir 8 a x
* dibujar el tile 5
en lugar de restar podríamos recuperar x de la pila de retorno, o de una variable relativa.
sin embargo, como ese enfoque u otros similares implicarían muchas operaciones tiene sentido utilizar el byte auto.
una posible ventaja de ir en orden es que podemos incrementar la dirección del sprite por 10 (16 en decimal) para llegar a la dirección del siguiente tile. para esto, o para los cambios de coordenadas, podemos aprovechar el byte auto de la pantalla.
sin embargo, en este caso voy a ir por la primera opción y voy a establecer manualmente la dirección para cada tile.
adicionalmente, guardaré el color en la pila de retorno:
es posible considerar formas más eficientes de dibujarla. por ejemplo, podríamos tener un dibuja-sprite generalizado que reciba la dirección inicial de un conjunto de tiles y la anchura y altura en términos de número de tiles:
```
@dibuja-pala ( x^ y^ color -- )
@ -427,52 +504,25 @@ adicionalmente, guardaré el color en la pila de retorno:
.Pantalla/y DEO2
.Pantalla/x DEO2
( dibujar tile 0 )
;pala/tile0 .Pantalla/direc DEO2
( copiar color de la pila de retorno: )
STHkr .Pantalla/sprite DEO
( establecer la primera dirección del sprite)
;pala-sprite .Pantalla/direc DEO2
( añadir 8 a x: )
.Pantalla/x DEI2 #0008 ADD2 .Pantalla/x DEO2
( auto byte: largo: +1 sprite )
( establecer dirección auto y auto `y` )
#16 .Pantalla/auto DEO
( dibujar tile 1 )
;pala/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/tile3 .Pantalla/direc DEO2
STHkr .Pantalla/sprite DEO
( sub 8 a x: )
.Pantalla/x DEI2 #0008 SUB2 .Pantalla/x DEO2
( dibujar tile 2 )
;pala/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/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/tile5 .Pantalla/direc DEO2
( obtener y no mantener el color de la pila de retorno: )
STHr .Pantalla/sprite DEO
( obtener el color de la pila de retorno: )
STHr
( dibujar tres filas: )
.Pantalla/sprite DEOk DEOk DEO
RTN
```
¡eso es todo!
ahora podemos llamarlo, por ejemplo, de la siguiente manera y obtener nuestra pala dibujada:
notemos el uso del modo mantener al final: DEOk enviará el color al puerto de sprites de la pantalla, pero mantendrá ambos parámetros en la pila para que podamos reutilizarlos.
ahora que la subrutina está lista podemos llamarla, por ejemplo, de la siguiente manera y conseguir que se dibuje nuestra pala:
```
#0008 #0008 #c5 ;dibuja-pala JSR2
@ -480,16 +530,6 @@ ahora podemos llamarlo, por ejemplo, de la siguiente manera y obtener nuestra pa
=> ./img/screenshot_uxn-pong-paddle.png captura de pantalla de la pala dibujada sobre el fondo
es posible considerar formas más eficientes de dibujarla. por ejemplo, podríamos tener un dibuja-sprite generalizado que reciba la dirección inicial de un conjunto de tiles y la anchura y altura en términos de número de tiles:
```
@dibuja-sprite ( x^ y^ ancho alto direc* color )
```
crear eso podría ser un buen ejercicio para probar! en este caso me mantendré con el método manual.
lo bueno de que este proceso esté en una subrutina es que podemos "olvidarnos" de su funcionamiento interno y simplemente usarlo :)
## variables y constantes para las palas
reservemos un espacio en la página cero para las coordenadas x e `y` de cada pala.
@ -804,35 +844,23 @@ hagamos que la subrutina reciba el color como argumento, para poder borrar la pe
.pelota/x LDZ2 .Pantalla/x DEO2
.pelota/y LDZ2 .Pantalla/y DEO2
( dibujar tile 0 )
;pelota-sprite/tile0 .Pantalla/direc DEO2
( el byte de color ya estaba en la pila )
DUP .Pantalla/sprite DEO
( establecer dirección del sprite)
;pelota-sprite .Pantalla/direc DEO2
( mover a la derecha )
.Pantalla/x DEI2 #0008 ADD2 .Pantalla/x DEO2
( byte auto: dibujar +1 sprite )
( establecer dirección auto y auto `y` )
#16 .Screen/auto DEO
( dibujar tile 1 )
;pelota-sprite/tile1 .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
( establecer el color desde la pila de trabajo: )
.Pantalla/sprite
( dibujar dos filas: )
DEOk DEO
RTN
```
para dibujarla, solo tendríamos que hacer:
¡notemos que estamos utilizando un enfoque muy similar al de la subrutina "dibujar-palas"!
para dibujarla solo tendríamos que hacer:
```
( dibujar pelota )
@ -1510,31 +1538,17 @@ RTN
.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
( establecer dirección del sprite )
;pelota-sprite .Pantalla/direc DEO2
( mover a la derecha )
.Pantalla/x DEI2 #0008 ADD2 .Pantalla/x DEO2
( byte auto: dibujar +1 sprite )
( establecer dirección auto y auto `y` )
#16 .Pantalla/auto DEO
( 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
( establecer el color desde la pila de trabajo: )
.Pantalla/sprite
( dibujar dos filas: )
DEOk DEO
RTN
```
@ -1591,47 +1605,17 @@ RTN
( establecer `y` y x iniciales )
.Pantalla/y DEO2
.Pantalla/x DEO2
( establecer dirección del sprite )
;pala-sprite .Pantalla/direc DEO2
( dibujar tile 0 )
;pala-sprite/tile0 .Pantalla/direc DEO2
( copiar color de la pila de retorno: )
STHkr .Pantalla/sprite DEO
( byte auto: largo: +1 sprite )
( establecer dirección auto y auto `y` )
#16 .Pantalla/auto 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
( obtener el color de la pila de trabajo: )
STHr .Pantalla/sprite
( dibujar tres filas: )
DEOk DEOk DEO
RTN
```