DIY – Fabriquer un tamagotchi à base d’arduino – tamaguino

DIY – Fabriquer un tamagotchi à base d’arduino – tamaguino

tamagotchi tamaguino

DIY – Fabriquer un tamagotchi à base d’arduino -tamaguino

 

Vous vous souvenez tous de ce jeux sortie dans les années 90? Aujourd’hui en 2022 il est apparemment toujours aussi populaire, ma fille de 9ans nous en à demandé un au noël dernier, bien que je trouve ce jeu amusant, il est aussi couteux et marrant qu’un court instant. Plutôt que d’en acheter un je lui est donc proposé qu’on en fabrique un sur la base du projet Tamaguino  de Mr “Alojz Jakob” vous trouverez toutes ses sources à cette adresse : https://alojzjakob.github.io/Tamaguino/.

Cela m’a permis de commencer à initier ma fille à l’électronique et de passer un moment père et fille 😉 , de plus le jour ou elle voudra passer à autre chose elle pourra le transformer en Tétris ou Space invaders ou tout simplement s’en servir de base pour apprendre à programmer.

Le projet date un peu et je dois avouez que j’ai eu quelque difficulté à faire entrer le programme dans l’Arduino nano qui utilise une grande partie de la mémoire disponible.

Après avoir modifié quelque peu le programme, j’ai ajouté une fonction de sauvegarde en eeprom (manuel pour éviter un nombre d’écriture trop grande) , traduit l’interface, j’ai aussi ajouté la possibilité d’éteindre l’écran et d’activer ou couper le son. Le projet vous intéresse? continuez à lire ce qui suit je vous explique tout.

Sommaire

  1. Matériel nécessaire
  2. Schéma d’implantation
  3. Boîtier
  4. Préparation de l’environnement
    1. Installation du logiciel Arduino
    2. Installation des librairies Arduino
    3. Sélection de la carte et du port de communication
  5. Code
  6. Téléversement
  7. Résultat

1. Matériel nécessaire

  1. Un Arduino Nano
  2. Un écran Oled
  3. 3 boutons poussoirs
  4. Quelques morceaux de câbles
  5. Un interrupteur on/off
  6. Une batterie ( optionnelle mais c’est mieux)
  7. Un pistolet à colle
  8. Un buzzer
  9. Une imprimante 3d pour le boîtier

2. Schéma d’implantation

3. Boîtier

Le boîtier à été réalisé sous Solidworks puis imprimé en PLA rose, pour télécharger les fichiers 3D rendez-vous ici.

4. Préparation de l’environnement

De quoi avons nous besoin:

    • Le logiciel Arduino téléchargeables ici
    • Installé la librairie Adafruit_gfx.h version 1.1.5
    • Installé la librairie Adafruit_SSD1306.h version 1.1.2

4.A. Installation du logiciel Arduino

Personnellement je préfère créer une instance d’Arduino par projet pour évitez les conflits entre les librairies, pour cela téléchargez Arduino au format zip.

télécharger arduino

 

Extrayez l’archive dans un dossier que je nommerais “arduino tamaguino” pour l’exemple, 

 

extarire arduino

 

Créez-y ensuite un dossier nommé “portable” puis dans le dossier portable un dossier “sketchbook”

 

 

Lancez ensuite le logiciel en cliquant sur “arduino.exe”

4.B. Installation des librairies Arduino

Pour ce faire rendez-vous dans le menu Outils > Gérer les bibliothèques.

 

 

Recherchez “Adafruit_GFX”, puis sélectionner la version 1.1.2 et cliquez sur “installer).

 

 

Même manip pour la librairie “Adafruit_ssd1306”.

 

 

4.C Sélection de la carte et du port de communication

Pour sélectionner votre type de carte rendez-vous dans le menu “outils > type de carte” puis cliquer votre carte dans ce cas-ci “Arduino Nano”.

 

 

Sélectionner maintenant le port de communication dans le menu “Outils > port”(n’oubliez pas de relier votre Arduino à l’ordinateur via le câble usb) .

 

 

Vous trouverez ci-dessous le code légèrement modifié par mes soins.

Vous n’avez plus qu’a copié/collé le code dans votre fenêtre principale en prenant le soins de supprimer tout ce qui ci-trouve déjà.

5. Code



#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>
#define OLED_RESET 8
Adafruit_SSD1306 display(OLED_RESET);

const byte button1Pin = 7;
const byte button2Pin = 6;
const byte button3Pin = 5;

const byte sound = 4;

bool button1State = 0;
bool button2State = 0;
bool button3State = 0;
int hi_address = 0;
int hunger_address = 4;
int happiness_address = 8;
int health_address = 12;
int discipline_address = 16;
int weight_address = 20;
int age_address = 24;



// front grass 32x10
const unsigned char grass_front [] PROGMEM = {
  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x08, 0x89, 0xc0, 0x48, 0x5c, 0x50, 0x84,
  0x9c, 0x48, 0x50, 0x22, 0x88, 0x80, 0x44, 0x22, 0x40, 0x84, 0x2e, 0x21, 0x49, 0x24, 0xa4, 0xb1,
};
//grass 2 (dino walking on) 4x8
const unsigned char grass [] PROGMEM = {
  0xff, 0xee, 0xbb, 0x55, 0xaa, 0x11,
};

//trees
const unsigned char trees [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x10, 0x05, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x15, 0x00,
  0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x40, 0x00, 0x55, 0x40, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x15, 0x04, 0x40, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x02, 0xa0, 0x00, 0x00, 0x01, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
  0x00, 0x28, 0x84, 0x24, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x82, 0x00,
  0x00, 0x01, 0x10, 0x00, 0x04, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x20, 0x00, 0x00, 0x00,
  0x41, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x88, 0x82, 0x40, 0x91, 0x04, 0x24,
  0x41, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x44, 0x44, 0x11, 0x04, 0x10, 0x11, 0x04, 0x01, 0x00, 0x00,
  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
  0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x02, 0x10, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x04,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x20, 0x00, 0x01, 0x00,
  0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
};

const unsigned char mountains [] PROGMEM = {
  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
  0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e,
  0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
  0x03, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
  0x07, 0x74, 0x07, 0x80, 0x10, 0x00, 0x00, 0x80, 0x00, 0x06, 0x80, 0x00, 0x00, 0x00, 0x00, 0xd5,
  0x0e, 0xc2, 0x0d, 0xc0, 0x28, 0x01, 0x01, 0xc1, 0x00, 0x1f, 0x40, 0x00, 0x00, 0x00, 0x01, 0x28,
  0x1d, 0x13, 0x1b, 0x60, 0x54, 0x03, 0x83, 0xa3, 0x80, 0x36, 0x20, 0x00, 0x00, 0x00, 0x06, 0xd0,
  0x3a, 0x41, 0xb4, 0x30, 0xe2, 0xcc, 0xf7, 0x57, 0xc0, 0xd8, 0x10, 0x00, 0x00, 0x00, 0x19, 0x20,
  0x68, 0x84, 0x49, 0x19, 0xa1, 0x36, 0x5d, 0x2a, 0xa1, 0xa0, 0x10, 0x00, 0x00, 0x00, 0xe6, 0x40,
  0xd2, 0x10, 0xa4, 0x0c, 0x80, 0x8c, 0x1a, 0x15, 0x57, 0x40, 0x88, 0x00, 0x00, 0x1f, 0x38, 0x80,
  0x49, 0x08, 0x00, 0x06, 0x02, 0xc0, 0x24, 0x18, 0x0b, 0x80, 0x05, 0x0b, 0x8c, 0xe0, 0x23, 0x00,
  0xa0, 0x20, 0x00, 0x11, 0x00, 0x00, 0x48, 0x84, 0x84, 0x02, 0x20, 0x5d, 0xf3, 0x00, 0xcd, 0xc0,
  0x50, 0x00, 0x04, 0x04, 0x01, 0x44, 0x00, 0x00, 0x08, 0x00, 0x00, 0x30, 0x04, 0x07, 0x10, 0x20,
  0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x10,
  0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x01, 0x11, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x20, 0x02,
};


const unsigned char cloud2 [] PROGMEM = {
  0x04, 0x70, 0x18, 0x00, 0x6e, 0xfb, 0x7c, 0xee, 0xff, 0xff, 0xfd, 0xff, 0x6f, 0xfb, 0x38, 0xee,
  0x07, 0x70, 0x52, 0x00,
};



// walking sprites
// walk right
const unsigned char dinoWalk0 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x60, 0x00,
  0x00, 0x00, 0x1f, 0xf1, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xb8, 0x00, 0x00, 0x00, 0x7b, 0xff,
  0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x00, 0x00, 0x03, 0xff, 0x7f, 0xe0, 0x00, 0x00, 0x0f,
  0xf7, 0xde, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x7a, 0x00, 0x00,
};
const unsigned char dinoWalk1 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x60, 0x00,
  0x00, 0x00, 0x1f, 0xf1, 0xf0, 0x00, 0x00, 0x00, 0x37, 0xff, 0xb8, 0x00, 0x00, 0x00, 0x7f, 0xff,
  0xfc, 0x00, 0x00, 0x00, 0xff, 0x7f, 0xd8, 0x00, 0x00, 0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f,
  0xbf, 0xda, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00,
};
const unsigned char dinoWalk2 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x60, 0x00,
  0x00, 0x00, 0x1b, 0xf1, 0xf0, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xb8, 0x00, 0x00, 0x00, 0x7f, 0x7f,
  0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x00, 0x00, 0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f,
  0xbf, 0xfa, 0x00, 0x00, 0x00, 0x7f, 0x78, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x5e, 0x00, 0x00,
};
// walk left
const unsigned char dinoWalk3 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0xe0, 0x00, 0x00,
  0x00, 0x0f, 0x8f, 0xf8, 0x00, 0x00, 0x00, 0x1d, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xde,
  0x00, 0x00, 0x00, 0x1b, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xfe, 0xff, 0xc0, 0x00, 0x00, 0x00,
  0x7b, 0xef, 0xf0, 0x00, 0x00, 0x00, 0x3c, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x5e, 0x3d, 0x00, 0x00,
};
const unsigned char dinoWalk4 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0xe0, 0x00, 0x00,
  0x00, 0x0f, 0x8f, 0xf8, 0x00, 0x00, 0x00, 0x1d, 0xff, 0xec, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xfe,
  0x00, 0x00, 0x00, 0x1b, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
  0x5b, 0xfd, 0xf0, 0x00, 0x00, 0x00, 0x3c, 0x1f, 0xfe, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00,
};
const unsigned char dinoWalk5 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x03, 0xe0, 0x00, 0x00,
  0x00, 0x0f, 0x8f, 0xd8, 0x00, 0x00, 0x00, 0x1d, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0xfe,
  0x00, 0x00, 0x00, 0x1b, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
  0x5f, 0xfd, 0xf0, 0x00, 0x00, 0x00, 0x3c, 0x1e, 0xfe, 0x00, 0x00, 0x00, 0x7a, 0x2f, 0x00, 0x00,
};


/* --------- GAME SPRITES ---------- */
const unsigned char dinoJump [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x60, 0x00,
  0x00, 0x00, 0x1f, 0xf1, 0xf0, 0x00, 0x00, 0x00, 0x3b, 0xff, 0xb8, 0x00, 0x00, 0x00, 0x7f, 0xdf,
  0xfc, 0x00, 0x00, 0x00, 0xff, 0xff, 0xd8, 0x00, 0x00, 0x03, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x0f,
  0xff, 0xfe, 0x00, 0x00, 0x00, 0x7d, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x07, 0x80, 0x00,

};

const unsigned char obstacle1 [] PROGMEM = {
  0x00, 0x00, 0x1e, 0x00, 0x2f, 0x00, 0x5e, 0x80, 0x5f, 0xc0, 0xb7, 0xc0,
};

const unsigned char obstacle2 [] PROGMEM = {
  0x14, 0x00, 0x08, 0x00, 0x52, 0x00, 0x34, 0x00, 0x69, 0x40, 0xf0, 0x80,
};

const unsigned char poop [] PROGMEM = {
  0x80, 0x88, 0x01, 0x81, 0x02, 0xe0, 0x27, 0x10, 0x0b, 0xf0, 0x1c, 0x08,
};


#define WALKSIZE 6
//const unsigned char* const dinoWalk[WALKSIZE] PROGMEM = {
const unsigned char* dinoWalk[WALKSIZE] = {
  dinoWalk0, dinoWalk1, dinoWalk2,
  dinoWalk3, dinoWalk4, dinoWalk5
};
int walkPos = 0;
int walkXPos = 0;
bool walkAnimReverse = false;
bool walkRight = false;
int walkDirOffset = 2;



// EATING

const unsigned char eating1 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
  0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00,
  0x7f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00,
  0x00, 0x03, 0x7c, 0x7f, 0xfe, 0x00, 0x00, 0x02, 0xf9, 0xff, 0xfe, 0x00, 0x00, 0x0c, 0xf3, 0xff,
  0xff, 0x00, 0x00, 0x1f, 0xf4, 0x7f, 0xff, 0x80, 0x00, 0x7f, 0xf0, 0x7f, 0xff, 0xc0, 0x00, 0xff,
  0xf8, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe0,
  0x1f, 0xe7, 0xff, 0xe0, 0xff, 0xe0, 0x3f, 0xdf, 0xff, 0xde, 0xff, 0xf0, 0x7f, 0xbf, 0xff, 0xbf,
  0x7f, 0xf0, 0x7f, 0x7f, 0xfe, 0x77, 0xbf, 0xf8, 0x7f, 0x7f, 0xf9, 0xf7, 0xbf, 0xfc, 0x3f, 0xff,
  0xe7, 0xef, 0xbf, 0xfe, 0x5f, 0xfe, 0x1f, 0x1f, 0xbf, 0xff, 0x67, 0xf1, 0xf9, 0x1f, 0xbf, 0xff,
  0x38, 0x0f, 0xe8, 0x3f, 0xbf, 0xff, 0x1f, 0xff, 0xe0, 0x3f, 0xbf, 0xff, 0x0e, 0xfe, 0x40, 0xbf,
  0x6f, 0xff, 0x04, 0x54, 0x00, 0xff, 0x57, 0xff, 0x00, 0x10, 0x01, 0xfe, 0xab, 0xff, 0x00, 0x18,
  0x01, 0xfd, 0x55, 0xff, 0x00, 0x18, 0x05, 0xfa, 0xaa, 0xff, 0x00, 0x1d, 0x27, 0xf1, 0x55, 0x5f,
  0x00, 0x0f, 0x7f, 0xe0, 0xaa, 0xaf, 0x00, 0x07, 0xff, 0x80, 0x55, 0x57, 0x00, 0x03, 0xfe, 0x00,
  0x2a, 0xab, 0x00, 0x01, 0xf0, 0x00, 0x15, 0x55, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xaa, 0x00, 0x00,
  0x00, 0x00, 0x05, 0x55, 0x00, 0x00, 0x00, 0x00, 0x02, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55,

};
const unsigned char eating2 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
  0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00,
  0x7f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00,
  0x00, 0x03, 0x7c, 0x7f, 0xfe, 0x00, 0x00, 0x02, 0xf9, 0xff, 0xfe, 0x00, 0x00, 0x0c, 0xf3, 0xff,
  0xff, 0x00, 0x00, 0x1f, 0xf4, 0x7f, 0xff, 0x80, 0x00, 0x7f, 0xf0, 0x7f, 0xff, 0xc0, 0x00, 0xff,
  0xf8, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe0,
  0x1f, 0xe7, 0xff, 0xe0, 0xff, 0xe0, 0x3f, 0xdf, 0xff, 0xde, 0xff, 0xf0, 0x7f, 0xbf, 0xff, 0xbf,
  0x7f, 0xf0, 0x7f, 0x7f, 0xfe, 0x77, 0xbf, 0xf8, 0x7f, 0x7f, 0xf9, 0xf7, 0xbf, 0xfc, 0x3f, 0xff,
  0xe7, 0xef, 0xbf, 0xfe, 0x5f, 0xfe, 0x1f, 0x1f, 0xbf, 0xff, 0x67, 0xf1, 0xf9, 0x1f, 0xbf, 0xff,
  0x38, 0x0f, 0xe8, 0x3f, 0xbf, 0xff, 0x1f, 0xff, 0xe1, 0x7f, 0x3f, 0xff, 0x0e, 0xfe, 0x41, 0xfe,
  0xef, 0xff, 0x04, 0xd4, 0x0b, 0xfd, 0x57, 0xff, 0x00, 0xd4, 0x0f, 0xfa, 0xab, 0xff, 0x00, 0x60,
  0x9f, 0xf5, 0x55, 0xff, 0x00, 0x75, 0xff, 0xca, 0xaa, 0xff, 0x00, 0x3f, 0xff, 0x05, 0x55, 0x5f,
  0x00, 0x1f, 0xfc, 0x02, 0xaa, 0xaf, 0x00, 0x07, 0xc0, 0x01, 0x55, 0x57, 0x00, 0x00, 0x00, 0x00,
  0xaa, 0xab, 0x00, 0x00, 0x00, 0x00, 0x15, 0x55, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xaa, 0x00, 0x00,
  0x00, 0x00, 0x05, 0x55, 0x00, 0x00, 0x00, 0x00, 0x02, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55,

};
const unsigned char eating3 [] PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff,
  0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0x00, 0x00, 0x00,
  0x7f, 0xff, 0xf0, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x01, 0xff, 0xff, 0xfc, 0x00,
  0x00, 0x03, 0x7c, 0x7f, 0xfe, 0x00, 0x00, 0x02, 0xf9, 0xff, 0xfe, 0x00, 0x00, 0x0c, 0xf3, 0xff,
  0xff, 0x00, 0x00, 0x1f, 0xf4, 0x7f, 0xff, 0x80, 0x00, 0x7f, 0xf0, 0x7f, 0xff, 0xc0, 0x00, 0xff,
  0xf8, 0xff, 0xff, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xe0,
  0x1f, 0xe7, 0xff, 0xe0, 0xff, 0xe0, 0x3f, 0xdf, 0xff, 0xde, 0xff, 0xf0, 0x7f, 0xbf, 0xff, 0xbf,
  0x7f, 0xf0, 0x7f, 0x7f, 0xfe, 0x77, 0xbf, 0xf8, 0x7f, 0x7f, 0xf9, 0xf7, 0xbf, 0xfc, 0x3f, 0xff,
  0xe7, 0xef, 0xbf, 0xfe, 0x5f, 0xfe, 0x1f, 0xdf, 0xbf, 0xff, 0x67, 0xf1, 0xff, 0x3f, 0xbf, 0xff,
  0x38, 0x0f, 0xfc, 0xff, 0xbf, 0xff, 0x1f, 0xff, 0xf3, 0xff, 0x3f, 0xff, 0x0f, 0xff, 0xcf, 0xfe,
  0xef, 0xff, 0x00, 0x38, 0x3f, 0xf9, 0x57, 0xff, 0x07, 0x83, 0xff, 0xea, 0xab, 0xff, 0x01, 0xff,
  0xfe, 0x15, 0x55, 0xff, 0x00, 0xff, 0xf0, 0x0a, 0xaa, 0xff, 0x00, 0x3f, 0xc0, 0x05, 0x55, 0x5f,
  0x00, 0x00, 0x00, 0x02, 0xaa, 0xaf, 0x00, 0x00, 0x00, 0x05, 0x55, 0x57, 0x00, 0x00, 0x00, 0x02,
  0xaa, 0xab, 0x00, 0x00, 0x00, 0x01, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00,
  0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55,

};


const unsigned char* eating[4] = {
  eating1, eating2, eating3, eating2
};

//const unsigned char apple0 [] PROGMEM = {
const unsigned char apple [] PROGMEM = {
  0x00, 0x01, 0xf0, 0x00, 0x07, 0xe0, 0x00, 0x0f, 0xe0, 0x3f, 0x1f, 0xc0, 0x00, 0xdf, 0x80, 0x00,
  0x20, 0x00, 0x0f, 0xd7, 0xf0, 0x3f, 0xff, 0xfc, 0x7f, 0xff, 0xfe, 0x78, 0xff, 0xfe, 0xf0, 0x7f,
  0xff, 0xe0, 0x7f, 0xff, 0xe0, 0xff, 0xff, 0xf1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xfe, 0x7f, 0xff, 0xfe, 0x3f, 0xff, 0xfc, 0x1f,
  0xff, 0xf8, 0x0f, 0xff, 0xf0, 0x07, 0xc3, 0xe0,
};


const unsigned char steak [] PROGMEM = {
  0x0f, 0xe0, 0x00, 0x3f, 0xf8, 0x00, 0x31, 0xfe, 0x00, 0x6e, 0x7f, 0x00, 0xd1, 0x7f, 0x80, 0xa0,
  0xbf, 0x80, 0xa0, 0xbf, 0xc0, 0xa0, 0xbf, 0xc0, 0xd1, 0x3f, 0xc0, 0xae, 0xff, 0xe0, 0xd1, 0xff,
  0xe0, 0xef, 0xff, 0xe0, 0x77, 0xff, 0xf0, 0x7b, 0xff, 0xd0, 0x3d, 0xff, 0x78, 0x1e, 0xf9, 0xfe,
  0x0f, 0x67, 0xff, 0x07, 0x7f, 0xff, 0x03, 0x9f, 0xfc, 0x03, 0xc3, 0xf9, 0x01, 0xf8, 0xc3, 0x00,
  0xff, 0x1e, 0x00, 0x1f, 0xfe, 0x00, 0x01, 0xfc,
};

const char z = "z";

//ground
int grassXPos = 0;
float treesXPos = -20;
//sky
float couldsXPos = 0;
const int sunRadius = 3;
bool sunOrMoon = false;
const int moonShadow = 2;
float sunXPos = -2 * sunRadius;
//clouds
const int cloud1Width = 64;
float cloud1XPos = display.width() + cloud1Width;


int stars [6][2];




// menus
bool menuOpened = false;
int menu = 0;
int subMenu = 1;
bool menuDepth = false;
bool justOpened = false;
#define MENUSIZE 8
#define STRING_SIZE 11

const char mainMenu[MENUSIZE][8][STRING_SIZE] PROGMEM = {
  {"food", "apple", "steak", "eau", NULL},
  {"jeux", NULL},
  {"dormir", NULL},
  {"laver", NULL},
  {"docteur", NULL},
  {"former", NULL},
  {"stats", "faim", "joie", "santer", "former", "poid", "age", NULL},
  {"settings", "save", NULL},
};

/* ------- PET STATS ------- */

float hunger=EEPROM.read(hunger_address)/100;
float happiness=EEPROM.read(happiness_address)/100;
float health =EEPROM.read(health_address)/100;
float discipline =EEPROM.read(discipline_address)/100;
float weight=EEPROM.read(weight_address)/100;
float age =EEPROM.read(age_address)/100;

//settings


int action = 0;
int setting = 0;

bool notification = false;
int notificationBlink = 0;
bool dead = false;

bool sleeping = false;

//game
bool game = false;
bool paused = false;
bool gameOver = false;
int score = 0;
//int hiScore = EEPROM.read(hi_address);
int level = 0;
bool newHiScore = false;
bool jumping = false;
bool jumpUp = true;
int jumpPos = 0;
bool obstacle1show = false;
bool obstacle2show = false;
int obstacle1XPos = 0;
int obstacle2XPos = 0;


float poopometer = 0;
int poops [3] = {
  0, 0, 0,
};

#define ACTIVATED LOW

void setup() {
  pinMode(button1Pin, INPUT_PULLUP);
  pinMode(button2Pin, INPUT_PULLUP);
  pinMode(button3Pin, INPUT_PULLUP);
  pinMode(sound, OUTPUT);

  randomSeed(analogRead(0));

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();


  tone(sound, 500, 200);
  delay(200);
  tone(sound, 1000, 200);
  delay(400);
  tone(sound, 700, 200);
  delay(200);
  tone(sound, 1100, 200);

  delay(2200);
  // end splash

  display.clearDisplay();
  if (age==0 or age==255)
  {
 hunger = 50;
 happiness = 50;
 health =  50;
 discipline =  50;
 weight = 50;
 age =  1;
}}



void loop() {

  button1State = digitalRead(button1Pin);
  button2State = digitalRead(button2Pin);
  button3State = digitalRead(button3Pin);

  if (!dead) {
    /* -------- MODIFY PET STATS -------- */
    // TODO: different gradients regarding to age
    if (sleeping) {
      hunger -= 0.00005;
      poopometer += 0.00005;
      if (happiness - 0.0001 > 0) {
        happiness -= 0.0001;
      }
      health -= 0.00005 + countPoops() * 0.0001;
      if (discipline - 0.0001 > 0) {
        discipline -= 0.0001;
      }
    }
    else {
      hunger -= 0.00025;
      poopometer += 0.00025;
      if (happiness - 0.0002 > 0) {
        happiness -= 0.0002;
      }
      health -= 0.0001 + countPoops() * 0.0001;
      if (discipline - 0.0002 > 0) {
        discipline -= 0.0002;
      }
      //discipline-=0.02;
    }
    age += 0.000025;
  //  EEPROM.write(age_address, age);

    if (poopometer >= 10) {
      poopometer = countPoops();
      poops[round(poopometer)] = random(20, display.width() + 32);
      tone(sound, 200, 50);

      poopometer = 0;
    }

    if ((hunger > 19.99975 && hunger < 20.00025) || (happiness > 19.9998 && happiness < 20.0002) || (health > 19.9999 && health < 20.0001)) {
      tone(sound, 200, 50);
    }


    if (hunger <= 20 || countPoops() > 0 || happiness <= 20 || health <= 20) {
      notification = true;
    }
    if (hunger > 20 && countPoops() == 0 && happiness > 20 && health > 20) {
      notification = false;

    }

    if (hunger <= 0 || health <= 0 || happiness <= 0) {
      dead = true;

      tone(sound, 500, 500);
      delay(550);
      tone(sound, 400, 500);
      delay(550);
      tone(sound, 300, 600);

    }


    display.clearDisplay();
    display.setCursor(0, 0);


    /* ------- BUTTON PRESS ACTIONS ------- */

    /* ------- BUTTON 1 - MENU ------- */
    if (button1State == ACTIVATED) {

      // JUMP IN GAME
      if (game) {

        if (!jumping && !paused) {
          tone(sound, 200, 50);
          jumping = true;
        }

      } else {
        // MENU
        tone(sound, 300, 80);
        if (!menuOpened) {
          menuOpened = true;
        } else {
          if (menuDepth) {

            if ((const char*)pgm_read_word(&(mainMenu[menu][subMenu + 1])) == NULL) {
              subMenu = 1;
            } else {
              ++subMenu;
            }
            setting = 100 * (menu + 1) + subMenu;
          } else {
            if (menu == MENUSIZE - 1) {
              menu = 0;
            } else {
              ++menu;
            }

            if ((const char*)pgm_read_word(&(mainMenu[menu][1])) != NULL) {
              subMenu = 1;

              justOpened = true;
            }
            setting = 100 * (menu + 1) + subMenu;
          }
        }

        delay(60);

      }

    }
    /* ------- BUTTON 2 - SELECT ------- */
    if (button2State == ACTIVATED) {

      if (game) {
        if (!gameOver) {
          paused = !paused;
          tone(sound, 600, 80);
          delay(60);
        }

      } else {
        tone(sound, 600, 80);

        if (menuOpened) {

          if (subMenu != 1 && (const char*)pgm_read_word(&(mainMenu[menu][1][0])) != NULL) {
            action = 100 * (menu + 1) + subMenu;
          }
          if (subMenu == 1 && (const char*)pgm_read_word(&(mainMenu[menu][1][0])) == NULL) {
            action = 100 * (menu + 1) + subMenu;
          }
          if (subMenu == 1 && (const char*)pgm_read_word(&(mainMenu[menu][1][0])) != NULL && menuDepth) {
            action = 100 * (menu + 1) + subMenu;
          }
          if ((const char*)pgm_read_word(&(mainMenu[menu][1][0])) != NULL) {
            setting = 100 * (menu + 1) + subMenu;
            menuDepth = true;
          }

        } else {
          action = NULL;

          menuOpened = true;
          menuDepth = true;
          subMenu = 1;
          menu = 6;
          action = 701;
          setting = 701;
        }
        justOpened = false;

        delay(60);

      }

    }
    /* ------- BUTTON 3 - BACK ------- */
    if (button3State == ACTIVATED) {
      tone(sound, 1000, 80);

      if (game || gameOver) {
        walkPos = 0;
        walkXPos = 0;
        walkAnimReverse = false;
        walkRight = true;
        walkDirOffset = 0;
        treesXPos = -20;
        grassXPos = 0;
        obstacle1show = false;
        obstacle2show = false;
        jumping = false;
        jumpPos = 0;
        jumpUp = true;
        game = false;
        score = 0;
        newHiScore = false;
        gameOver = false;
        level = 0;
        paused = false;
      } else {
        if (!menuDepth) {
          menuOpened = false;
          menu = 0;
          setting = 0;
        } else {
          menuDepth = false;
          setting = 100 * (menu + 1) + 1;
        }
        action = NULL;
        subMenu = 1;
      }


      delay(60);
    }



    /* ------- SCENERY AND WALKING ------- */

    //draw sun
    sunXPos += 0.1;
    if (sunXPos > display.width() + 2 * sunRadius) {
      sunXPos = -2 * sunRadius;
      sunOrMoon = !sunOrMoon;
    }
    if (sleeping) {
      sunOrMoon = true;
    }

    if (sleeping) {
      sunOrMoon = true;
    }

    if (!sunOrMoon) {
      display.fillCircle(sunXPos, 2 * sunRadius, sunRadius, WHITE);
    } else {
      display.fillCircle(sunXPos, 2 * sunRadius, sunRadius, WHITE);
      display.fillCircle(sunXPos - moonShadow, 2 * sunRadius, sunRadius, BLACK);
      //if(walkPos == 5){
      if (round(cloud1XPos) % 5 == 0) {
        for (int i = 0; i < 6; i++) {
          stars[i][0] = random(0, display.width());
          stars[i][1] = random(0, 10);
        }
      } else {
        for (int i = 0; i < 6; i++) {

          display.drawPixel(stars[i][0], stars[i][1], WHITE);
        }
      }
    }

    //cloud 1
    cloud1XPos -= 0.3;
    if (cloud1XPos < -cloud1Width) {
      cloud1XPos = display.width() + cloud1Width;
    }
    display.drawBitmap(cloud1XPos, 5, cloud2 , cloud1Width, 5, WHITE);


    //mountains
    display.drawBitmap(0, 7, mountains , 128, 16, WHITE);

    //walk and move ground perspective

    if (game) {


      /* ------ GAME -----*/
      level = round(score / 10);

      if (jumping && !gameOver && !paused) {
        if (jumpUp) {
          jumpPos = jumpPos + 1 + level;
          if (jumpPos >= 12) {
            jumpUp = false;
          }
        } else {
          //jumpPos--;
          jumpPos = jumpPos - 1 - level;
          if (jumpPos <= 0) {
            jumpUp = true;
            jumping = false;
            tone(sound, 100, 50);
            score += 1;
          }
        }
      }


      if (!gameOver && !paused) {
        if (walkAnimReverse) {
          walkPos -= 1;
          if (walkPos == -1) {
            walkPos = 0;
            walkAnimReverse = false;
          }
        } else {
          walkPos += 1;
          if (walkPos == 3) {
            walkPos = 2;
            walkAnimReverse = true;
          }
        }



        walkXPos += 2;
        grassXPos += 4;
        treesXPos = treesXPos + 1 + level;
        obstacle1XPos = obstacle1XPos + 2 + level;
        obstacle2XPos = obstacle2XPos + 2 + level;


        if (!jumping &&
            (
              (obstacle1show && display.width() - obstacle1XPos >= 20 && display.width() - obstacle1XPos <= 46)
              ||
              (obstacle2show && display.width() - obstacle2XPos >= 20 && display.width() - obstacle2XPos <= 46)
            )
           ) {
          gameOver = true;
          jumping = true;
          jumpPos = -2;
          tone(sound, 500, 40);
          delay(50);
          tone(sound, 350, 40);
          delay(50);
          tone(sound, 200, 60);

       /*   if (score > hiScore) {
            hiScore = score;
            EEPROM.write(hi_address, hiScore);
            newHiScore = true;
          }*/
          if (happiness + 15 < 100) {
            happiness += 15;
          } else {
            happiness = 100;
          }
          health -= 1;
          if (weight - score * 0.0025 > 5) {
            weight -= score * 0.0025;
         //   EEPROM.write(weight_address, weight);
          }


        }
      }

      if (walkXPos == display.width()) {
        walkXPos = 0;
      }
      if (grassXPos == display.width()) {
        grassXPos = 0;
      }
      if (treesXPos == display.width()) {
        treesXPos = -128;
      }

      if (jumping) {
        display.drawBitmap(10, 26 - jumpPos, dinoJump , 48, 24, WHITE);
      } else {
        display.drawBitmap(10, 26, dinoWalk[walkPos] , 48, 24, WHITE);
      }

      for (int i = 0; i < display.width() / 4 + 1; i++) {
        display.drawBitmap(-walkXPos + i * 8, 50, grass , 8, 6, WHITE);
      }


      // obstacles 1

      if (obstacle1XPos - 16 >= display.width()) {
        obstacle1XPos = 0;
        obstacle1show = false;
      }
      if (!obstacle1show && random(1, 10) == 1 && obstacle2XPos > 40) {
        obstacle1show = true;
        obstacle1XPos = 0;
      }
      if (obstacle1show) {
        display.drawBitmap(display.width() - obstacle1XPos, 44, obstacle1 , 16, 6, WHITE);
      }

      // obstacles 2
      if (obstacle2XPos - 16 >= display.width()) {
        obstacle2XPos = 0;
        obstacle2show = false;
      }
      if (!obstacle2show && random(1, 10) == 1 && obstacle1XPos > 40) {
        obstacle2show = true;
        obstacle2XPos = 0;
      }

      if (obstacle2show) {
        display.drawBitmap(display.width() - obstacle2XPos, 44, obstacle2 , 16, 6, WHITE);
      }




      //draw front grass
      for (int i = 0; i < display.width() / 16 + 1; i++) {
        display.drawBitmap(-grassXPos + i * 32, 60, grass_front , 32, 8, WHITE);
      }
      //draw trees
      display.drawBitmap(-treesXPos, 23, trees , 112, 20, WHITE);

      if (!gameOver) {
        display.setCursor(0, 56);
        display.setTextColor(WHITE);
        display.print(F("lvl: "));
        display.print(level);
        display.setCursor(64, 56);
        display.setTextColor(WHITE);
        display.print(score);
      }

      if (paused && round(cloud1XPos) % 2 == 0) {
        display.fillRect(24, 11, 80, 15, BLACK);
        display.fillRect(25, 12, 78, 13, WHITE);
        display.setCursor(47, 15);
        display.setTextColor(BLACK);
        display.println(F("PAUSED"));
      }

      /* ---------- END GAME ----------*/

    }
    else
    {

      /* ------ NO GAME -----*/
      if (!sleeping) {
        display.drawBitmap(walkXPos, 26, dinoWalk[walkPos + walkDirOffset] , 48, 24, WHITE);
      } else {
        display.drawBitmap(walkXPos, 29, dinoWalk[walkPos + walkDirOffset] , 48, 24, WHITE);
        if (walkRight) {
          if (round(cloud1XPos) % 3 == 0) {
            display.setCursor(walkXPos + 48, 36);
            display.print(z);
          } else {
            display.setCursor(walkXPos + 46, 38);
            display.print(z);
          }
        } else {
          if (round(cloud1XPos) % 3 == 0) {
            display.setCursor(walkXPos - 4, 36);
            display.print(z);
          } else {
            display.setCursor(walkXPos - 2, 38);
            display.print(z);
          }
        }
      }
      if (walkRight) {
        if (!sleeping) {
          walkXPos += 1;
          grassXPos += 2;
          treesXPos += 0.5;
        }
        if (walkXPos > 80) {
          walkRight = false;
          walkDirOffset = 3;
        }
      } else {
        if (!sleeping) {
          walkXPos -= 1;
          grassXPos -= 2;
          treesXPos -= 0.5;
        }
        if (walkXPos < 0) {
          walkRight = true;
          walkDirOffset = 0;
        }
      }

      //draw grass (ground)
      for (int i = 0; i < 2 * display.width() / 4; i++) {
        display.drawBitmap(-walkXPos + i * 8, 50, grass , 8, 6, WHITE);
      }
      // draw poops
      for (int i = 0; i < 3; i++) {
        if (poops[i] > 0) {
          display.drawBitmap(-walkXPos + poops[i], 44, poop , 16, 6, WHITE);
        }
      }
      //draw front grass
      for (int i = 0; i < 2 * display.width() / 16; i++) {
        display.drawBitmap(-grassXPos + i * 32, 56, grass_front , 32, 8, WHITE);
      }
      //draw trees
      display.drawBitmap(-treesXPos, 23, trees , 112, 20, WHITE);



      if (!sleeping) {
        if (walkAnimReverse) {
          --walkPos;
          if (walkPos == -1) {
            walkPos = 0;
            walkAnimReverse = false;
          }
        } else {
          ++walkPos;
          if (walkPos == 3) {
            walkPos = 2;
            walkAnimReverse = true;
          }
        }
      }

    }


    /* ------- MENUS AND ACTIONS ------- */
    //render menu
    if (menuOpened and !game) {
      display.fillRect(0, 0, display.width(), 30, BLACK);
      display.drawRect(0, 0, display.width(), 29, WHITE);
      display.fillRect(1, 1, display.width() - 2, 27, BLACK);
      display.drawRect(0, 0, display.width(), 12, WHITE);
      display.setCursor(8, 2);
      display.setTextSize(1);
      if (menuDepth) {
        display.fillRect(0, 0, display.width(), 12, WHITE);
        display.fillRect(1, 18, 1, 5, WHITE);
        display.fillRect(2, 19, 1, 3, WHITE);
        display.fillRect(3, 20, 1, 1, WHITE);
        display.setTextColor(BLACK);
      } else {
        display.fillRect(1, 3, 1, 5, WHITE);
        display.fillRect(2, 4, 1, 3, WHITE);
        display.fillRect(3, 5, 1, 1, WHITE);
        display.setTextColor(WHITE);
      }
      char oneItem [STRING_SIZE];
      memcpy_P (&oneItem, &mainMenu[menu][0], sizeof oneItem);
      display.println(oneItem);
      if (subMenu) {
        display.setTextColor(WHITE);
        display.setCursor(8, 16);
        char subItem [STRING_SIZE];
        memcpy_P (&subItem, &mainMenu[menu][subMenu], sizeof subItem);
        display.println(subItem);
      }
    }

    //do actions

    if (action > 0) {


      if ((action == 101 || action == 102 || action == 103) && !sleeping && random(1, (11 - round(discipline / 10))) == 1 ) {
        //95-100 discipline = 100% chance to feed
        //85-95 discipline = 50% chance
        //75-85 discipline = 33.33% chance
        //65-75 discipline = 25% chance
        //55-65 discipline = 20% chance
        //45-55 discipline = 16.67% chance
        //35-45 discipline = 14.28% chance
        //25-35 discipline = 12.5% chance
        //15-25 discipline = 12.5% chance
        //5-15 discipline = 10% chance
        //0-5 discipline = 9% chance

        //animate eating

        display.fillRect(0, 0, display.width(), display.height(), BLACK);
        for (int j = 0; j < 3; j++) {
          for (int i = 0; i < 4; i++) {
            display.clearDisplay();
            switch (action) {
              case 101:
                //apple
                display.drawBitmap(50, 40, apple, 24, 24, WHITE);
                if (j > 0) display.fillCircle(76, 54, 12, BLACK);
                if (j == 2) display.fillCircle(47, 55, 12, BLACK);
                break;
              case 102:
                //steak
                display.drawBitmap(50, 40, steak, 24, 24, WHITE);
                if (j > 0) display.fillCircle(76, 59, 13, BLACK);
                if (j == 2) display.fillCircle(60, 63, 13, BLACK);
                break;
              case 103:
                //water ripples
                display.drawCircle(80, 55, 1 + 1 * i, WHITE);
                display.drawCircle(80, 55, 5 + 2 * i, WHITE);
                display.drawCircle(80, 55, 10 + 4 * i, WHITE);
                break;


            }
            display.drawBitmap(80, 24, eating[i], 48, 40, WHITE);
            delay(150);
            display.display();
          }
        }



        switch (action) {
          //apple
          case 101:
            if (hunger + 10 > 100) {
              hunger = 100;
              weight += 1;
            } else {
              hunger += 10;
            }
            if (health + 1 <= 100) {
              health += 1;
            }
            poopometer += 0.02;
            break;
          //steak
          case 102:
            if (hunger + 20 > 100) {
              hunger = 100;
              weight += 2;
            } else {
              hunger = hunger + 20;
              weight += 1;
            }
            if (health - 1 > 0) {
              health -= 1;
            }
            poopometer += 0.05;
            break;
          //water
          case 103:
            if (hunger + 5 <= 100) {
              hunger = hunger + 5;
            }
            poopometer += 0.01;   
            break;
        }
      //   EEPROM.write(hunger_address, hunger);
      //   EEPROM.write(weight_address, weight);
      } else {
        if (action == 101 || action == 102 || action == 103) {
          tone(sound, 500, 200);
          delay(250);
        }
      }

      switch (action) {
        case 201:
          //game
          if (!sleeping && health > 20) {
            game = true;
            walkPos = 0;
            walkXPos = 0;
            walkAnimReverse = false;
            walkRight = false;
            walkDirOffset = 2;
            treesXPos = -20;
            grassXPos = 0;
          }
          break;
        case 301:
          //sleep
          sleeping = !sleeping;
          if (!sleeping) {
            sunOrMoon = false;
          } else {
            for (int i = 0; i < 6; i++) {
              stars[i][0] = random(0, display.width());
              stars[i][1] = random(0, 10);
            }
          }

          break;
        case 401:
          //bath
          resetPoops();
          break;
        case 501:
          //doctor
          if (health < 60) {
            health = 100;
            for (int i = 0; i < 5; i++) {
              display.clearDisplay();
              if (i % 2 != 0) {
                display.fillRect(32, 23, 64, 16, WHITE);
                display.fillRect(56, 0, 16, 64, WHITE);
              }
              display.display();
          //    EEPROM.write(health_address, health);
              delay(300);
            }
          }

          break;
        case 601:
          //discipline
          if (action == 601 && !sleeping) {
            if (discipline + 12 <= 100) {
              discipline += 12;
            } else {
              discipline = 100;
            }
            if (happiness - 3 > 0) {
              happiness -= 3;
            }
            delay(150);
            // EEPROM.write(happiness_address, happiness);
            for (int i = 0; i < 5; i++) {
              tone(sound, 200 * i, 100);
              display.setCursor(100 + 3 * i, 32);
              display.print(F("!"));
              display.display();
              delay(150);
            }

          }
          break;

        case 801:
          EEPROM.write(age_address, (age*100));
          EEPROM.write(weight_address,( weight*100));
          EEPROM.write(hunger_address,( hunger*100));
          EEPROM.write(discipline_address, (discipline*100));
          EEPROM.write(happiness_address, (happiness*100));
          EEPROM.write(health_address, (health*100));
          break;
      }
      action = 0;
    }

    //display settings
    if (setting > 0 and !game) {
      display.setCursor(8, 16);
      if (setting == 201) {
        display.println(F("bonheur +"));
      }
      if (setting == 301) {
        display.println(F("repos"));
      }
      if (setting == 401) {
        display.println(F("Santer +"));
      }
      if (setting == 501) {
        display.println(F("Santer -"));
      }
      if (setting == 601) {
        display.println(F("apprendre"));
      }
      if (setting == 701 || setting == 702 || setting == 703 || setting == 704) {
        display.drawRect(70, 17, 52, 7, WHITE);
      }
      if (setting == 701) {

        drawBar(hunger);
      }
      if (setting == 702) {
        drawBar(happiness);
      }
      if (setting == 703) {
        drawBar(health);
      }
      if (setting == 704) {
        drawBar(discipline);
      }
      if (setting == 705 || setting == 706 || setting == 801) {
        display.setCursor(80, 16);
      }
      if (setting == 705) {
        display.setCursor(70,16);
        display.print (weight);
     //   display.println(F(" kg"));
      }
      if (setting == 706) {
        display.print(age, 1);
        display.print(F(" AN"));
        //EEPROM.write(age_address, age);
      }
      if (setting == 801) {

      }
    }
    //display notification
    if (notification) {
      ++notificationBlink;
      if (notificationBlink == 10) {
        notificationBlink = 0;
      }
      if (notificationBlink != 1) {
        display.drawRect(117, 28, 11, 11, WHITE);
        display.setTextColor(WHITE);

      } else {
        display.fillRect(117, 28, 11, 11, WHITE);
        display.setTextColor(BLACK);

      }
      display.setCursor(120, 30);
      display.println(F("!"));
    }

    // GAME OVER
    if (gameOver) {



      display.setCursor(36, 15);
      display.setTextColor(WHITE);
      display.println(F("GAME OVER"));
      display.setCursor(21, 29);
      if (newHiScore) {
       // display.println(F("NEW SCORE!"));
        display.setCursor(21, 40);
      }
      display.println(score);



    }

    display.display();

  } else {
    //dead...
    display.clearDisplay();
    display.setCursor(0, 0);
//    display.setTextColor(WHITE);
    display.println(F("Mort...\n\nPress button "));
    display.display();

    if (button1State == HIGH) {
      tone(sound, 300, 80);
      delay(200);
      noTone(sound);
      for (int i = 0 ; i < EEPROM.length() ; i++) {
    EEPROM.write(i, 0);
  }
      asm volatile ("  jmp 0");
    }
  }
}


void drawBar(float value) {
  display.fillRect(72, 19, 48 * value / 100, 3, WHITE);
}

char* getItem(int menu, int index) {
  char oneItem [STRING_SIZE];
  memcpy_P (&oneItem, &mainMenu[menu][index], sizeof oneItem);
  return oneItem;
}

int countPoops() {
  int poopsCnt = 0;
  for (int i = 0; i < 3; i++) {
    if (poops[i] > 0) {
      ++poopsCnt;
    }
  }
  return poopsCnt;
}

void resetPoops() {
  for (int i = 0; i < 3; i++) {
    poops[i] = 0;
  }
}

 

6.Téléversement

Il ne vous reste plus qu’à téléverser le programme dans l’Arduino. Pour ce faire cliquez sur le bouton téléverser puis patienter le temps que la compilation ainsi que le téléversement ce réalise.

 

Si tout c’est bien passé vous voila avec un tamagotchi/ tamaguino fonctionnel!! Enjoy 😎 !!

7.Résultat

 

tamaguino

 

 

 

 

 

Laisser un commentaire
Précédent Suivant