top of page

Creant i movent Sprites

Objectiu


Després de practicar amb el que us explicarem hauríeu de ser capaços de crear un Sprite utilitzant l’eina que més us vagi bé i incorporar-lo al FUSION-C per a donar-li color i moure’l per pantalla amb els cursors.


En aquest exemple treballarem ajudant-nos del programari d’edició d’imatges Gimp, així com del que ja hem presentat fins ara.


Primer de tot què és un Sprite?


Un sprite és, als videojocs, un element gràfic que es pot desplaçar sobre la pantalla. En principi, un sprite és parcialment transparent, i pot ser animat (és a dir, és format de diversos mapes de bits que apareixen uns sobre els altres).


Dissenyant un Sptite


Per aquesta guia hem decidit crear l’Sprite d’un gat de tamany 16 X 16 pixels.




Aquest és el resultat de dibuixar el gat amb el programa Gimp. Per que l’Sprite del gat tingui un mínim de detall pel que fa al color, hem decidit creat un Sptite amb dues capes. Una capa tindrà el color principal del gat i l’altre les taques del gat. Això ho traslladarem a l’MSX com dos Sptires que mourem a la vegada com si es tractés d’un de sol.






Tot seguit us comento una eina de Gimp que us pot ser de molta utilitat per a dibuixar Sprites i després traslladar la informació a bits per a ser gestionat des de l’MSX.


Aquesta eina és una grella del tamany d’un píxel per a poder crear els nostres dissenys d’Sprites amb comoditat des de Gimp.


Primer des de l’opció de menú Image > Configure Grid seleccionem el tamany de la graella a 1x1.








La graella no apareixerà fins que no l’activem des des del menú View>Show Grid





Un cop activada la graella se’ns mostrarà a la imatge d’aquesta manera:




Cada quadre de la graella es correspondrà a un píxel.


Per a fer el gat hem creat una imatge transparent de 16x16 pixels. Utilitzant la graella podem dissenyar Sprites amb més precisió que amb d’altres utilitats.


Si volem també podem incorporar al Gimp la paleta de 16 colors del MSX1 que podem trobar per exemple en format ja Gimp al següent enllaç [1]





Dissenyant l’animació


Ara que hem introduït el disseny d’un primer Sprite, dissenyarem un altre Sprite per a poder animar el gat.


La idea que hi ha darrera a animar un Sprite és la mateixa que hi ha darrera l’animació tradicional de paper de dibuixar varies posicions estàtiques i passar els fulls de forma ràpida per a generar la sensació d’animació.




A la figura de sobre podem veure l’animació de sis marcs o frames d’un gat. Nosaltres ho simplificarem a dos marcs. Al utilitzar Sprites gran part de la gestió ens la farà el VDP, ja que estem utilitzant el que es coneix com a Sptires hardware.


Per a generar l’animació anirem canviat entre els dos Sprites en pantalla a la vegada que anirem movent la coordenada X.





La figura de sobre és el segon Sprites de l’animació. Igual que al primer cas, es tractaria de dos Sprites o un Sprite compost de dos capes.


Ara que ja tenim els dos Sprites del gat, que podem veure a sota, ja podem passar a traslladar aquesta informació per tal de poder-la utilitzar dins de FUSION-C per a fer l’animació. L’animació s’aconseguirà superposant els Sptires de sota a la vegada que els anirem movent per la coordenada X.







Convertint el que hem dibuixat en un llenguatge que l’ordinador entengui


Els nostres Sptires són de 16 píxels horitzontal i de 16 píxels verticals o sigui de 16x16. En FUSION-C hem decidir traslladar la informació amb patrons de text de 8x8 quedant l’Sprite dividit en quatre patrons de la següent manera:





Traslladarem la informació del dibuix a l’ordinador fent servir el sistema binari. Un 1 indica que hi ha un pixel i un 0 indica absència de pixel.


En el cas del primer marc de moviment del gat, com hem dit que està compost de dos capes o Sprites, necessitem de 8 patrons de 8x8 per a general aquest marc.


El resultat traslladat a FUSION-C de la primera capa de l’Sprite del primer marc serien els quatre patrons de més avall.



static const unsigned char body_idle_pattern_right_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00011000,
  0b00100000
};

static const unsigned char body_idle_pattern_right_2[] = {
  0b00100000,
  0b00100011,
  0b00011111,
  0b00001111,
  0b00000111,
  0b00000110,
  0b00000010,
  0b00000000
};

static const unsigned char body_idle_pattern_right_3[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char body_idle_pattern_right_4[] = {
  0b00010100,
  0b10011010,
  0b11110000,
  0b11110000,
  0b11110000,
  0b00111000,
  0b00100000,
  0b00000000
};

Per tal de definir l’Sprite a FUSION-C hem d’utilitzar la funció SetSpritePattern on li passarem tres paràmetres, el número de patró, l’array del patró i el nombre de linies del patró.


Per el nostre primer Sprite consistent en la primera capa del primer marc de l’animació quedaria tal com es mostra més avall.


SetSpritePattern( 0, body_idle_pattern_right_1,8 );
SetSpritePattern( 1, body_idle_pattern_right_2,8 );
SetSpritePattern( 2, body_idle_pattern_right_3,8 );
SetSpritePattern( 3, body_idle_pattern_right_4,8 );


Encara ens falta traslladar la informació del color. Sense la informació del color el nostre Sprite es veuria de la següent manera si el carreguessim.


Definit la paleta de colors que utilitzarem


Primer de tot hem de pasar la paleta de color a utilitzar a FUSION-C. Que en el cas de MSX serà una paleta de 16 colors. Per fer-ho definirem un array on carregarem 4-tuples de dades amb el següent format:


Número del color de la paleta de MSX

R component vermell amb decimals

G component verd amb decimals

B component blau amb decimals


Els valors de R,G i B poden anar des del 0 fins al 7


Pel nostre exemple hem fet servir la paleta de colors de MSX1, que en FUSION-C definirem dins un array quedant de la manera que podem veure més avall.


char mypalette[] = {
      0, 0,0,0, // transparent 
      1, 1,1,1, // black
      2, 1.7,5,2, // medium green
      3, 3.1,5.7,3.4, // light green 
      4, 2.4,2.3,6.1, // dark blue
      5, 3.5,3.2,6.6, // light blue 
      6, 5,2.5,2.2, // dark red
      7, 2.7,6,6.5, // cyan
      8, 6,2.7,2.4, // medium red
      9, 7,3.7,3.4, // light red
      10, 5.6,5.3,2.5, // dark yellow
      11, 6,5.7,3.7, // light yellow
      12, 1.5,4.4,1.7, // dark green
      13, 5,2.8,4.9, // magenta
      14, 5.6,5.6,5.6, // gray
      15, 7,7,7 // white
    };


Colorejant els Sprites


Un cop definida la paleta caldrà traslladar la informació de color als Sptires. Per colorejar els Sprites utilitzarem la funció de FUSION-C SC5SpriteColors. Aquesta funció agafa com a paràmetres el número d’Sprite a colorejar i un array on es defineix per a cada línia de l’Sprite el seu color.


Els arrays amb la informació de color de les línies de l’Sprite tenen el següent format.


char LineColorsLayer4[16]= { 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4  };
char LineColorsLayer14[16]= { 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14 };


Aquí hem definit els colors de les dues capes o Sprites del primer marc de l’animació. La primera capa agafa el color blau fosc (dark blue) i la segona capa agafa el color gris (gray) de la paleta definida més amunt.



SC5SpriteColors(1,LineColorsLayer4);
SC5SpriteColors(2,LineColorsLayer14)


Aquí estem carregant la informació del color al primer i al segon sprite del primer marc de l'animació que es corresponen la primera i segona capes de l’sprite.



El bucle de joc


Per tal que el programa estigui tot el temps atent del que fem nosaltres, ha d’estar tota l’estona executant-se. M’entre s’està executant, en el nostre cas pasticular, el programa anirà comprovant si s’ha premut ESC per sortir, o si s’han premut els cursors o la barra d'espai, per moure o fer saltar el nostre sprite. A mesura que anem avançant tornarem a comentar el concepte del bucle de joc.


Tot el codi que ara passarem a explicar quedarà emmarcat dins aquest bucle de programa, que s'està executant infinitament fins que es premi la tecla ESC que es correspon al codi de tecla 27.



// Game loop
while (Inkey()!=27)
{  

…

  Screen(0);
  Exit(0);
}


Movent l’Sprite del gat per pantalla


Inicialitzem la posició de l’sprite del gat amb la funció PutSprite fora del bucle del joc. La funció agafa com a paràmetres el númer de l’sprite, el patró d’inici, la posició x i la y en pantalla i el color de l’sprite. En MSX2 els color vindran definits tal com hem explicat abans i aquest valor no tindrà cap efecte.



  x=79;
  y=50;

  PutSprite (1,0,x,y,4);
  PutSprite (2,4,x,y,14);


El resultat d’haver posicionat l’sprite del gat a la posició x=79 i y=50 seria el de la imatge de més avall.





Ara que tenim posicionat el gat hem de fer que al prémer els cursos esquerra i dret el gat es mogui cap a la dreta o es giri cap a l’esquerra. Això ho aconseguim amb el codi de más avall.



// Game loop
  while (Inkey()!=27)
  {  
    stick = JoystickRead(0);
    space = TriggerRead(0);



      // Right
      if(stick==3)
      {
        
        x=(x+1);
        x=screen_limits_x(x);

        if( x % 2 == 0) 
        {
          PutSprite (1,0,x,y,4);
          PutSprite (2,4,x,y,14);
        }

        if( x % 2 == 1) 
        {
          PutSprite (1,8,x,y,4);
          PutSprite (2,12,x,y,14);          
        }
        FT_wait(10);
      }


      // Right
      if(stick==7)
      {

        x=(x-1);
        x=screen_limits_x(x);

        if( x % 2 == 0) 
        {
          PutSprite (1,16,x,y,4);
          PutSprite (2,20,x,y,14);
        }

        if( x % 2 == 1) 
        {
          PutSprite (1,24,x,y,4);
          PutSprite (2,28,x,y,14);
        }
        FT_wait(10);
      }


  }
  Screen(0);
  Exit(0);
}


Al tros de codi de més amunt podem veure el control del moviment del gat cap a l’esquerra i cap a la dreta.


A la funció JoystickRead si li passem el paràmetre 0 llegirem l’estat dels cursors premuts. Carregarem el resultat de la funció a la variable stick per a poder decidir les accions segons el que hàgim premut al codi de més avall.


Analitzant el tros de codi on stick=3, que indica que el cursor premut és l’esquerra, podem veure com canviem el conjunt dels dos Sprites que composen un gat en funció de si la coordenada x es senar o parell. Això ho fem amb la divisió entera de la coordenada x per 2.


Els valors possibles que podrà agafar stick seran els següents.

0

inactiu

1

amunt

2

amunt + dreta

3

dreta

4

dreta + avall

5

avall

6

avall + esquerra

7

esquerra

8

esquerra + amunt





Tot seguit us deixo el llistat del codi així com un enllaç d’una imatge de disc per a poder-ho executar directament.



//
// Fusion-C
// Example : Moving Sam Garcia The Cat 16x16 Sprites
//
#include "fusion-c/header/vdp_graph2.h"
#include "fusion-c/header/msx_fusion.h"
#include "fusion-c/header/vdp_sprites.h"
#include <stdio.h>
#include <string.h>
#include <math.h>

/* --------------------------------------------------------- */
/*  SPRITEs of Sam Garcia The Cat                            */
/* ========================================================= */

static const unsigned char body_idle_pattern_right_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00011000,
  0b00100000
};

static const unsigned char body_idle_pattern_right_2[] = {
  0b00100000,
  0b00100011,
  0b00011111,
  0b00001111,
  0b00000111,
  0b00000110,
  0b00000010,
  0b00000000
};

static const unsigned char body_idle_pattern_right_3[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char body_idle_pattern_right_4[] = {
  0b00010100,
  0b10011010,
  0b11110000,
  0b11110000,
  0b11110000,
  0b00111000,
  0b00100000,
  0b00000000
};

static const unsigned char detail_idle_pattern_right_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_idle_pattern_right_2[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000001,
  0b00000000,
  0b00000000
};

static const unsigned char detail_idle_pattern_right_3[] = {  
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_idle_pattern_right_4[] = {
  0b00000000,
  0b00000100,
  0b00001110,
  0b00001110,
  0b00001100,
  0b10000100,
  0b10011000,
  0b00000000
};

static const unsigned char body_walk_pattern_right_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00110000
};

static const unsigned char body_walk_pattern_right_2[] = {
  0b01000000,
  0b01000001,
  0b00100011,
  0b00011111,
  0b00001111,
  0b00011100,
  0b00110000,
  0b00100000
};

static const unsigned char body_walk_pattern_right_3[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00010100
};

static const unsigned char body_walk_pattern_right_4[] = {
  0b00011010,
  0b00010000,
  0b10110000,
  0b11110000,
  0b11111000,
  0b11101100,
  0b00000100,
  0b00000000
};

static const unsigned char detail_walk_pattern_right_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_walk_pattern_right_2[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000010,
  0b00001100,
  0b00001000
};

static const unsigned char detail_walk_pattern_right_3[] = {  
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_walk_pattern_right_4[] = {
  0b00000100,
  0b00001110,
  0b00001110,
  0b00001100,
  0b00000100,
  0b00000010,
  0b00000010,
  0b00000000
};

static const unsigned char body_idle_pattern_left_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char body_idle_pattern_left_2[] = {
  0b00101000,
  0b01011001,
  0b00001111,
  0b00001111,
  0b00001111,
  0b00011100,
  0b00000100,
  0b00000000
};

static const unsigned char body_idle_pattern_left_3[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00011000,
  0b00000100
};

static const unsigned char body_idle_pattern_left_4[] = {
  0b00000100,
  0b11000100,
  0b11111000,
  0b11110000,
  0b11100000,
  0b01100000,
  0b01000000,
  0b00000000
};

static const unsigned char detail_idle_pattern_left_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_idle_pattern_left_2[] = {
  0b00000000,
  0b00100000,
  0b01110000,
  0b01110000,
  0b00110000,
  0b00100001,
  0b00011001,
  0b00000000
};

static const unsigned char detail_idle_pattern_left_3[] = {  
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_idle_pattern_left_4[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b10000000,
  0b00000000,
  0b00000000
};

static const unsigned char body_walk_pattern_left_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00101000
};

static const unsigned char body_walk_pattern_left_2[] = {
  0b01011000,
  0b00001000,
  0b00001101,
  0b00001111,
  0b00011111,
  0b00110111,
  0b00100000,
  0b00000000
};

static const unsigned char body_walk_pattern_left_3[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00001100
};

static const unsigned char body_walk_pattern_left_4[] = {
  0b00000010,
  0b00000010,
  0b11000100,
  0b11111000,
  0b11110000,
  0b00111000,
  0b00001100,
  0b00000100
};

static const unsigned char detail_walk_pattern_left_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_walk_pattern_left_2[] = {
  0b00100000,
  0b01110000,
  0b01110000,
  0b00110000,
  0b00100000,
  0b01000000,
  0b01000000,
  0b00000000
};

static const unsigned char detail_walk_pattern_left_3[] = { 
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_walk_pattern_left_4[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b01000000,
  0b00110000,
  0b00010000
};

static const unsigned char body_impuls_pattern_right_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00110000
};

static const unsigned char body_impuls_pattern_right_2[] = {
  0b00100000,
  0b00100000,
  0b00100011,
  0b00111111,
  0b00011111,
  0b00001111,
  0b00001000,
  0b00011000
};

static const unsigned char body_impuls_pattern_right_3[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00010100
};

static const unsigned char body_impuls_pattern_right_4[] = {
  0b00011100,
  0b00010100,
  0b00100000,
  0b11100000,
  0b11100000,
  0b11100000,
  0b00100000,
  0b00100000
};

static const unsigned char detail_impuls_pattern_right_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_impuls_pattern_right_2[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000110,
  0b00000100
};

static const unsigned char detail_impuls_pattern_right_3[] = { 
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_impuls_pattern_right_4[] = {
  0b00000000,
  0b00001000,
  0b00011100,
  0b00011100,
  0b00011000,
  0b00010000,
  0b00011000,
  0b00001000
};

static const unsigned char body_salt_pattern_right_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00100000
};

static const unsigned char body_salt_pattern_right_2[] = {
  0b00100000,
  0b00110000,
  0b00110011,
  0b00011111,
  0b00001111,
  0b00000110,
  0b00001100,
  0b00001000
};

static const unsigned char body_salt_pattern_right_3[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00101000,
  0b00111000,
  0b00110100
};

static const unsigned char body_salt_pattern_right_4[] = {
  0b00100000,
  0b01100000,
  0b11100000,
  0b11100000,
  0b11100000,
  0b00100000,
  0b01100000,
  0b00000000
};

static const unsigned char detail_salt_pattern_right_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_salt_pattern_right_2[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000001,
  0b00000010,
  0b00000110
};

static const unsigned char detail_salt_pattern_right_3[] = { 
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00001000
};

static const unsigned char detail_salt_pattern_right_4[] = {
  0b00011100,
  0b00011100,
  0b00011100,
  0b00011100,
  0b00011000,
  0b00001000,
  0b00001000,
  0b00000000
};

static const unsigned char body_impuls_pattern_left_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00101000
};

static const unsigned char body_impuls_pattern_left_2[] = {
  0b00111000,
  0b00101000,
  0b00000100,
  0b00000111,
  0b00000111,
  0b00000111,
  0b00000100,
  0b00000100
};

static const unsigned char body_impuls_pattern_left_3[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00001100
};

static const unsigned char body_impuls_pattern_left_4[] = {
  0b00000100,
  0b00000100,
  0b10000100,
  0b11111100,
  0b11111000,
  0b11110000,
  0b00010000,
  0b00011000
};

static const unsigned char detail_impuls_pattern_left_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_impuls_pattern_left_2[] = {
  0b00000000,
  0b00010000,
  0b00111000,
  0b00111000,
  0b00011000,
  0b00001000,
  0b00011000,
  0b00010000
};

static const unsigned char detail_impuls_pattern_left_3[] = { 
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_impuls_pattern_left_4[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b01100000,
  0b00100000
};

static const unsigned char body_salt_pattern_left_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00101000,
  0b00111000,
  0b00101100
};

static const unsigned char body_salt_pattern_left_2[] = {
  0b00000100,
  0b00000110,
  0b00000111,
  0b00000111,
  0b00000111,
  0b00000100,
  0b00000110,
  0b00000000
};

static const unsigned char body_salt_pattern_left_3[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000100
};

static const unsigned char body_salt_pattern_left_4[] = {
  0b00000100,
  0b00001100,
  0b11001100,
  0b11111000,
  0b11110000,
  0b01100000,
  0b00110000,
  0b00010000
};

static const unsigned char detail_salt_pattern_left_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00010000
};

static const unsigned char detail_salt_pattern_left_2[] = {
  0b00111000,
  0b00111000,
  0b00111000,
  0b00111000,
  0b00011000,
  0b00010000,
  0b00010000,
  0b00000000
};

static const unsigned char detail_salt_pattern_left_3[] = { 
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char detail_salt_pattern_left_4[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b10000000,
  0b01000000,
  0b01100000
};

/* --------------------------------------------------------- */
/*  SPRITE energia Sam Garcia The Cat                        */
/* ========================================================= */

static const unsigned char energia_pattern_1[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char energia_pattern_2[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00100000,
  0b11000000,
  0b11000000
};

static const unsigned char energia_pattern_3[] = { 
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char energia_pattern_4[] = {
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000100,
  0b00000011,
  0b00000011
};

// Functions prototypes
char FT_wait(int);
int screen_limits_x(int);
int screen_limits_y(int);

/* --------------------------------------------------------- */
char FT_wait(int cicles)
{
  int i;
  for(i=0;i<cicles;i++) 
  {
    EnableInterupt();
    Halt();
  }
  return(0);
}

int screen_limits_x(int x)
{
  if( x < 0) 
  {
   x=0;
  }

  if(x > 200)
  {
   x=200; 
  }
  return x;
}

int screen_limits_y(int y)
{
  if( y < 0) 
  {
   y=0;
  }

  if(y > 160)
  {
   y=160; 
  }
  return y;
}

/* --------------------------------------------------------- */
void main( void ) {
    int x;
    int y;

    char strx[6];
    char stry[6];

    char stick;
    char space;    

    char mypalette[] = {
      0, 0,0,0, // transparent 
      1, 1,1,1, // black
      2, 1.7,5,2, // medium green
      3, 3.1,5.7,3.4, // light green 
      4, 2.4,2.3,6.1, // dark blue
      5, 3.5,3.2,6.6, // light blue 
      6, 5,2.5,2.2, // dark red
      7, 2.7,6,6.5, // cyan
      8, 6,2.7,2.4, // medium red
      9, 7,3.7,3.4, // light red
      10, 5.6,5.3,2.5, // dark yellow
      11, 6,5.7,3.7, // light yellow
      12, 1.5,4.4,1.7, // dark green
      13, 5,2.8,4.9, // magenta
      14, 5.6,5.6,5.6, // gray
      15, 7,7,7 // white
    };
    
    char LineColorsLayer4[16]= { 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4  };
    char LineColorsLayer14[16]= { 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14 };
    
    char LineColorsLayer12[16]= { 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12 };
    char LineColorsLayer3[16]= { 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 };
    char LineColorsLayer2[16]= { 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 };
    char LineColorsLayer1[16]= { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 };


    x=79;
    y=50;

   
  if(ReadMSXtype()==3)  // IF MSX is Turbo-R Switch CPU to Z80 Mode
    {
       ChangeCPU(0);
    }
  
  SetColors(15,1,1);
  Screen(5);

  SetSC5Palette((Palette *)mypalette);
  
  SpriteReset();

  SpriteDouble();
  
  // The 16 x 16 pixels Sprite is made of 4 patterns

  SetSpritePattern( 0, body_idle_pattern_right_1,8 );
  SetSpritePattern( 1, body_idle_pattern_right_2,8 );
  SetSpritePattern( 2, body_idle_pattern_right_3,8 );
  SetSpritePattern( 3, body_idle_pattern_right_4,8 );

  SetSpritePattern( 4, detail_idle_pattern_right_1,8 );
  SetSpritePattern( 5, detail_idle_pattern_right_2,8 );
  SetSpritePattern( 6, detail_idle_pattern_right_3,8 );
  SetSpritePattern( 7, detail_idle_pattern_right_4,8 );

  SetSpritePattern( 8, body_walk_pattern_right_1,8 );
  SetSpritePattern( 9, body_walk_pattern_right_2,8 );
  SetSpritePattern( 10, body_walk_pattern_right_3,8 );
  SetSpritePattern( 11, body_walk_pattern_right_4,8 );

  SetSpritePattern( 12, detail_walk_pattern_right_1,8 );
  SetSpritePattern( 13, detail_walk_pattern_right_2,8 );
  SetSpritePattern( 14, detail_walk_pattern_right_3,8 );
  SetSpritePattern( 15, detail_walk_pattern_right_4,8 );

  SetSpritePattern( 16, body_idle_pattern_left_1,8 );
  SetSpritePattern( 17, body_idle_pattern_left_2,8 );
  SetSpritePattern( 18, body_idle_pattern_left_3,8 );
  SetSpritePattern( 19, body_idle_pattern_left_4,8 );

  SetSpritePattern( 20, detail_idle_pattern_left_1,8 );
  SetSpritePattern( 21, detail_idle_pattern_left_2,8 );
  SetSpritePattern( 22, detail_idle_pattern_left_3,8 );
  SetSpritePattern( 23, detail_idle_pattern_left_4,8 );

  SetSpritePattern( 24, body_walk_pattern_left_1,8 );
  SetSpritePattern( 25, body_walk_pattern_left_2,8 );
  SetSpritePattern( 26, body_walk_pattern_left_3,8 );
  SetSpritePattern( 27, body_walk_pattern_left_4,8 );

  SetSpritePattern( 28, detail_walk_pattern_left_1,8 );
  SetSpritePattern( 29, detail_walk_pattern_left_2,8 );
  SetSpritePattern( 30, detail_walk_pattern_left_3,8 );
  SetSpritePattern( 31, detail_walk_pattern_left_4,8 );

  SetSpritePattern( 32, body_impuls_pattern_right_1,8 );
  SetSpritePattern( 33, body_impuls_pattern_right_2,8 );
  SetSpritePattern( 34, body_impuls_pattern_right_3,8 );
  SetSpritePattern( 35, body_impuls_pattern_right_4,8 );

  SetSpritePattern( 36, detail_impuls_pattern_right_1,8 );
  SetSpritePattern( 37, detail_impuls_pattern_right_2,8 );
  SetSpritePattern( 38, detail_impuls_pattern_right_3,8 );
  SetSpritePattern( 39, detail_impuls_pattern_right_4,8 );

  SetSpritePattern( 40, energia_pattern_1,8 );
  SetSpritePattern( 41, energia_pattern_2,8 );
  SetSpritePattern( 42, energia_pattern_3,8 );
  SetSpritePattern( 43, energia_pattern_4,8 );

  SetSpritePattern( 44, body_salt_pattern_right_1,8 );
  SetSpritePattern( 45, body_salt_pattern_right_2,8 );
  SetSpritePattern( 46, body_salt_pattern_right_3,8 );
  SetSpritePattern( 47, body_salt_pattern_right_4,8 );

  SetSpritePattern( 48, detail_salt_pattern_right_1,8 );
  SetSpritePattern( 49, detail_salt_pattern_right_2,8 );
  SetSpritePattern( 50, detail_salt_pattern_right_3,8 );
  SetSpritePattern( 51, detail_salt_pattern_right_4,8 );

  SetSpritePattern( 52, body_impuls_pattern_left_1,8 );
  SetSpritePattern( 53, body_impuls_pattern_left_2,8 );
  SetSpritePattern( 54, body_impuls_pattern_left_3,8 );
  SetSpritePattern( 55, body_impuls_pattern_left_4,8 );

  SetSpritePattern( 56, detail_impuls_pattern_left_1,8 );
  SetSpritePattern( 57, detail_impuls_pattern_left_2,8 );
  SetSpritePattern( 58, detail_impuls_pattern_left_3,8 );
  SetSpritePattern( 59, detail_impuls_pattern_left_4,8 );

  SetSpritePattern( 60, body_salt_pattern_left_1,8 );
  SetSpritePattern( 61, body_salt_pattern_left_2,8 );
  SetSpritePattern( 62, body_salt_pattern_left_3,8 );
  SetSpritePattern( 63, body_salt_pattern_left_4,8 );

  SetSpritePattern( 64, detail_salt_pattern_left_1,8 );
  SetSpritePattern( 65, detail_salt_pattern_left_2,8 );
  SetSpritePattern( 66, detail_salt_pattern_left_3,8 );
  SetSpritePattern( 67, detail_salt_pattern_left_4,8 );

  SC5SpriteColors(1,LineColorsLayer4);
  SC5SpriteColors(2,LineColorsLayer14);
  SC5SpriteColors(3,LineColorsLayer12);

  Sprite16();
  
  // Printing initial coordinates on the Screen
  PutText(0,10,"SCREEN 5",0);  
    
  sprintf(strx, "%i", x);
  sprintf(stry, "%i", y);
  
  PutText(83,10,"(",0);
  PutText(91,10,strx,0);
  PutText(113,10,",",0);
  PutText(122,10,stry,0);
  PutText(144,10,")",0);

  // Positioning Sam on the Screen
  PutSprite (1,0,x,y,4);
  PutSprite (2,4,x,y,14);

  // Game loop
  while (Inkey()!=27)
  {  
    stick = JoystickRead(0);
    space = TriggerRead(0);

      // Idle
      if(stick!=0) {
        
        sprintf(strx, "%i", x);
        sprintf(stry, "%i", y);
        
        PutText(83,10,"(",0);
        PutText(91,10,strx,0);
        PutText(113,10,",",0);
        PutText(122,10,stry,0);
        PutText(144,10,")",0);        

      }
      
      // Up
      if(stick==1)
      {        
        y=(y-1);

        PutSprite (1,0,x,y,4);
        PutSprite (2,4,x,y,14);

        FT_wait(10);
      }

      // Right
      if(stick==3)
      {
        
        x=(x+1);
        x=screen_limits_x(x);

        if( x % 2 == 0) 
        {
          PutSprite (1,0,x,y,4);
          PutSprite (2,4,x,y,14);
        }

        if( x % 2 == 1) 
        {
          PutSprite (1,8,x,y,4);
          PutSprite (2,12,x,y,14);          
        }
        FT_wait(10);
      }

      // Down
      if(stick==5)
      {        
        y=(y+1);

        PutSprite (1,0,x,y,4);
        PutSprite (2,4,x,y,14);

        FT_wait(10);
      }

      // Right
      if(stick==7)
      {

        x=(x-1);
        x=screen_limits_x(x);

        if( x % 2 == 0) 
        {
          PutSprite (1,16,x,y,4);
          PutSprite (2,20,x,y,14);
        }

        if( x % 2 == 1) 
        {
          PutSprite (1,24,x,y,4);
          PutSprite (2,28,x,y,14);
        }
        FT_wait(10);
      }

      // Button A
      if(space==255 && stick==3)
      {
          PutSprite (1,32,x,y,4);
          PutSprite (2,36,x,y,14);

          FT_wait(10);

          // Impulse
          SC5SpriteColors(3,LineColorsLayer12);
          PutSprite (3,40,x,y,12);
          FT_wait(10);

          SC5SpriteColors(3,LineColorsLayer2);
          PutSprite (3,40,x,y,2);
          FT_wait(10);

          SC5SpriteColors(3,LineColorsLayer3);
          PutSprite (3,40,x,y,3);
          FT_wait(10);          

          SC5SpriteColors(3,LineColorsLayer1);
          PutSprite (3,40,x,y,1);
          FT_wait(10);

          // Jump
          x=x+20;
          y=y-20;

          PutSprite (1,44,x,y,4);
          PutSprite (2,48,x,y,14);

          FT_wait(10);

          // Back to the floor
          y=y+20;

          PutSprite (1,0,x,y,4);
          PutSprite (2,4,x,y,14);

      }
      // Button A
      if(space==255 && stick==7)
      {
          PutSprite (1,52,x,y,4);
          PutSprite (2,56,x,y,14);

          FT_wait(10);

          // Impulse
          SC5SpriteColors(3,LineColorsLayer12);
          PutSprite (3,40,x,y,12);
          FT_wait(10);

          SC5SpriteColors(3,LineColorsLayer2);
          PutSprite (3,40,x,y,2);
          FT_wait(10);

          SC5SpriteColors(3,LineColorsLayer3);
          PutSprite (3,40,x,y,3);
          FT_wait(10);          

          SC5SpriteColors(3,LineColorsLayer1);
          PutSprite (3,40,x,y,1);
          FT_wait(10);

          // Jump
          x=x-20;
          y=y-20;

          PutSprite (1,60,x,y,4);
          PutSprite (2,64,x,y,14);

          FT_wait(10);

          // Back to the floor
          y=y+20;

          PutSprite (1,16,x,y,4);
          PutSprite (2,20,x,y,14);

      }

  }
  Screen(0);
  Exit(0);
}


Clica aquí per a veure l'exemple funcionant.








Comments


bottom of page