From 7c6873603cd0f6186aaf4c09a58675c8914c069d Mon Sep 17 00:00:00 2001 From: jota Date: Sat, 30 Apr 2022 12:56:10 -0300 Subject: [PATCH] =?UTF-8?q?Traducci=C3=B3n=20de=20la=20actualizaci=C3=B3n:?= =?UTF-8?q?=20D=C3=ADa=202=20y=20D=C3=ADa=206?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tutorial_de_uxn_día_2.gmo | 14 +- src/tutorial_de_uxn_día_6.gmo | 292 ++++++++++++++++----------------- 2 files changed, 145 insertions(+), 161 deletions(-) diff --git a/src/tutorial_de_uxn_día_2.gmo b/src/tutorial_de_uxn_día_2.gmo index 450ad29..8b83847 100644 --- a/src/tutorial_de_uxn_día_2.gmo +++ b/src/tutorial_de_uxn_día_2.gmo @@ -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. diff --git a/src/tutorial_de_uxn_día_6.gmo b/src/tutorial_de_uxn_día_6.gmo index 09fb4a2..72a91cc 100644 --- a/src/tutorial_de_uxn_día_6.gmo +++ b/src/tutorial_de_uxn_día_6.gmo @@ -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: + ++ ++ ++ ++ ++ ++ ++
bitflag
3sin usar
2dirección automática
1auto y
0auto x
+& * 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 ```