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:
commit
1be7ceddcc
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
||||
|
|
Loading…
Reference in New Issue