forked from sejo/compudanzas
Revisión pausada del Día 5 y 6, y correciones breves de otros Días
This commit is contained in:
parent
cc10cd9624
commit
bb7925f997
|
@ -184,7 +184,7 @@ podemos escribirlo de la siguiente manera:
|
|||
|
||||
( programa principal )
|
||||
|0100
|
||||
( establecer colores del sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
@ -322,7 +322,7 @@ el programa completo se vería de la siguiente manera:
|
|||
|
||||
( programa principal )
|
||||
|0100
|
||||
( establecer colores del sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
@ -661,7 +661,7 @@ además, 5, 'a' y 'f' en el nibble bajo dibujarán los píxeles que están "ence
|
|||
|
||||
( programa principal )
|
||||
|0100
|
||||
( establecer colores del sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
@ -703,7 +703,7 @@ el siguiente código dibujará nuestro sprite cuadrado con las 16 combinaciones
|
|||
|
||||
( programa principal )
|
||||
|0100
|
||||
( establecer colores de sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
@ -934,7 +934,7 @@ el siguiente código mostrará nuestro sprite en las 16 diferentes combinaciones
|
|||
|
||||
( programa principal )
|
||||
|0100
|
||||
( establecer colores de sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
|
|
@ -91,7 +91,7 @@ este utiliza el procedimiento de dibujo de sprites que probamos el día anterior
|
|||
|
||||
( programa principal )
|
||||
|0100
|
||||
( establecer colores del sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
@ -640,7 +640,7 @@ observa el uso de las máscaras AND, los saltos condicionales y algunas operacio
|
|||
|
||||
( programa principal )
|
||||
|0100
|
||||
( establecer colores del sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
esta es la quinta sección del {tutorial de uxn}! aquí introducimos el dispositivo de ratón varvara para explorar más posibles interacciones, y cubrimos los elementos restantes de uxntal y uxn: la pila de retorno, el modo de retorno y el modo mantener.
|
||||
|
||||
también discutimos posibles estructuras para crear bucles y programas más complejos utilizando estos recursos.
|
||||
¡también discutimos posibles estructuras para crear bucles y programas más complejos utilizando estos recursos!
|
||||
|
||||
# el dispositivo del ratón
|
||||
|
||||
|
@ -20,7 +20,7 @@ vemos este dispositivo definido en uxntal de la siguiente manera:
|
|||
|
||||
el byte de estado codifica el estado de activación/desactivación de hasta 8 botones del ratón; uno por bit.
|
||||
|
||||
contando de derecha a izquierda, el primer bit corresponde al primer botón del ratón, el segundo al segundo, y así sucesivamente.
|
||||
contando de derecha a izquierda, el primer bit corresponde al primer botón del ratón, el segundo bit al segundo botón del ratón, y así sucesivamente.
|
||||
|
||||
normalmente, en un ratón de tres botones, el primer botón es el izquierdo, el segundo el del medio y el tercero el derecho.
|
||||
|
||||
|
@ -38,9 +38,9 @@ nota que al igual que el dispositivo controlador, este sistema nos permite compr
|
|||
* 06 cuando se pulsan el segundo y el tercer botón
|
||||
* 07 cuando se pulsan los tres botones
|
||||
|
||||
recuerda que podemos utilizar las máscaras AND, tal y como se introdujo en {tutorial de uxn día 3}, para aislar y evaluar por separado cualquiera de estos bits.
|
||||
recuerda que podemos utilizar las máscaras AND, tal y como se introdujo en el {tutorial de uxn día 3}, para aislar y evaluar por separado cualquiera de estos bits.
|
||||
|
||||
## shorts de desplazamiento
|
||||
## cortos de desplazamiento
|
||||
|
||||
el dispositivo del ratón tiene un par de cortos para indicar si el ratón se está desplazando.
|
||||
|
||||
|
@ -55,6 +55,7 @@ del mismo modo, despx indicará un desplazamiento horizontal
|
|||
* 0001 cuando se desplaza hacia la derecha
|
||||
* ffff cuando se desplaza hacia la izquierda
|
||||
* 0000 cuando no se desplaza
|
||||
|
||||
dependiendo del dispositivo, los valores pueden ser mayores que 0001 o menores que ffff dependiendo de la velocidad de desplazamiento.
|
||||
|
||||
## vector ratón
|
||||
|
@ -73,7 +74,7 @@ el vector del ratón se disparará en cualquiera de los siguientes eventos:
|
|||
el siguiente es un ejemplo simple que ilustra el uso de los siguientes elementos:
|
||||
|
||||
* vector del ratón
|
||||
* coordenadas x e y del ratón
|
||||
* coordenadas x e `y` del ratón
|
||||
* estado del ratón (pulsado o no pulsado)
|
||||
|
||||
combinado con un condicional y el dibujo de un sprite.
|
||||
|
@ -92,7 +93,7 @@ dibuja nuestro cuadrado en la posición del ratón, cambiando su color cuando se
|
|||
|
||||
( init )
|
||||
|0100
|
||||
( establecer colores del sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
@ -164,7 +165,7 @@ este es un programa que logra dibujar el puntero en la pantalla
|
|||
|
||||
( init )
|
||||
|0100
|
||||
( establecer colores del sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
@ -200,7 +201,7 @@ BRK
|
|||
@puntero_icn [ 80c0 e0f0 f8e0 1000 ]
|
||||
```
|
||||
|
||||
nótese que dibuja el puntero en primer plano, y que utiliza 'a' en el nibble bajo del byte del sprite: esto implica que utilizará el color 2 para dibujar la forma del puntero, y dibujará con transparencia el resto del tile. ( ver dibujar sprites de 1bpp en {tutorial de uxn día 2} )
|
||||
nótese que dibuja el puntero en primer plano, y que utiliza 'a' en el nibble bajo del byte del sprite: esto implica que utilizará el color 2 para dibujar la forma del puntero, y dibujará con transparencia el resto del tile. ( ver dibujar sprites de 1bpp en el {tutorial de uxn día 2} )
|
||||
|
||||
este modo de mezcla te permitiría dibujar cosas en el plano de fondo y que el puntero las cubra sólo con su forma, y no con todo el cuadrado del tile.
|
||||
|
||||
|
@ -216,7 +217,7 @@ eso es aun mas cierto si consideramos que solo estamos dibujando el puntero, y n
|
|||
|
||||
crear una macro para todo este código podría ser posible, pero también poco práctico debido a la cantidad de código.
|
||||
|
||||
¿tal vez podríamos tener un JMP a otra sección del programa, que al final tiene otro JMP para volver a la posición correspondiente en la subrutina en-raton?
|
||||
¿tal vez podríamos tener un JMP a otra sección del programa, que al final tiene otro JMP para c vnm a la posición correspondiente en la subrutina en-raton?
|
||||
|
||||
de hecho, eso es casi lo que haremos, pero con un elemento adicional de uxn: ¡su pila de retorno!
|
||||
|
||||
|
@ -298,12 +299,12 @@ o un salto absoluto:
|
|||
BRK
|
||||
```
|
||||
|
||||
la cosa es que si queremos que ocurra algo más después de dibujar el puntero dentro de en-raton, no podemos volver atrás fácilmente.
|
||||
el detalle esta en que si queremos que ocurra algo más después de dibujar el puntero dentro de en-raton, no podemos atrás fácilmente.
|
||||
|
||||
al final de nuestra subrutina dibuja-puntero, necesitaríamos "saltar hacia atrás" así
|
||||
al final de nuestra subrutina dibuja-puntero, necesitaríamos "saltar hacia atrás" así:
|
||||
|
||||
```
|
||||
;en-raton/volver JMP2
|
||||
;en-raton/retornar JMP2
|
||||
```
|
||||
|
||||
funcionaría, pero no es la mejor forma.
|
||||
|
@ -338,12 +339,11 @@ y en el caso de un salto absoluto:
|
|||
@en-raton ( -> )
|
||||
;dibuja-puntero JSR2
|
||||
|
||||
|
||||
( algo más aquí )
|
||||
BRK
|
||||
```
|
||||
|
||||
## volviendo
|
||||
## retornando
|
||||
|
||||
JSR está empujando la "dirección de retorno" hacia la pila de retorno.
|
||||
|
||||
|
@ -379,11 +379,11 @@ LIT2r 0102 ADDr
|
|||
|
||||
ahora volvamos a nuestros saltos :)
|
||||
|
||||
## saltando al retorno
|
||||
## saltando a retorno
|
||||
|
||||
como ya hemos discutido, JMP nos permitirá saltar incondicionalmente a la dirección dada en la parte superior de la pila (de trabajo).
|
||||
|
||||
JSR o JSR2 empujan hacia abajo en la pila de retorno la dirección absoluta de la siguiente instrucción, un short, para que eventualmente podamos retornar allí.
|
||||
JSR o JSR2 empujan hacia abajo en la pila de retorno la dirección absoluta de la siguiente instrucción, un corto, para que eventualmente podamos retornar allí.
|
||||
|
||||
¿cómo podemos saltar incondicionalmente a esa dirección absoluta que está presente en la pila de retorno?
|
||||
|
||||
|
@ -391,19 +391,19 @@ JSR o JSR2 empujan hacia abajo en la pila de retorno la dirección absoluta de l
|
|||
|
||||
¡activando el modo de retorno en la instrucción JMP!
|
||||
|
||||
adicionalmente, como las direcciones empujadas por JSR son shorts, necesitamos activar el modo short también:
|
||||
adicionalmente, como las direcciones empujadas por JSR son cortos, necesitamos activar el modo corto también:
|
||||
|
||||
```
|
||||
JMP2r ( saltar a la dirección absoluta en la parte superior de la pila de retorno )
|
||||
```
|
||||
|
||||
en muchos programas uxntales verás esta instrucción escrita como una macro, RTN ( volver o "return" )
|
||||
en muchos programas uxntal verás esta instrucción escrita como una macro, RTN ( retornar o "return" ):
|
||||
|
||||
```
|
||||
%RTN { JMP2r }
|
||||
```
|
||||
|
||||
podemos terminar una subrutina usando esta macro para "volver" a la posición en el programa después del JSR correspondiente.
|
||||
podemos terminar una subrutina usando esta macro para "retornar" a la posición en el programa después del JSR correspondiente.
|
||||
|
||||
## ejemplo completo usando subrutinas
|
||||
|
||||
|
@ -426,7 +426,7 @@ este es el programa hola-puntero.tal, pero utilizando dibuja-puntero como subrut
|
|||
|
||||
( init )
|
||||
|0100
|
||||
( establecer colores del sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
@ -440,7 +440,7 @@ este es el programa hola-puntero.tal, pero utilizando dibuja-puntero como subrut
|
|||
BRK
|
||||
|
||||
@en-raton ( -> )
|
||||
;dibujar-puntero JSR2 ( o ,dibujar-puntero JSR )
|
||||
;dibuja-puntero JSR2 ( o ,dibuja-puntero JSR )
|
||||
|
||||
( algo más )
|
||||
BRK
|
||||
|
@ -486,9 +486,9 @@ puede haber otros casos en los que el uso de "variables" tendría un sentido má
|
|||
|
||||
habiendo introducido la pila de retorno y el modo de retorno, se nos abre otro mundo de posibilidades: también podemos utilizar la pila de retorno como una pila adicional y temporal, para almacenar algunos valores mientras operamos con otros.
|
||||
|
||||
para lograr esto, uxn tiene una instrucción llamada STH, almacenar o "stash".
|
||||
para lograr esto, uxn tiene una instrucción llamada STH, "stash" o almacenar.
|
||||
|
||||
¡esta es la última instrucción de uxn que teníamos que cubrir en esta serie de tutoriales! :)
|
||||
¡esta es la última instrucción de uxn que teníamos en mente cubrir en esta serie de tutoriales! :)
|
||||
|
||||
## STH
|
||||
|
||||
|
@ -502,20 +502,20 @@ y, como habrás previsto, en el modo corto esta instrucción opera moviendo cort
|
|||
|
||||
el siguiente es un ejemplo de subrutina que muestra algunas posibilidades de la pila y el modo de retorno.
|
||||
|
||||
se trata de una subrutina que dibuja una línea horizontal de una longitud dada (de 1 a 255 píxeles, es decir, utilizando un byte), partiendo de una coordenada x dada (corto) y utilizando una coordenada y dada (corto).
|
||||
se trata de una subrutina que dibuja una línea horizontal de una longitud dada (de 1 a 255 píxeles, es decir, utilizando un byte), partiendo de una coordenada x dada (corto) y utilizando una coordenada `y` dada (corto).
|
||||
|
||||
estos parámetros se dan como argumentos en la pila de trabajo.
|
||||
|
||||
la subrutina utiliza la pila de retorno para "almacenar" uno de estos argumentos mientras trabaja con los otros.
|
||||
|
||||
además, tiene un bucle de trabajo! escrito en una de las varias formas de implementarlo :)
|
||||
además, ¡tiene un bucle de trabajo! escrito en una de las varias formas de implementarlo :)
|
||||
|
||||
el estado de las pilas de trabajo (pt) y de retorno (pr) se muestra en los comentarios después de casi cada paso. la parte superior de las pilas se encuentra a su derecha.
|
||||
|
||||
un signo de intercalación (^) después de un nombre de valor indica que corresponde a un cortocircuito.
|
||||
un signo de intercalación (^) después de un nombre de valor indica que corresponde a un corto.
|
||||
|
||||
```
|
||||
@dibujar-linea-horizontal ( x^ y^ longitud -- )
|
||||
@dibuja-linea-horizontal ( x^ y^ longitud -- )
|
||||
( inicio )
|
||||
( pt: x^ y^ longitud / pr: )
|
||||
|
||||
|
@ -558,13 +558,13 @@ RTN
|
|||
|
||||
### llamando
|
||||
|
||||
para llamar a la subrutina, podrías hacer algo como lo siguiente
|
||||
para llamar a la subrutina, podrías hacer algo como lo siguiente:
|
||||
|
||||
```
|
||||
#0008 ( empujar x inicial )
|
||||
.Pantalla/altura DEI2 MITAD2 ( empujar y )
|
||||
#ff ( empujar longitud de la línea )
|
||||
;dibujar-linea-horizontal JSR2 ( llamar subrutina )
|
||||
;dibuja-linea-horizontal JSR2 ( llamar subrutina )
|
||||
```
|
||||
|
||||
### notas
|
||||
|
@ -578,13 +578,13 @@ sin embargo, muestra cómo podemos usar estas instrucciones para tener una pila
|
|||
* hacer que la subrutina dibuje una línea hecha de sprites en lugar de píxeles individuales
|
||||
* modificar la subrutina para que pueda recibir como argumento (en la pila de trabajo) el color de los sprites o píxeles
|
||||
* modificar la subrutina para que pueda recibir como argumento (en la pila de trabajo) la dirección del sprite a dibujar
|
||||
* reescribir la subrutina para que utilice una longitud de corto para la línea, en lugar de un byte.
|
||||
* reescribir la subrutina para que utilice una longitud de pequeño tamaño para la línea, en lugar de un byte.
|
||||
|
||||
# el modo mantener
|
||||
|
||||
el último elemento básico de uxntal que nos queda por cubrir es su tercer modo para las instrucciones: el modo mantener o "keep".
|
||||
|
||||
el modo mantener se codifica en el 8º bit de un byte de instrucción, contando de derecha a izquierda.
|
||||
el modo mantener se codifica en el 8vo bit de un byte de instrucción, contando de derecha a izquierda.
|
||||
|
||||
en uxntal, indicamos que queremos activar esta bandera añadiendo la letra 'k' al final de un mnemónico de instrucción.
|
||||
|
||||
|
@ -627,7 +627,7 @@ dije entonces que había un conjunto más optimizado, y que lo discutiríamos m
|
|||
|
||||
¡ahora es ese momento!
|
||||
|
||||
en primer lugar, analicemos lo que ocurre con MOD. está calculando lo que se escribiría en notación infija de la siguiente manera, suponiendo que la barra (/) indica una división entera
|
||||
en primer lugar, analicemos lo que ocurre con MOD. está calculando lo que se escribiría en notación infija de la siguiente manera, suponiendo que la barra (/) indica una división entera:
|
||||
|
||||
```
|
||||
a - ( a/b )*b
|
||||
|
@ -679,7 +679,7 @@ podemos generalizar este comportamiento para el modo corto, y obtener el conjunt
|
|||
|
||||
el modo mantener puede ser útil cuando hacemos comparaciones y no queremos perder los valores originales.
|
||||
|
||||
por ejemplo, en nuestra subrutina dibujar-línea-horizontal, teníamos el siguiente conjunto de líneas de código:
|
||||
por ejemplo, en nuestra subrutina dibuja-línea-horizontal, teníamos el siguiente conjunto de líneas de código:
|
||||
|
||||
```
|
||||
( duplicar longitud y el conteo, comparar, y saltar )
|
||||
|
@ -754,7 +754,7 @@ ten en cuenta que puedes cambiar el vector de un dispositivo durante el tiempo d
|
|||
|
||||
básicamente, las puertas para las aplicaciones visuales interactivas en el ordenador varvara están completamente abiertas ahora para ti :)
|
||||
|
||||
¿crearás juegos? ¿pequeñas aplicaciones, útiles o no? ¿un instrumento para visuales en vivo? ¿programas dirigidos a dispositivos manuales específicos?
|
||||
¿crearás juegos? ¿pequeñas aplicaciones, útiles o no? ¿un instrumento para visuales en vivo? ¿programas dirigidos a dispositivos de mano específicos?
|
||||
|
||||
algunas cosas pueden parecer difíciles de construir, pero afortunadamente, por ahora no hay nada más en el funcionamiento de la máquina que no hayamos cubierto ya.
|
||||
|
||||
|
@ -764,7 +764,7 @@ puedes ir poco a poco, paso a paso, practicando tu manejo de la pila y ejercitan
|
|||
|
||||
# instrucciones del día 5
|
||||
|
||||
estas son las instrucciones uxntales que hemos discutido hoy! con estas, las hemos cubierto todas!
|
||||
¡estas son las instrucciones uxntal que hemos discutido hoy! ¡con estas, las hemos cubierto todas!
|
||||
|
||||
* JSR: salta incondicionalmente a la dirección de la pila de trabajo, empujando hacia abajo en la pila de retorno la dirección de la siguiente instrucción en memoria
|
||||
* STH: toma un valor de la pila de trabajo y lo empuja hacia abajo en la pila de retorno. en el modo de retorno, hace lo contrario.
|
||||
|
@ -779,7 +779,7 @@ además de utilizar estrategias y fragmentos de código anteriores, cubrimos est
|
|||
|
||||
primero, te invito a tomar un descanso!
|
||||
|
||||
después, sigue explorando y comparte tus descubrimientos!
|
||||
después, ¡sigue explorando y comparte tus descubrimientos!
|
||||
|
||||
# apoyo
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ en el {tutorial de uxn día 5} hablamos de una forma de crear un bucle para repe
|
|||
|
||||
aquí ampliaremos ese procedimiento para que también se repita verticalmente en toda la pantalla.
|
||||
|
||||
## configuración
|
||||
## configurando
|
||||
|
||||
empecemos con el siguiente programa como plantilla. incluye los datos para un sprite de 1bpp que consiste en líneas diagonales.
|
||||
|
||||
|
@ -107,7 +107,7 @@ integrando todo ello, podríamos obtener:
|
|||
|
||||
nótese el uso de DUP2 para evitar releer el valor de x.
|
||||
|
||||
esto debería funcionar ahora! pero vamos a discutir una forma más agradable de hacerlo :)
|
||||
¡esto debería funcionar ahora! pero vamos a discutir una forma más agradable de hacerlo :)
|
||||
|
||||
### una segunda versión, usando la pila
|
||||
|
||||
|
@ -116,7 +116,7 @@ en lugar de leer el ancho de pantalla y la coordenada x cada vez, podríamos usa
|
|||
después de establecer la dirección del tile, podemos empujar nuestro límite (el ancho de la pantalla) y el valor inicial hacia abajo en la pila:
|
||||
|
||||
```
|
||||
.Pantalla/ancho DEI2 #0000 ( establecer límite y x inicial )
|
||||
.Pantalla/ancho DEI2 #0000 ( establecer límite y `x` inicial )
|
||||
```
|
||||
|
||||
usaremos ese valor en la parte superior de la pila como coordenada x.
|
||||
|
@ -141,14 +141,14 @@ 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 )
|
||||
```
|
||||
|
||||
cuando terminamos el bucle, tenemos que hacer POP de ambos valores.
|
||||
cuando terminamos el bucle, tenemos que hacer POP a ambos valores.
|
||||
|
||||
usando esta estrategia, obtendríamos el siguiente bucle:
|
||||
|
||||
```
|
||||
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
|
||||
|
||||
.Pantalla/ancho DEI2 #0000 ( empujar límite y x inicial )
|
||||
.Pantalla/ancho DEI2 #0000 ( empujar límite y `x` inicial )
|
||||
&bucle-x
|
||||
DUP2 .Pantalla/x DEO2 ( establecer coordenada x )
|
||||
|
||||
|
@ -192,7 +192,7 @@ lo siguiente muestra nuestro programa en contexto, llenando completamente la pri
|
|||
( dibujar fondo )
|
||||
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
|
||||
|
||||
.Pantalla/ancho DEI2 #0000 ( establecer límite y x inicial )
|
||||
.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 )
|
||||
|
@ -207,7 +207,7 @@ BRK
|
|||
|
||||
## repitiendo una fila
|
||||
|
||||
similar a lo que acabamos de hacer: ¿cuál es el procedimiento que podríamos seguir para repetir verticalmente una fila empezando por y, y terminando en un límite correspondiente a y+altura?
|
||||
similar a lo que acabamos de hacer: ¿cuál es el procedimiento que podríamos seguir para repetir verticalmente una fila empezando por `y`, y terminando en un límite correspondiente a y+altura?
|
||||
|
||||
siguiendo la misma estrategia, podríamos hacer:
|
||||
|
||||
|
@ -223,9 +223,9 @@ para ilustrar un pequeño cambio, supongamos que queremos tener un margen en la
|
|||
%MARGEN-PARED { #0010 } ( margen en la parte superior e inferior )
|
||||
```
|
||||
|
||||
nuestra y inicial sería MARGEN-PARED, y nuestro límite sería la altura de la pantalla menos MARGEN-PARED.
|
||||
nuestra `y` inicial sería MARGEN-PARED, y nuestro límite sería la altura de la pantalla menos MARGEN-PARED.
|
||||
|
||||
podemos usar la misma estructura que antes, pero usando y:
|
||||
podemos usar la misma estructura que antes, pero usando `y`:
|
||||
|
||||
```
|
||||
;tile-fondo .Pantalla/direc DEO2 ( establecer la dirección del tile )
|
||||
|
@ -238,8 +238,8 @@ MARGEN-PARED ( establecer `y` inicial )
|
|||
( - dibujar fila aquí - )
|
||||
|
||||
|
||||
#0008 ADD2 ( )
|
||||
GTH2k ( ¿es ese límite mayor que y? o también, ¿es `y` menor que el límite? )
|
||||
#0008 ADD2 ( incrementa `y` )
|
||||
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 )
|
||||
```
|
||||
|
@ -257,7 +257,7 @@ MARGEN-PARED ( establecer `y` inicial )
|
|||
DUP2 .Pantalla/y DEO2 ( establecer coordenada y )
|
||||
|
||||
( dibujar fila )
|
||||
.Pantalla/ancho DEI2 #0000 ( establecer límite y x inicial )
|
||||
.Pantalla/ancho DEI2 #0000 ( establecer límite y `x` inicial )
|
||||
&bucle-x
|
||||
DUP2 .Pantalla/x DEO2 ( fijar coordenada x )
|
||||
|
||||
|
@ -269,7 +269,7 @@ MARGEN-PARED ( establecer `y` inicial )
|
|||
,&bucle-x JCN ( salta si x es menor que el límite )
|
||||
POP2 POP2 ( eliminar x y el límite )
|
||||
|
||||
#0008 ADD2 ( )
|
||||
#0008 ADD2 ( incrementar y )
|
||||
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 )
|
||||
|
@ -291,7 +291,7 @@ ahora podemos envolver estos bucles anidados dentro de una subrutina:
|
|||
DUP2 .Pantalla/y DEO2 ( establecer coordenada y )
|
||||
|
||||
( dibujar fila )
|
||||
.Pantalla/ancho DEI2 #0000 ( establecer límite y x inicial )
|
||||
.Pantalla/ancho DEI2 #0000 ( establecer límite y `x` inicial )
|
||||
&bucle-x
|
||||
DUP2 .Pantalla/x DEO2 ( establecer coordenada x )
|
||||
|
||||
|
@ -303,20 +303,20 @@ ahora podemos envolver estos bucles anidados dentro de una subrutina:
|
|||
,&bucle-x JCN ( salta si x es menor que el límite )
|
||||
POP2 POP2 ( eliminar x y el límite )
|
||||
|
||||
#0008 ADD2 ( )
|
||||
GTH2k ( ¿es ese límite mayor que y? o también, ¿es `y` menor que el límite? )
|
||||
#0008 ADD2 ( incrementar y )
|
||||
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
|
||||
```
|
||||
|
||||
que podemos llamar simplemente desde nuestra subrutina de inicialización:
|
||||
que podemos llamar simplemente desde nuestra subrutina de iniciación:
|
||||
|
||||
```
|
||||
;dibuja-fondo JSR2
|
||||
```
|
||||
|
||||
=> ./img/screenshot_uxn-background-full.png captura de pantalla que muestra la pantalla de varvara cubierta de líneas diagonales excepto por un margen en la parte superior e inferior.
|
||||
=> ./img/screenshot_uxn-background-full.png captura de pantalla que muestra la pantalla varvara cubierta de líneas diagonales excepto por un margen en la parte superior e inferior.
|
||||
|
||||
¡lindo!
|
||||
|
||||
|
@ -326,11 +326,11 @@ se habla de varias posibilidades para usar uxntal de esa manera abstracta: yo di
|
|||
|
||||
# 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.
|
||||
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.
|
||||
|
||||
la coordenada x de cada pala puede ser constante, y la coordenada y debe ser de seguro una variable.
|
||||
la coordenada x de cada pala puede ser constante, y la coordenada `y` debe ser de seguro una variable.
|
||||
|
||||
en esta parte veremos como dibujar las palas en base a estos parámetros, y también recapitularemos como cambiar sus coordenadas `y` con el controlador.
|
||||
en esta parte veremos cómo dibujar las palas en base a estos parámetros, y también recapitularemos cómo cambiar sus coordenadas `y` con el controlador.
|
||||
|
||||
## dibujar las palas multi-tile
|
||||
|
||||
|
@ -353,11 +353,11 @@ los datos resultantes son los siguientes:
|
|||
```
|
||||
@pala
|
||||
&tile0 [ 3f 7f e7 c3 c3 c3 c3 00 00 18 3c 3c 3c 3c 3c ]
|
||||
&tile1 [ fc fe ff ff ff ff ff 00 00 00 00 06 06 ]
|
||||
&tile2 [ c3 c3 c3 e7 ff ff ff 3c 3c 3c 18 00 00 00 ]
|
||||
&tile3 [ ff ff ff ff ff ff 06 06 06 06 06 06 ]
|
||||
&tile4 [ ff ff ff ff ff 7f 3f 00 00 00 00 00 00 ]
|
||||
&tile5 [ ff ff ff ff ff fe fc 06 06 06 06 1e 3c 00 ]
|
||||
&tile1 [ fc fe ff ff ff ff ff 00 00 00 00 00 00 06 06 ]
|
||||
&tile2 [ c3 c3 c3 e7 ff ff ff 3c 3c 3c 3c 18 00 00 00 ]
|
||||
&tile3 [ ff ff ff ff ff ff 06 06 06 06 06 06 06 06 06 ]
|
||||
&tile4 [ ff ff ff ff ff 7f 3f 00 00 00 00 00 00 00 00 ]
|
||||
&tile5 [ ff ff ff ff ff fe fc 06 06 06 06 06 1e 3c 00 ]
|
||||
```
|
||||
|
||||
se pueden obtener estos números leyendo la notación hexadecimal en nasu en la parte superior derecha, primero la columna de la izquierda y luego la de la derecha, o utilizando una herramienta como hexdump con el archivo chr correspondiente:
|
||||
|
@ -372,7 +372,7 @@ he dibujado el sprite usando el modo de mezcla 85 como indica nasu, pero lo camb
|
|||
|
||||
construyamos una subrutina que dibuje las 6 fichas de la pala en el orden correspondiente.
|
||||
|
||||
podríamos tener la subrutina recibiendo como argumentos la posición x e y de su esquina superior izquierda:
|
||||
podríamos tener la subrutina recibiendo como argumentos la posición x e `y` de su esquina superior izquierda:
|
||||
|
||||
```
|
||||
@dibuja-pala ( x^ y^ -- )
|
||||
|
@ -386,9 +386,9 @@ 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 pelota, 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á borrar 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.
|
||||
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.
|
||||
|
||||
|
@ -404,15 +404,15 @@ podríamos por ejemplo dibujar los tiles en el siguiente orden, con las siguient
|
|||
o podríamos hacerlo de forma más tradicional:
|
||||
|
||||
* 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
|
||||
* dibujar el tile 1, luego restar 8 a x, y añadir 8 a `y`
|
||||
* dibujar el tile 2, luego añadir 8 a x
|
||||
* dibujar el tile 3, luego restar 8 a x, y añadir 8 a y
|
||||
* dibujar el tile 3, luego restar 8 a x, y añadir 8 a `y`
|
||||
* 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.
|
||||
|
||||
una posible ventaja de ir en orden es que podemos incrementar la dirección del sprite en 10 (16 en decimal) para llegar a la dirección del siguiente tile. para esto, y/o para los cambios de coordenadas, podemos aprovechar el auto byte de pantalla.
|
||||
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, y/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.
|
||||
|
||||
|
@ -486,13 +486,13 @@ es posible considerar formas más eficientes de dibujarla. por ejemplo, podríam
|
|||
@dibuja-sprite ( x^ y^ ancho alto direc* color )
|
||||
```
|
||||
|
||||
crear eso podría ser un buen ejercicio para probar! en este caso me quedaré con el método manual.
|
||||
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.
|
||||
reservemos un espacio en la página cero para las coordenadas x e `y` de cada pala.
|
||||
|
||||
```
|
||||
( página cero )
|
||||
|
@ -653,7 +653,7 @@ para borrarlos, podemos hacer lo mismo pero usando un byte del sprite correspond
|
|||
donde COLOR-BORRAR en este caso sería:
|
||||
|
||||
```
|
||||
%COLOR-BORRAR { #40 } ( limpiar el sprite del primer plano )
|
||||
%COLOR-BORRAR { #40 } ( borrar el sprite del primer plano )
|
||||
```
|
||||
|
||||
¡este es un buen recordatorio para revisar las tablas de los bytes de los sprites en el {tutorial de uxn día 2}!
|
||||
|
@ -713,7 +713,7 @@ RTN
|
|||
|
||||
### procedimiento completo
|
||||
|
||||
integrando todo, nuestra subrutina en el marco se vería como lo siguiente.
|
||||
integrando todo, nuestra subrutina en-cuadro se vería como lo siguiente.
|
||||
|
||||
¡ahora somos capaces de mover nuestras palas!
|
||||
|
||||
|
@ -740,7 +740,7 @@ te invito a que modifiques la subrutina actualiza-palas para que haya un límite
|
|||
|
||||
¡ahora vamos a poner la pelota en marcha!
|
||||
|
||||
aquí trabajaremos de nuevo con un sprite multi-tile dibujado en relación a las variables x e y para su esquina superior izquierda.
|
||||
aquí trabajaremos de nuevo con un sprite multi-tile dibujado en relación a las variables x e `y` para su esquina superior izquierda.
|
||||
|
||||
adicionalmente, usaremos esta sección para hablar de las estrategias para la detección de colisiones, con las paredes y las palas.
|
||||
|
||||
|
@ -758,9 +758,9 @@ estos son sus datos:
|
|||
```
|
||||
@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 ff ff 00 00 00 08 0c 06 06 ]
|
||||
&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 fc f8 f0 c0 06 06 0c 1c 38 f0 c0 00 ]
|
||||
&tile3 [ ff ff fe fe fc f8 f0 c0 06 06 0c 1c 38 f0 c0 00 ]
|
||||
```
|
||||
|
||||
podemos definir un par de macros para referirse a sus parámetros:
|
||||
|
@ -796,13 +796,13 @@ MITAD2
|
|||
|
||||
las coordenadas están listas, así que ahora podemos usarlas dentro de nuestra subrutina.
|
||||
|
||||
hagamos que la subrutina reciba el color como argumento, para poder limpiar la pelota como hacemos con las palas:
|
||||
hagamos que la subrutina reciba el color como argumento, para poder borrar la pelota como hacemos con las palas:
|
||||
|
||||
```
|
||||
@dibuja-pelota ( color -- )
|
||||
( fijar x e y iniciales )
|
||||
( fijar x e `y` iniciales )
|
||||
.pelota/x LDZ2 .Pantalla/x DEO2
|
||||
.pelota/y LDZ2 . pantalla/y DEO2
|
||||
.pelota/y LDZ2 .Pantalla/y DEO2
|
||||
|
||||
( dibujar tile 0 )
|
||||
;pelota-sprite/tile0 .Pantalla/direc DEO2
|
||||
|
@ -845,11 +845,11 @@ COLOR-PELOTA ;dibuja-pelota JSR2
|
|||
|
||||
para el movimiento de la pelota, seguiremos la misma estructura que antes:
|
||||
|
||||
* despejar la pelota en la posición actual
|
||||
* borrar la pelota en la posición actual
|
||||
* actualizar su posición
|
||||
* dibujar la pelota en la nueva posición
|
||||
|
||||
se vería algo como lo siguiente, y podría sentarse a lo largo de los procedimientos equivalentes para las palas dentro de la subrutina en-cuadro:
|
||||
se vería algo como lo siguiente, y podría situarse a lo largo de los procedimientos equivalentes para las palas dentro de la subrutina en-cuadro:`
|
||||
|
||||
```
|
||||
( dentro de en-cuadro )
|
||||
|
@ -869,13 +869,13 @@ ahora vamos a discutir cómo construir esa subrutina actualiza-pelota :)
|
|||
|
||||
además de nuestras variables para llevar la cuenta de la posición de la pelota, deberíamos poder llevar la cuenta de la dirección por-eje en la que se mueve.
|
||||
|
||||
un enfoque podría ser tener una bandera para cada x e y que indique si debemos incrementarlos o disminuirlos.
|
||||
un enfoque podría ser tener una bandera para cada x e `y` que indique si debemos incrementarlos o decrementarlos.
|
||||
|
||||
otro enfoque podría ser tener una variable de velocidad para cada x e y, que se cambia de acuerdo a la dirección que queremos que la pelota vaya.
|
||||
otro enfoque podría ser tener una variable de velocidad para cada x e `y`, que se cambia de acuerdo a la dirección que queremos que la pelota vaya.
|
||||
|
||||
utilizaremos este último enfoque con la velocidad, ya que nos ayudará a discutir algunas ventajas de la aritmética de enteros sin signo.
|
||||
|
||||
incluimos estas variables en nuestra página cero, complementando las x e y que ya teníamos:
|
||||
incluimos estas variables en nuestra página cero, complementando las x e `y` que ya teníamos:
|
||||
|
||||
```
|
||||
@pelota [ &x $2 &y $2 &vel-x $2 &vel-y $2 ]
|
||||
|
@ -883,7 +883,7 @@ incluimos estas variables en nuestra página cero, complementando las x e y que
|
|||
|
||||
### diferentes direcciones
|
||||
|
||||
si, por ejemplo, iniciamos vel-x con 1
|
||||
si, por ejemplo, iniciamos vel-x con 1:
|
||||
|
||||
```
|
||||
#0001 .pelota/vel-x STZ2
|
||||
|
@ -895,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 ( sumar ambas cosas )
|
||||
ADD2 ( sumar ambas )
|
||||
.pelota/x STZ2 ( almacenar nueva x )
|
||||
```
|
||||
|
||||
|
@ -952,11 +952,11 @@ para obtener otros "números negativos", observemos lo siguiente: si restamos 1
|
|||
1 0000 0000 0000 0000: 0000
|
||||
```
|
||||
|
||||
obtenemos 0! fffe funciona efectivamente como "-2"!
|
||||
¡obtenemos 0! ¡fffe funciona efectivamente como "-2"!
|
||||
|
||||
podríamos continuar así obteniendo más y más números "negativos" que funcionan gracias al tamaño restringido de la memoria del ordenador.
|
||||
|
||||
volviendo a nuestro código, si inicializamos nuestra velocidad con:
|
||||
volviendo a nuestro código, si iniciamos nuestra velocidad con:
|
||||
|
||||
```
|
||||
#ffff .pelota/vel-x STZ2
|
||||
|
@ -968,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 ( sumar ambas cosas )
|
||||
ADD2 ( sumar ambas )
|
||||
.pelota/x STZ2 ( almacenar nueva x )
|
||||
```
|
||||
|
||||
|
@ -983,18 +983,18 @@ podría tener sentido establecer estos valores como macros:
|
|||
|
||||
### implementando el movimiento de la pelota
|
||||
|
||||
basándonos en lo que acabamos de discutir, podemos empezar nuestra subrutina de actualización de la pelota con lo siguiente:
|
||||
basándonos en lo que acabamos de discutir, podemos empezar nuestra subrutina actualiza-pelota con lo siguiente:
|
||||
|
||||
```
|
||||
@actualiza-pelota ( -- )
|
||||
( obtener velocidad-x y x )
|
||||
( obtener velocidad-x y `x` )
|
||||
.pelota/vel-x LDZ2 .pelota/x LDZ2
|
||||
ADD2 ( sumar ambas cosas )
|
||||
.pelota/x STZ2 ( guarda la nueva x )
|
||||
|
||||
( obtener velocidad-y e y )
|
||||
( obtener velocidad-y e `y` )
|
||||
.pelota/vel-y LDZ2 .pelota/y LDZ2
|
||||
ADD2 ( sumar ambas cosas )
|
||||
ADD2 ( sumar ambas )
|
||||
.pelota/y STZ2 ( almacenar nueva y )
|
||||
RTN
|
||||
```
|
||||
|
@ -1018,13 +1018,13 @@ woohoo! se mueve, pero de momento sale volando :)
|
|||
|
||||
## colisiones con las paredes
|
||||
|
||||
hemos definido la forma general de actualizar la posición de la pelota dada su velocidad en x e y.
|
||||
hemos definido la forma general de actualizar la posición de la pelota dada su velocidad en x e `y`.
|
||||
|
||||
¡ahora veamos cómo implementar el clásico "rebote"!
|
||||
|
||||
primero, empecemos con las paredes en la parte superior e inferior de la pantalla; recordando que hay un margen (MARGEN-PARED) entre el borde real de la pantalla, y las paredes.
|
||||
|
||||
para realizar estas detecciones de colisión, tendríamos que comprobar sólo la coordenada y de la pelota.
|
||||
para realizar estas detecciones de colisión, tendríamos que comprobar sólo la coordenada `y` de la pelota.
|
||||
|
||||
como siempre, hay muchas maneras de lograr esto. una podría ser:
|
||||
|
||||
|
@ -1046,7 +1046,7 @@ pista: mira de nuevo las máscaras a nivel de bit discutidas en el {tutorial de
|
|||
|
||||
### pared superior
|
||||
|
||||
si la pelota golpea la pared superior, significa que su coordenada y es menor que la coordenada y de la pared.
|
||||
si la pelota golpea la pared superior, significa que su coordenada `y` es menor que la coordenada `y` de la pared.
|
||||
|
||||
considerando que hay un margen en la parte superior, podemos hacer esta comprobación de la siguiente manera:
|
||||
|
||||
|
@ -1069,12 +1069,12 @@ considerando que hay un margen en la parte superior, podemos hacer esta comproba
|
|||
|
||||
aquí el procedimiento sería similar, pero considerando el tamaño de la pelota.
|
||||
|
||||
queremos saber si la coordenada y, más el tamaño de la pelota, es mayor que la coordenada y de la pared inferior.
|
||||
queremos saber si la coordenada `y`, más el tamaño de la pelota, es mayor que la coordenada `y` de la pared inferior.
|
||||
|
||||
la coordenada y de la pared inferior sería la altura de la pantalla, menos el margen de la pared:
|
||||
la coordenada `y` de la pared inferior sería la altura de la pantalla, menos el margen de la pared:
|
||||
|
||||
```
|
||||
(actualización del interior de la pelota )
|
||||
(dentro de actualiza-pelota )
|
||||
&verif-pared-inf
|
||||
.pelota/y LDZ2 TAM-PELOTA ADD2 ( y + tamaño de la pelota )
|
||||
.Pantalla/alto DEI2
|
||||
|
@ -1088,9 +1088,9 @@ la coordenada y de la pared inferior sería la altura de la pantalla, menos el m
|
|||
&continuar
|
||||
```
|
||||
|
||||
### código de actualización de la pelota hasta ahora
|
||||
### actualiza-pelota hasta ahora
|
||||
|
||||
nuestra subrutina de actualización de la pelota tiene el siguiente aspecto ahora mismo:
|
||||
nuestra subrutina actualiza-pelota tiene el siguiente aspecto hasta el momento:
|
||||
|
||||
```
|
||||
@actualiza-pelota ( -- )
|
||||
|
@ -1101,7 +1101,7 @@ nuestra subrutina de actualización de la pelota tiene el siguiente aspecto ahor
|
|||
.pelota/x STZ2 ( guardar la nueva x )
|
||||
|
||||
( actualizar y )
|
||||
( obtener velocidad-y e y )
|
||||
( obtener velocidad-y e `y` )
|
||||
.pelota/vel-y LDZ2 .pelota/y LDZ2
|
||||
ADD2 ( sumar ambas cosas )
|
||||
.pelota/y STZ2 ( almacenar nueva y )
|
||||
|
@ -1159,12 +1159,12 @@ para ello, podemos comprobar si x es menor que la suma del margen y el ancho de
|
|||
&verif-pala-der
|
||||
```
|
||||
|
||||
una vez que sabemos que eso es cierto, podemos ver si la pelota está dentro del alcance vertical de la pala; la coordenada y de la pelota tiene que estar dentro de un cierto rango relativo a la coordenada y de la pelota.
|
||||
una vez que sabemos que eso es cierto, podemos ver si la pelota está dentro del alcance vertical de la pala; la coordenada `y` de la pelota tiene que estar dentro de un cierto rango relativo a la coordenada `y` de la pelota.
|
||||
|
||||
en especifico, si queremos que la pelota pueda rebotar cuando cualquier parte de la pelota golpee cualquier parte de la pala, la coordenada y de la pelota tiene que ser:
|
||||
en especifico, si queremos que la pelota pueda rebotar cuando cualquier parte de la pelota golpee cualquier parte de la pala, la coordenada `y` de la pelota tiene que ser:
|
||||
|
||||
* mayor que la coordenada y de la pala menos la altura AND de la pelota
|
||||
* menor que la coordenada y de la pala más la altura de la pala
|
||||
* mayor que la coordenada `y` de la pala menos la altura AND de la pelota
|
||||
* menor que la coordenada `y` de la pala más la altura de la pala
|
||||
|
||||
si esas dos condiciones se cumplen, entonces podemos establecer una velocidad positiva para x:
|
||||
|
||||
|
@ -1219,7 +1219,7 @@ todo el código x-en-izquierda terminaría pareciendo:
|
|||
&verif-pala-der
|
||||
```
|
||||
|
||||
fin sería una etiqueta al final de la subrutina, y reset es una subrutina de la que hablaremos más adelante.
|
||||
"fin" sería una etiqueta al final de la subrutina, y "reset" es una subrutina de la cuálf 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 pelota: podría ocurrir que cruzara la pared pero con una coordenada x que nunca fuera igual a 0.
|
||||
|
||||
|
@ -1237,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 pelota mayor que el ancho de la pantalla - margen - ancho de la pala? )
|
||||
GTH2 ( ¿es la coordenada derecha de la pelota mayor que el ancho de la pantalla - margen - ancho-palaf? )
|
||||
,&x-en-derecha JCN
|
||||
&fin JMP
|
||||
|
||||
|
@ -1267,7 +1267,7 @@ para la pala derecha haremos lo mismo que arriba, pero cambiando las comparacion
|
|||
RTN
|
||||
```
|
||||
|
||||
¡eso debería ser todo! ¡puedes encontrar la subrutina de actualización de la pelota completa a continuación!
|
||||
¡eso debería ser todo! ¡puedes encontrar la subrutina actualiza-pelota completa a continuación!
|
||||
|
||||
¡para poder ensamblar y ejecutar el juego, vamos a definir la subrutina reset!
|
||||
|
||||
|
@ -1285,7 +1285,7 @@ aquí solo definiremos una subrutina de reinicio o "reset" que devuelva la pelot
|
|||
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.
|
||||
sería interesante tener algún mecanismo para también cambiar la velocidad: tal vez basado en el cuentafotogramas, en la posición de las palas, o cualquier otra cosa que elijas.
|
||||
|
||||
# el programa completo
|
||||
|
||||
|
@ -1331,7 +1331,7 @@ aquí está todo el código que hemos escrito hoy:
|
|||
( configuración )
|
||||
|0100
|
||||
@configuracion ( -> )
|
||||
( establecer colores del sistema )
|
||||
( establecer los colores del sistema )
|
||||
#2ce9 .Sistema/r DEO2
|
||||
#01c0 .Sistema/g DEO2
|
||||
#2ce5 .Sistema/b DEO2
|
||||
|
@ -1340,7 +1340,7 @@ aquí está todo el código que hemos escrito hoy:
|
|||
;en-cuadro .Pantalla/vector DEO2
|
||||
|
||||
( dibujar fondo )
|
||||
;dibujar fondo JSR2
|
||||
;dibuja-fondo JSR2
|
||||
|
||||
( iniciar palas )
|
||||
MARGEN .izquierda/x STZ2
|
||||
|
@ -1389,7 +1389,6 @@ BRK
|
|||
BRK
|
||||
```
|
||||
|
||||
|
||||
## reset
|
||||
|
||||
```
|
||||
|
@ -1413,7 +1412,7 @@ RTN
|
|||
ADD2 ( sumar ambas cosas )
|
||||
.pelota/x STZ2 ( guardar la nueva x )
|
||||
|
||||
( obtener velocidad-y e y )
|
||||
( 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 )
|
||||
|
@ -1428,7 +1427,7 @@ RTN
|
|||
|
||||
&establecer-vel-pos
|
||||
PELOTA-VEL-POS .pelota/vel-y STZ2
|
||||
&continuar JMP
|
||||
,&continuar JMP
|
||||
|
||||
&verif-pared-inf
|
||||
.pelota/y LDZ2 TAM-PELOTA ADD2 ( y + tamaño-pelota )
|
||||
|
@ -1474,7 +1473,7 @@ RTN
|
|||
.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
|
||||
,&fin JMP
|
||||
|
||||
&x-en-derecha
|
||||
.pelota/y LDZ2 DUP2
|
||||
|
@ -1505,7 +1504,7 @@ RTN
|
|||
|
||||
```
|
||||
@dibuja-pelota ( color -- )
|
||||
( fijar x e y iniciales )
|
||||
( fijar x e `y` iniciales )
|
||||
.pelota/x LDZ2 .Pantalla/x DEO2
|
||||
.pelota/y LDZ2 .Pantalla/y DEO2
|
||||
|
||||
|
@ -1549,9 +1548,9 @@ RTN
|
|||
DUP #10 AND ( comprobar bit para arriba )
|
||||
,&izquierda-arriba JCN
|
||||
DUP #20 AND ( comprobar bit para abajo )
|
||||
&izquierda-abajo JCN
|
||||
,&izquierda-abajo JCN
|
||||
|
||||
&derecha JMP ( salta si no se ha pulsado ninguno de los dos )
|
||||
,&derecha JMP ( salta si no se ha pulsado ninguno de los dos )
|
||||
|
||||
&izquierda-arriba
|
||||
.izquierda/y LDZ2 VEL-PALA SUB2 .izquierda/y STZ2
|
||||
|
@ -1565,9 +1564,9 @@ RTN
|
|||
DUP #01 AND ( comprobar bit para A )
|
||||
,&derecha-arriba JCN
|
||||
DUP #02 AND ( comprobar bit para B )
|
||||
&derecha-abajo JCN
|
||||
,&derecha-abajo JCN
|
||||
|
||||
&fin JMP ( salta si no se ha pulsado ninguno de los dos )
|
||||
,&fin JMP ( salta si no se ha pulsado ninguno de los dos )
|
||||
|
||||
&derecha-arriba
|
||||
.derecha/y LDZ2 VEL-PALA SUB2 .derecha/y STZ2
|
||||
|
@ -1646,14 +1645,14 @@ RTN
|
|||
DUP2 .Pantalla/y DEO2 ( establecer coordenada `y` )
|
||||
|
||||
( dibujar fila )
|
||||
.Pantalla/ancho DEI2 #0000 ( establecer límite `y` x inicial )
|
||||
.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 )
|
||||
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? )
|
||||
|
@ -1694,7 +1693,7 @@ aquí hay algunas posibilidades extra para que practiques y trates de implementa
|
|||
* 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!
|
||||
* ¡etc!
|
||||
|
||||
¡comparte lo que termines creando en base a todo esto! :)
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ as you may recall, the zero page consists of the first 256 addresses of program
|
|||
|
||||
we can refer to any of the 256 addresses of the zero page using one byte only, instead of the two bytes that are needed for absolute addresses.
|
||||
|
||||
something importat to keep in mind is that the contents of the zero page are not present in uxn roms.
|
||||
something important to keep in mind is that the contents of the zero page are not present in uxn roms.
|
||||
|
||||
this means that a caveat of using variables there, is that in order to initialize them we need to do it during runtime, by storing values from the stack into them.
|
||||
|
||||
|
@ -207,7 +207,6 @@ labels for the zero page would work the same as before; we only need to specify
|
|||
|
||||
in order to refer to them, we would use the dot (.) rune for literal zero page addresses, instead of the colon (;) rune for literal absolute addresses.
|
||||
|
||||
|
||||
### instructions: LDZ, STZ
|
||||
|
||||
the instructions for loading (reading) and storing (writing) from and to the zero page are:
|
||||
|
@ -266,7 +265,7 @@ BRK
|
|||
|
||||
note the use of the literal zero page address rune (.) to refer to the .pixel label.
|
||||
|
||||
also, note that in the case of .pixel the address is referring to the zero page, accessed with LDZ/STZ, and in the case of .Screen the address is referring to the i/o address space, accessed with DEO/DEI.
|
||||
also, note that in the case of .pixel the address is referring to the zero page, accessed with LDZ/STZ, and in the case of .Screen the address is referring to the i/o address space, accessed with DEI/DEO.
|
||||
|
||||
### a little stack wrangling practice
|
||||
|
||||
|
@ -920,12 +919,10 @@ we can use these macros to divide the frequency in our code:
|
|||
.Screen/addr DEO2 ( set computed address )
|
||||
```
|
||||
|
||||
|
||||
=> ./img/screencap_uxn-animation-quarterspeed.gif animation of a diagonal stripe inside a pixelated square. the diagonal moves from bottom right to top left. it moves slower than the previous one.
|
||||
|
||||
ah, way better!
|
||||
|
||||
|
||||
## not powers of two
|
||||
|
||||
note that if you want to divide the frequency to numbers that are not powers of 2, you might start to see some glitches approximately every 4 seconds: this is due to framecount overflowing and not giving a nice sequence of results for those divisors.
|
||||
|
@ -936,7 +933,6 @@ the easiest workaround for these issues would be to use a short-sized framecount
|
|||
|
||||
you'd have to adapt the program to work with that size of framecount - nice exercise, i feel and think!
|
||||
|
||||
|
||||
# instructions of day 4
|
||||
|
||||
these are all the uxntal instructions that we discussed today!
|
||||
|
|
|
@ -25,6 +25,7 @@ counting from right to left, the first bit corresponds to the first mouse button
|
|||
usually, in a three-button mouse, the first button is the left one, the second button the middle one, and the third button the right one.
|
||||
|
||||
using a three-button mouse like this, we would have eight possible values for the state byte, for example:
|
||||
|
||||
* 00 when none of the buttons are pressed
|
||||
* 01 when only the first button is pressed
|
||||
* 02 when only the second button is pressed
|
||||
|
@ -35,7 +36,7 @@ note that similarly to the controller device, this system allows us to check for
|
|||
* 03 when the first and second buttons are pressed
|
||||
* 05 when the first and third buttons are pressed
|
||||
* 06 when the second and third buttons are pressed
|
||||
* 07 when the threee buttons are pressed
|
||||
* 07 when the three buttons are pressed
|
||||
|
||||
remember that we can use AND masks, as introduced on {uxn tutorial day 3}, to isolate and evaluate separately any of these bits.
|
||||
|
||||
|
@ -257,6 +258,7 @@ first of all, let's move our pointer drawing subroutine to another label in our
|
|||
#4a .Screen/sprite DEO
|
||||
BRK
|
||||
```
|
||||
|
||||
note that we could join the actions of updating the pointer position and sending it to the screen, using a pair of DUP2:
|
||||
|
||||
```
|
||||
|
@ -273,7 +275,6 @@ this would leave our on-mouse subroutine empty:
|
|||
BRK
|
||||
```
|
||||
|
||||
|
||||
### using normal jumps
|
||||
|
||||
with what we know already, and depending on the position of draw-pointer with respect to on-mouse, we could do a relative jump:
|
||||
|
@ -396,7 +397,7 @@ additionally, as the addresses pushed by JSR are shorts, we need to activate the
|
|||
JMP2r ( jump to the absolute address at the top of the return stack )
|
||||
```
|
||||
|
||||
in many uxntal programs you will see this instruction written as a macro, RTN (return)
|
||||
in many uxntal programs you will see this instruction written as a macro, RTN (return):
|
||||
|
||||
```
|
||||
%RTN { JMP2r }
|
||||
|
@ -626,7 +627,7 @@ i said then that there was a more optimized set, and that we'd discuss it later.
|
|||
|
||||
now is that moment!
|
||||
|
||||
first of all, let's analyze what's happening with MOD. it is calculating what would be written in infix notation as follows, assumming that the slash (/) indicates an integer division
|
||||
first of all, let's analyze what's happening with MOD. it is calculating what would be written in infix notation as follows, assumming that the slash (/) indicates an integer division:
|
||||
|
||||
```
|
||||
a - ( a/b )*b
|
||||
|
|
|
@ -45,7 +45,6 @@ let's start with the following program as a template. it includes the data for a
|
|||
#01c0 .System/g DEO2
|
||||
#2ce5 .System/b DEO2
|
||||
|
||||
|
||||
BRK
|
||||
|
||||
@tile-background 1122 4488 1122 4488
|
||||
|
@ -1220,7 +1219,7 @@ the whole x-in-left code would end up looking like:
|
|||
&check-right-paddle
|
||||
```
|
||||
|
||||
finish would be a label at the end of the subroutine, and reset is a subroutine that we will discuss later.
|
||||
"finish" would be a label at the end of the subroutine, and "reset" is a subroutine that we will discuss later.
|
||||
|
||||
this approach of comparing with 0000 is the easiest, but keep in mind that it might not work if you change the ball speed: it could happen that it crosses the wall but with an x coordinate that is never equal to 0.
|
||||
|
||||
|
|
Loading…
Reference in New Issue