#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
// Définition des broches pour l'écran TFT
#define TFT_CLK 13
#define TFT_MISO 12
#define TFT_MOSI 11
#define TFT_DC 5
#define TFT_CS 4
#define TFT_RST 8
#define ILI9341_BLACK 0x0000 ///< Couleur noir
#define ILI9341_YELLOW 0xFFE0 ///< Couleur jaune
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
const int SEUIL_ACTION_BAS = 15;
const int SEUIL_ACTION_HAUT = 1000;
const int NB_ZONES = 3; // 3 zones pour chaque dimension (3x3)
const int LCD_COLONNES = 10; // Nombre de "colonnes logiques"
const int LCD_LIGNES = 10; // Nombre de "lignes logiques"
const int PIXELS_PAR_COLONNE = 24; // Largeur d'une "colonne logique" en pixels
const int PIXELS_PAR_LIGNE = 32; // Hauteur d'une "ligne logique" en pixels
// === Définition des graphismes personnalisés ===
const uint8_t persoGraphique[] =
{
0b01000010,
0b01100110,
0b00011000,
0b00011000,
0b01111110,
0b01011010,
0b00100100,
0b01000010
};
const uint8_t buissonGraphique[] = {
0b00000, 0b01110, 0b11111, 0b11111,
0b11111, 0b01110, 0b00000, 0b00000
};
const uint8_t clefGraphique[] = {
0b00110, 0b00100, 0b00110, 0b00100,
0b00100, 0b01110, 0b01010, 0b01110
};
// === Structures ===
struct Coordonnees {
int colonne;
int ligne;
};
struct Zone {
Coordonnees positionPerso;
Coordonnees positionClef;
Coordonnees positionBuissons[5];
int nbBuissons;
bool clefPresente;
};
struct Perso {
Coordonnees position;
int vitesse;
unsigned long compteurVitesse;
};
// === Variables globales ===
Zone zones[NB_ZONES][NB_ZONES];
Perso perso = {{0, 0}, 100, 0};
int zoneActuelleX = 1;
int zoneActuelleY = 1;
int J1, J2;
int maxBuisson=10;
// === Données de la carte ===
const int mapBuissons[NB_ZONES][NB_ZONES][9][2] = {
{ // Zone 0,0 {colonne, ligne}
{{1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1},
{6, 1}, {6, 2}, {-1, -1}, {-1, -1}},
{{1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1},
{6, 1}, {6, 2}, {-1, -1}, {-1, -1}},
{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5},
{1, 6}, {1, 7}, {1, 8}, {1,9 }}},
{ // Zone 0,0
{{1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1},
{6, 1}, {6, 2}, {-1, -1}, {-1, -1}},
{{1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1},
{6, 1}, {6, 2}, {-1, -1}, {-1, -1}},
{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5},
{6, 1}, {1, 7}, {1, 8}, {1,9 }}},
{ // Zone 0,0
{{1, 1}, {2, 1}, {3, 1}, {4, 1}, {5, 1},
{6, 1}, {6, 2}, {-1, -1}, {-1, -1}},
{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5},
{6, 1},{6, 2}, {-1, -1}, {-1, -1}},
{{1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5},
{6, 1}, {1, 7}, {1, 8}, {1,9 }}}
};
// === Prototypes de fonctions ===
void initialiserZones();
void initialiserTFT();
void changerZone(int nouvelleZoneX, int nouvelleZoneY, const char* direction = "");
void afficherPersonnage();
void effacerCase(int colonne, int ligne);
void dessinerCase(int colonne, int ligne, uint16_t couleur);
void dessinerBitmap(int colonne, int ligne, const uint8_t* bitmap, uint16_t couleur);
void ramasserObjets();
void deplacementJoystick();
void gererCollisionBuissons();
void deplacerPerso(int dx, int dy);
// === Configuration initiale ===
void setup() {
tft.begin();
//tft.setRotation(1); // Orientation horizontale
initialiserZones();
initialiserTFT();
}
void loop() {
if (millis() > perso.compteurVitesse + perso.vitesse) {
deplacementJoystick();
ramasserObjets();
perso.compteurVitesse = millis();
}
}
// === Initialisation des zones ===
void initialiserZones() {
for (int i = 0; i < NB_ZONES; i++) {
for (int j = 0; j < NB_ZONES; j++) {
zones[i][j].nbBuissons = 0;
zones[i][j].clefPresente = true;
zones[i][j].positionClef = {8, 8};
// Charger les buissons depuis mapBuissons
int buissonIndex = 0;
for (int k = 0; k < 9; k++) {
if (mapBuissons[i][j][k][0] != -1 && mapBuissons[i][j][k][1] != -1) {
zones[i][j].positionBuissons[buissonIndex] = {mapBuissons[i][j][k][0], mapBuissons[i][j][k][1]};
buissonIndex++;
}
}
zones[i][j].nbBuissons = buissonIndex;
}
}
}
// === Initialisation de l'écran TFT ===
void initialiserTFT() {
tft.fillScreen(ILI9341_BLACK);
changerZone(1, 1);
}
// === Dessins sur l'écran ===
void dessinerCase(int colonne, int ligne, uint16_t couleur) {
int x = colonne * PIXELS_PAR_COLONNE;
int y = ligne * PIXELS_PAR_LIGNE;
tft.fillRect(x, y, PIXELS_PAR_COLONNE, PIXELS_PAR_LIGNE, couleur);
}
void effacerCase(int colonne, int ligne) {
dessinerCase(colonne, ligne, ILI9341_BLACK);
}
void dessinerBitmap(int colonne, int ligne, const uint8_t* bitmap, uint16_t couleur) {
int x = colonne * PIXELS_PAR_COLONNE;
int y = ligne * PIXELS_PAR_LIGNE;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (bitmap[i] & (1 << (7 - j))) {
tft.fillRect(x + j*3, y + i*3, 3, 3, couleur); }
}
}
}
void afficherPersonnage() {
dessinerBitmap(perso.position.colonne, perso.position.ligne, persoGraphique, ILI9341_YELLOW);
}
void ramasserObjets() {
Zone &zone = zones[zoneActuelleX][zoneActuelleY];
if (perso.position.colonne == zone.positionClef.colonne &&
perso.position.ligne == zone.positionClef.ligne &&
zone.clefPresente) {
zone.clefPresente = false;
effacerCase(zone.positionClef.colonne, zone.positionClef.ligne);
}
}
void gererCollisionBuissons() {
Zone &zone = zones[zoneActuelleX][zoneActuelleY];
for (int i = 0; i < zone.nbBuissons; i++) {
if (perso.position.colonne == zone.positionBuissons[i].colonne &&
perso.position.ligne == zone.positionBuissons[i].ligne) {
return; // Collision, ne pas bouger
}
}
}
void changerZone(int nouvelleZoneX, int nouvelleZoneY, const char* direction) {
if (nouvelleZoneX < 0 || nouvelleZoneX >= NB_ZONES || nouvelleZoneY < 0 || nouvelleZoneY >= NB_ZONES) {
return;
}
zones[zoneActuelleX][zoneActuelleY].positionPerso = perso.position;
zoneActuelleX = nouvelleZoneX;
zoneActuelleY = nouvelleZoneY;
if (strcmp(direction, "droite") == 0) {
perso.position = {0, perso.position.ligne};
} else if (strcmp(direction, "gauche") == 0) {
perso.position = {LCD_COLONNES - 1, perso.position.ligne};
} else if (strcmp(direction, "haut") == 0) {
perso.position = {perso.position.colonne, LCD_LIGNES - 1};
} else if (strcmp(direction, "bas") == 0) {
perso.position = {perso.position.colonne, 0};
}
tft.fillScreen(ILI9341_BLACK);
Zone &zone = zones[zoneActuelleX][zoneActuelleY];
if (zone.clefPresente) {
dessinerBitmap(zone.positionClef.colonne, zone.positionClef.ligne, clefGraphique, ILI9341_BLUE);
}
for (int i = 0; i < zone.nbBuissons; i++) {
dessinerBitmap(zone.positionBuissons[i].colonne, zone.positionBuissons[i].ligne, buissonGraphique, ILI9341_GREEN);
}
afficherPersonnage();
}
// === Gestion des déplacements ===
void deplacementJoystick() {
J1 = analogRead(1);
J2 = analogRead(0);
if (J1 < SEUIL_ACTION_BAS) {
if (perso.position.ligne < LCD_LIGNES - 1) {
deplacerPerso(0, 1);
} else if (zoneActuelleY < NB_ZONES - 1) {
changerZone(zoneActuelleX, zoneActuelleY + 1, "bas");
}
}
if (J1 > SEUIL_ACTION_HAUT) {
if (perso.position.ligne > 0) {
deplacerPerso(0, -1);
} else if (zoneActuelleY > 0) {
changerZone(zoneActuelleX, zoneActuelleY - 1, "haut");
}
}
if (J2 < SEUIL_ACTION_BAS) {
if (perso.position.colonne < LCD_COLONNES - 1) {
deplacerPerso(1, 0);
} else if (zoneActuelleX < NB_ZONES - 1) {
changerZone(zoneActuelleX + 1, zoneActuelleY, "droite");
}
}
if (J2 > SEUIL_ACTION_HAUT) {
if (perso.position.colonne > 0) {
deplacerPerso(-1, 0);
} else if (zoneActuelleX > 0) {
changerZone(zoneActuelleX - 1, zoneActuelleY, "gauche");
}
}
}
void deplacerPerso(int dx, int dy) {
int nouvelleColonne = perso.position.colonne + dx;
int nouvelleLigne = perso.position.ligne + dy;
Zone &zone = zones[zoneActuelleX][zoneActuelleY];
for (int i = 0; i < zone.nbBuissons; i++) {
if (nouvelleColonne == zone.positionBuissons[i].colonne &&
nouvelleLigne == zone.positionBuissons[i].ligne) {
return;
}
}
if (nouvelleColonne >= 0 && nouvelleColonne < LCD_COLONNES &&
nouvelleLigne >= 0 && nouvelleLigne < LCD_LIGNES) {
effacerCase(perso.position.colonne, perso.position.ligne);
perso.position.colonne = nouvelleColonne;
perso.position.ligne = nouvelleLigne;
afficherPersonnage();
}
}