Internet de les coses amb ESP32 i ESP8266

Exemples Referència Plaques   Recursos CITCEA
Projectes Programació Perifèrics   Inici
  Enrere

Representació d'sprites a la pantalla bicolor Midas

Els sprites són un tipus especial d'imatges que es poden moure per la pantalla. Hi pot haver diversos sprites a la vegada, ja sigui amb la mateixa imatge o amb imatges diferents. En els exemples que proposem, farem servir dos dibuixos per als sprites, un amb forma de peix i un altre que representa un pop.

pop     peix

A l'igual dels caràcters de les fonts, per definir un sprite haurem de fer una llista amb tants elements com columnes. A cada element tindrem un nombre binari en el qual el bit de menys pes representa la part superior i el de més pes la part inferior.

Per treballar amb sprites podem fer servir les funcions de la biblioteca ssd1306 o els mètodes de l'objecte SPRITE. Comencem primer amb exemples de les funcions de la biblioteca.

El següent programa posa els dos sprites a la pantalla i els va desplaçant, cada un amb un criteri diferent. Quan es superposen dos sprites , el darrer en ser creat taparà l'altre (els píxels no activats es consideren negres, no transparents). El nostre exemple s'ha fet de manera que els sprites mo coincideixin en el mateix punt.

Quan el pop hagi rebotat dos cops a la part dreta de la pantalla es convertirà en peix.

#include "ssd1306.h"
const uint8_t pop[8] PROGMEM = {
  0b11000000,
  0b00100000,
  0b11010110,
  0b00111101,
  0b00111111,
  0b11010110,
  0b00100000,
  0b11000000
};
const uint8_t peix[8] PROGMEM = {
  0b00101000,
  0b00010000,
  0b00101000,
  0b01000100,
  0b01000100,
  0b01001100,
  0b00101000,
  0b00010000
};  
SPRITE spritepop;
SPRITE spritepeix;
int n = 0;
int incXpop = 2;
int incYpop = 1;
int incXpeix = 3;  // El peix només es mou en horitzontal
void setup(){
  ssd1306_128x64_i2c_init();
  ssd1306_fillScreen(0);
  ssd1306_setFixedFont(ssd1306xled_font6x8);
  spritepop = ssd1306_createSprite(0, 50, 8, pop);
  ssd1306_drawSprite(&spritepop);
  spritepeix = ssd1306_createSprite(0, 24, 8, peix);
  ssd1306_drawSprite(&spritepeix);
  ssd1306_printFixed(0, 0, "El fons del mar", STYLE_NORMAL);
}
void loop(){
  if(n == 2){
    ssd1306_replaceSprite(&spritepop, peix);
  }
  spritepop.x = spritepop.x + incXpop;
  spritepop.y = spritepop.y + incYpop;
  if(spritepop.x == (128 - 8)){
    n++;
    incXpop = -incXpop;
  } 
  if (spritepop.x == 0){
    incXpop = -incXpop;
  }
  // El pop es mou entre Y = 48 i Y = 56
  if (spritepop.y <= 48){
    incYpop = -incYpop;
  }
  if (spritepop.y >= 56){
    incYpop = -incYpop;
  }
  spritepeix.x = spritepeix.x + incXpeix;
  // El peix es mou entre Y = 16 i Y = 40
  if(spritepeix.x == (128 - 8)){
    spritepeix.x = 0;  // Torna a sortir
    spritepeix.y = random(24) + 16; // Inici aleatori en el rang
  }
  ssd1306_eraseTrace(&spritepop);
  ssd1306_drawSprite(&spritepop);
  ssd1306_eraseTrace(&spritepeix);
  ssd1306_drawSprite(&spritepeix);
  delay(100);
}

Encara que no és la seva finalitat principal, podem posar un sprite fix en una posició de la pantalla.

#include "ssd1306.h"
const uint8_t pop[8] PROGMEM = {
  0b11000000,
  0b00100000,
  0b11010110,
  0b00111101,
  0b00111111,
  0b11010110,
  0b00100000,
  0b11000000
};
void setup(){
  ssd1306_128x64_i2c_init();
  ssd1306_fillScreen(0);
  ssd1306_setFixedFont(ssd1306xled_font6x8);
  ssd1306_drawSpriteEx(20, 50, 8, pop);
  ssd1306_printFixed(0, 0, "El fons del mar", STYLE_NORMAL);
}
void loop(){
}

Probablement la forma més pràctica de treballar amb els sprites és emprant els mètodes i paràmetres de l'objecte SPRITE.

El següent programa posa els dos sprites a la pantalla i els va desplaçant, cada un amb un criteri diferent. Quan es superposen dos sprites, el darrer en ser creat taparà l'altre (els píxels no activats es consideren negres, no transparents). El nostre exemple s'ha fet de manera que els sprites mo coincideixin en el mateix punt; si ho féssin, el peix passaria per davant (es mostra després) i els seus píxels negres taparien el pop.

En un dels sprites, el peix, fem servir les pròpies coordenades mentre que en el pop guardem les coordenades en variables i fem el posicionament amb la funció setPos.

#include "ssd1306.h"
const uint8_t pop[8] PROGMEM = {
  0b11000000,
  0b00100000,
  0b11010110,
  0b00111101,
  0b00111111,
  0b11010110,
  0b00100000,
  0b11000000
};
const uint8_t peix[8] PROGMEM = {
  0b00101000,
  0b00010000,
  0b00101000,
  0b01000100,
  0b01000100,
  0b01001100,
  0b00101000,
  0b00010000
};  
SPRITE spritepop;
SPRITE spritepeix;
int Xpop = 0;
int Ypop = 50;
int incXpop = 2;
int incYpop = 1;
int incXpeix = 3;  // El peix només es mou en horitzontal
void setup(){
  ssd1306_128x64_i2c_init();
  ssd1306_fillScreen(0);
  ssd1306_setFixedFont(ssd1306xled_font6x8);
  spritepop = ssd1306_createSprite(Xpop, Ypop, 8, pop);
  spritepop.draw();
  spritepeix = ssd1306_createSprite(0, 24, 8, peix);
  spritepeix.draw();
  ssd1306_printFixed(0, 0, "El fons del mar", STYLE_NORMAL);
}
void loop(){
  Xpop = Xpop + incXpop;
  Ypop = Ypop + incYpop;
  if(Xpop == (128 - 8)){
    incXpop = -incXpop;
  } 
  if (Xpop == 0){
    incXpop = -incXpop;
  }
  // El pop es mou entre Y = 48 i Y = 56
  if (Ypop <= 48){
    incYpop = -incYpop;
  }
  if (Ypop >= 56){
    incYpop = -incYpop;
  }
  spritepop.setPos(Xpop, Ypop);
  spritepeix.x = spritepeix.x + incXpeix;
  // El peix es mou entre Y = 16 i Y = 40
  if(spritepeix.x == (128 - 8)){
    spritepeix.x = 0;  // Torna a sortir
    spritepeix.y = random(24) + 16; // Inici aleatori en el rang
  }
  spritepop.eraseTrace();
  spritepop.draw();
  spritepeix.eraseTrace();
  spritepeix.draw();
  delay(100);
}

Llista de les funcions i paràmetres accessibles

Funció Ús Paràmetres Comentaris
SPRITE nomSprite Crea un objecte sprite
Funcions ssd1306_createSprite Crea un sprite Posició x [0 a 127]
Posició y [0 a 63]
Amplada (nombre de columnes)
Vector de la imatge
Cal haver definit un objecte de tipus SPRITE, al
qual li assignarem el que retorna aquesta funció
ssd1306_drawSprite Mostra l'sprite a la pantalla Punter a l'objecte SPRITE
    cal posar   &nomSprite
ssd1306_eraseTrace Esborra la imatge de l'sprite
de la posició anterior
Punter a l'objecte SPRITE
    cal posar   &nomSprite
Quan canviem la posició, l'objecte recorda
l'anterior per poder-lo esborrar
ssd1306_replaceSprite Substitueix la imatge de l'sprite Punter a l'objecte SPRITE
    cal posar   &nomSprite
Vector de la imatge
La nova imatge ha de tenir la mateixa amplada que l'antiga
ssd1306_drawSpriteEx Posa la imatge de l'sprite
en un punt fix de la pantalla
Posició x [0 a 127]
Posició y [0 a 63]
Amplada (nombre de columnes)
Vector de la imatge
La imatge ha de tenir vuit píxels d'alçada
El vector es guarda a la memòria de programa
Paràmetres nomSprite.x Coordenada x de la posició de l'sprite Es pot consultar i modificar
nomSprite.y Coordenada y de la posició de l'sprite Es pot consultar i modificar
nomSprite.w Amplada de l'sprite Nombre de columnes
nomSprite.lx Valor anterior de la coordenada x de la
posició de l'sprite
S'ha de consultar després de moure i abans
d'executar la funció eraseTrace
nomSprite.ly Valor anterior de la coordenada y de la
posició de l'sprite
S'ha de consultar després de moure i abans
d'executar la funció eraseTrace
nomSprite.data Vector que conté l'sprite nomSprite.data[i]
dona la component i del vector
Mètodes nomSprite.draw Mostra l'sprite a la pantalla
nomSprite.eraseTrace Esborra la imatge de l'sprite
de la posició anterior
Quan canviem la posició, l'objecte recorda
l'anterior per poder-lo esborrar
nomSprite.setPos Canvia les coordenades de l'sprite
a una nova posició
Posició x [0 a 127]
Posició y [0 a 63]
No redibuixa l'sprite

 

 

 

 

 

 

 

 

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.