{"id":2932,"date":"2021-02-11T22:41:59","date_gmt":"2021-02-11T22:41:59","guid":{"rendered":"http:\/\/blog.rastersoft.com\/?p=2932"},"modified":"2023-12-25T19:47:39","modified_gmt":"2023-12-25T19:47:39","slug":"pintando-en-el-spectrum-13","status":"publish","type":"post","link":"https:\/\/blog.rastersoft.com\/?p=2932","title":{"rendered":"Pintando en el Spectrum (13)"},"content":{"rendered":"\n<p>En la entrada anterior se me olvid\u00f3 comentar un detalle extra, que es la <em>tabla de sprites<\/em>. Esta tabla contiene la informaci\u00f3n de cualquier sprite que no sea \u00abde fondo\u00bb; esto es: todo sprite que vaya a ser animado, o que pueda aparecer o desaparecer, o moverse de sitio, y que, por tanto, no est\u00e9 definido en el mapa sino que deba pintarse aparte. Estos sprites, al no ser parte del <em>decorado<\/em> en s\u00ed, no pueden almacenarse en la tabla del mapa que vimos antes (la que define las paredes, suelo y objetos <em>fijos<\/em>), sino que deben definirse aparte.<\/p>\n\n\n\n<p>El primer ejemplo de este tipo de objetos son los propios sprites de los personajes: desde el momento en que \u00e9stos se pueden mover de un lado para otro es necesario que no formen parte del mapa. Otro ejemplo son todos los objetos que el protagonista puede coger o dejar, pues \u00e9stos <em>aparecer\u00e1n<\/em> o <em>desaparecer\u00e1n<\/em> del mapa, y tambi\u00e9n pueden cambiar de lugar en funci\u00f3n de donde los deje el jugador. Por \u00faltimo, cualquier objeto animado, como por ejemplo los personajes, o una olla al fuego que hace <em>chup, chup<\/em>&#8230;<\/p>\n\n\n\n<p>La <em>tabla de sprites<\/em> tiene el siguiente formato:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted mycode\">    DEFB 5 ; coordenada Z\n           ; si 255-> esta entrada est\u00e1 vac\u00eda\n           ; si 254-> fin de la tabla\n    DEFB 40 ; coordenada X en el mapa\n    DEFB 32 ; coordenada Y en el mapa\n    DEFB 0x58 ; color de sustituci\u00f3n\n    DEFW sprite_base_right ; puntero al sprite-en-s\u00ed<\/pre>\n\n\n\n<p>En primer lugar tenemos la coordenada Z o de altura. Este byte tiene dos valores especiales: si vale 254 nos indica que es el final de la tabla y, por tanto, que no hay m\u00e1s <em>sprites<\/em>. Si vale 255 significa que esta entrada nos la debemos saltar porque est\u00e1 <em>vac\u00eda<\/em>. Esto es \u00fatil para objetos que pueden aparecer y desaparecer del mapa: cuando no est\u00e1 visible ponemos esta entrada a 255, y no se pintar\u00e1; cuando vuelva a ser visible, la ponemos al valor de Z correcto.<\/p>\n\n\n\n<p>Justo despu\u00e9s est\u00e1n las coordenadas X e Y. La coordenada Y es fundamental a la hora de pintar el mapa. En efecto, si recordamos, cuando pint\u00e1bamos el mapa lo hac\u00edamos desde las coordenadas Y m\u00e1s bajas (que quedan \u00abarriba\u00bb de la pantalla) hacia las m\u00e1s altas. Pues bien: cada vez que se pinta una fila completa del mapa, se recorre la tabla de sprites en busca de todos aquellos cuya coordenada Y coincida con la fila que acabamos de pintar. Si encontramos un sprite que cumpla esta condici\u00f3n, calculamos la coordenada Y de pantalla restando de su coordenada Y la coordenada Z (de manera que cuanto m\u00e1s \u00abalto\u00bb est\u00e9 en Z, m\u00e1s arriba aparecer\u00e1 en pantalla, pero tapando todos los elementos del mapa que se encuentran antes que la Y del sprite). Es justo esto lo que nos permite simular el efecto 3D, en el que los objetos pueden moverse en los tres ejes, y ocluyendo (o <em>tapando<\/em>) todo lo que se encuentra detras.<\/p>\n\n\n\n<p>El siguiente byte es el color de sustituci\u00f3n: en mi juego quiero que haya varios personajes, pero todos van a estar hechos con el mismo sprite, as\u00ed que para distinguirlos cada uno tendr\u00e1 un color diferente. La manera m\u00e1s sencilla de implementar esto obligar\u00eda a tener un conjunto de atributos de color diferente para cada sprite, lo que supondr\u00eda un consumo excesivo de memoria. As\u00ed que decid\u00ed que los sprites que tienen m\u00e1scara de transparencia (lo que incluye al sprite de los personajes) pueden marcar bloques de atributos para que sean sustituidos por este color. Para ello s\u00f3lo tienen que activar el bit de FLASH y el de BRIGHT a la vez en un atributo concreto, y ese ser\u00e1 sustituido por este valor. En cambio, si s\u00f3lo marca el bit de FLASH, entonces simplemente no se escribir\u00e1 ese atributo de color concreto, con lo que el color que se utilizar\u00e1 ser\u00e1 el que ya hab\u00eda debajo. Esto permite conseguir tambi\u00e9n \u00abtransparencia\u00bb con los colores.<\/p>\n\n\n\n<p>As\u00ed, en el caso del sprite del personaje, todas las zonas del traje tienen los bits de FLASH y de BRIGHT activos, lo que significa que el color que defin\u00ed en el editor no se utilizar\u00e1 para esas zonas, sino \u00e9ste que he definido aqu\u00ed. Eso es lo que permite tener varios personajes, cada uno de un color diferente, sin consumir memoria extra para meter cada uno.<\/p>\n\n\n\n<p>Por \u00faltimo, tenemos un puntero a los datos del sprite en s\u00ed. Esto se hace as\u00ed para poder cambiar el puntero y, de esta manera, poder animar el sprite si se desea. Por ejemplo, si tenemos dos sprites de una olla que forman una animaci\u00f3n, lo que haremos ser\u00e1 ir cambiando la direcci\u00f3n del puntero de datos en la entrada de la tabla de sprites de manera que vaya alternando a cual de los dos apunta.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la entrada anterior se me olvid\u00f3 comentar un detalle extra, que es la tabla de sprites. Esta tabla contiene la informaci\u00f3n de cualquier sprite que no sea \u00abde fondo\u00bb; esto es: todo sprite que vaya a ser animado, o que pueda aparecer o desaparecer, o moverse de sitio, y que, por tanto, no est\u00e9 &hellip; <a href=\"https:\/\/blog.rastersoft.com\/?p=2932\" class=\"more-link\">Seguir leyendo <span class=\"screen-reader-text\">Pintando en el Spectrum (13)<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,17,7],"tags":[20],"class_list":["post-2932","post","type-post","status-publish","format-standard","hentry","category-programacion","category-retrocomputacion","category-tutoriales","tag-pintando-en-el-spectrum"],"_links":{"self":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/2932","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2932"}],"version-history":[{"count":2,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/2932\/revisions"}],"predecessor-version":[{"id":2936,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/2932\/revisions\/2936"}],"wp:attachment":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2932"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2932"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2932"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}