Batch Index du Forum
S’enregistrerRechercherFAQMembresGroupesConnexion
Répondre au sujet Page 1 sur 1
[Arduino] Snakeduino
Auteur Message
Répondre en citant
Message [Arduino] Snakeduino 
Bonjour à tous,

Aujourd'hui, je vous présente mon premier projet sur Arduino; Snakeduino. C'est le jeu du serpent (snake) sur une matrice de 8x8 leds RG contrôlée avec une manette de wii. Le score est affiché sur un écran LCD et on peut choisir de jouer avec l'accéléromètre ou le joystick en appuyant sur un bouton. Le meilleur score est sauvegardé sur l'arduino (premier octet).

Instructions de jeu :
Le serpent est la série de points (2 au départ) orange qui bougent automatiquement et que vous devez diriger avec votre manette de wii.
Le point vert est la pomme à manger (passer dessus avec la tête tête du serpent) et le point rouge est la pierre qu'il ne faut pas toucher.
Si vous vous mangez vous même, vous mourrez. Si vous passez sur la pierre également. A chaque fois que vous mangez une pomme, vous grandissez d'un pixel et vous gagnez un point.
Sur l'écran LCD est affiché votre score sur la première ligne et le record à battre sur la 2ème ligne. Si vous battez le meilleur score la tête de mort à la fin du jeu sera verte, sinon elle sera rouge.
Vous pouvez passer d'un bord de la matrice (de 8x8 leds) à l'autre sans mourir. A chaque fois que vous mangez une pomme, la pierre et la pomme réapparaissent ailleurs.
Pour jouer avec l'accéléromètre, il faut appuyer sur le bouton sur la breadboard au début du jeu ou quand on est mort et que l'écran est noir.
Si la led jaune sur la breadboard est allumée, cela veut dire que le snake se dirige avec l'accéléromètre, sinon c'est avec le joystick.

Le matériel dont vous aurez besoin :
Une nunchuck (manette de Wii) connectée l'adaptateur WiiChuck : http://www.watterott.com/de/Leiterplatten/WiiChuck-Adapter
Un écran LCD 16x2 jaune (DEM16216SYH-LY) : http://www.watterott.com/de/16x2-LCD-gelb-DEM16216SYH-LY
Une matrice 8x8 leds RG avec liaison série : http://www.watterott.com/de/LED-Matrix-Serial-Interface-Red/Green
Un Fritzing Starter Kit avec un arduino uno R3 : http://www.watterott.com/de/Fritzing-Starter-Kit
Ce kit contient tout ce qu'il faut d'autre pour ce projet, comme par exemple l'arduino, la breadboard, la led, le bouton, les câbles et les résistances.

L'algorithme (pour faire bouger le serpent, pour qu'il s'agrandisse, pour utiliser l'accéléromètre de la manette, etc) était assez complexe, cela m'a pris beaucoup de temps. Le code (surtout le type des variables) est optimisé au maximum car à un moment je n'avais plus de place dans la mémoire de l'Arduino, mais maintenant ça fonctionne nickel.

Si vous voulez faire le montage chez vous, veuillez lire les premières lignes du code en commentaire.

Je vous fourni mon schéma avec Fritzing (vous pouvez le télécharger ici) :


Une petite photo pour voir ce que ça donne :

(Le câblage n'est pas très joli mais je voulais mettre le tout dans une boîte plus tard.)

Je ferai sûrement bientôt une petite vidéo pour vous montrer le jeu sans avoir besoin de tester chez vous.

Voilà le code final qui est entièrement commenté :
Code:

/*
Créé par : Sablier94
Date de dernière mise à jour : 22.06.12
Nom du jeu : Snakeduino
Nom du sketch : WiiSnake2D.ino
Ce sketch est sous license CC-BY-NC-SA
Le schéma fritzing est disponible sur le fichie "SchemaWiiSnake2D.fzz".
Matériel nécessaire :
Une nunchuck (manette de Wii) connectée l'adaptateur WiiChuck : http://www.watterott.com/de/Leiterplatten/WiiChuck-Adapter
Un écran LCD 16x2 jaune (DEM16216SYH-LY) : http://www.watterott.com/de/16x2-LCD-gelb-DEM16216SYH-LY
Une matrice 8x8 leds RG avec liaison série : http://www.watterott.com/de/LED-Matrix-Serial-Interface-Red/Green
Un Fritzing Starter Kit avec un arduino uno R3 : http://www.watterott.com/de/Fritzing-Starter-Kit
Ce kit contient tout ce qu'il faut d'autre pour ce projet, comme par exemple la breadboard, la led, le bouton, les câbles et les résistances.
Notes pour les développeurs :
Ce sketch a été créé avec l'IDE Arduino 1.0.1 et pourrait ne pas fonctionner sur des versions antérieures. Les librairies utilisées sont déjà dans l'IDE 1.0 par défaut.
Les positions X et Y sont inversées, il faut faire Y = Y - 1 pour monter et pareillement pour l'axe X. X = 0 pour tout à droite, Y = 0 pour tout en haut et 8 pour tout à gauche et tout en bas.
Il faut brancher la nunchuk sur l'adaptateur dans le bon sens (dans mon cas c'est avec le bout de plastique transparent dessus) pour ne pas faire de court-circuit.
La résistance pour l'écran LCD peut être modifiée par ajuster la luminosité (ou vous pouvez utiliser un potentiomètre).
Attention, ce programme va écrire le meilleur score dans le premier octet de la mémoire de l'eeprom de l'arduino. L'octet qui était à la position 0 sera donc effacé !
la limite d'écriture de l'eeprom de l'arduino étant limitée à 100'000 cycles, faîtes attention que la ligne "EEPROM.write(0, 0)" dans le setup est bien commentée à part pour remettre le score à zéro.
Le jeu fonctionne sans problème. Si le serpent devient vert un moment, c'est parce qu'il y a quelque chose qui sort de la taille tableau de la matrice, mais normalement tous ces bugs sont corrigées.
Instructions de jeu :
Le serpent est la série de points (2 au départ) orange qui bougent automatiquement et que vous devez diriger avec votre manette de wii.
Le point vert est la pomme à manger (passer dessus avec la tête tête du serpent) et le point rouge est la pierre qu'il ne faut pas toucher.
Si vous vous mangez vous même, vous mourrez. Si vous passez sur la pierre également. A chaque fois que vous mangez une pomme, vous grandissez d'un pixel et vous gagnez un point.
Sur l'écran LCD est affiché votre score sur la première ligne et le record à battre sur la 2ème ligne. Si vous battez le meilleur score la tête de mort à la fin du jeu sera verte, sinon elle sera rouge.
Vous pouvez passer d'un bord de la matrice (de 8x8 leds) à l'autre sans mourir. A chaque fois que vous mangez une pomme, la pierre et la pomme réapparaissent ailleurs.
Pour jouer avec l'accéléromètre, il faut appuyer sur le bouton sur la breadboard au début du jeu ou quand on est mort et que l'écran est noir.
Si la led jaune sur la breadboard est allumée, cela veut dire que le snake se dirige avec l'accéléromètre, sinon c'est avec le joystick.
*/

#include <Wire.h> //Pour utiliser la manette nunchuk
#include <LiquidCrystal.h> //Pour utiliser l'écran LCD
#include <EEPROM.h> //Pour écrire le meilleur score dans la mémoire de l'arduino

/* Définition des constantes */
#define DATAOUT     9 //MOSI (input de la matrice)
// #define DATAIN      7 //MISO (output de la matrice) ==> Pas utilisé dans ce cas.
#define SPICLOCK    6 //SCK ((pour la synchronisation de la matrice))
#define SLAVESELECT 10 //SS ou SC

/* Couleur constantes */
#define BLACK 0 //Utilisé pour éteindre les leds
#define GREEN 1 //Utilisé pour les pommes
#define RED 2 //Utilisé pour la pierre
#define ORANGE 3 //Utilisé pour le serpent

const word intWaitTimeForPushButtonAgain = 200; //Temps de delai qu'on doit attendre pour appuyer une nouvelle fois sur le bouton sur la breadboard
const byte buttonBreadboardPin = 13; //Sur cette broche est branché le bouton qui permet de mettre le mode avec l'accéléromètre
const byte pinLedYellow = 8; //Sur ce pin est mis la led jaune qui insique si l'on joue avec ou sans l'accéléromètre
const byte bytColorSnake = ORANGE; //Couleur du serpent
const byte bytColorRock = RED; //Couleur des pierres
const byte bytColorApple = GREEN; //Couleur des pommes
const byte intSpeedSnake = 175; //Vitesse de déplacement du serpent (=taille du sleep). On ne peut pas dépasser 255 parce que c'est un byte

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //On initialise la librairie pour gérer l'écran LCD avec les numéros des pins utilisés

char* LastMove = "DOWN"; //Dernier mouvement effectué, donc il va partir vers le bas au début
boolean blnDeath; //Pour savoir si le serpent est mort
char out_buffer[64]; //Buffer de sortie pour la matrice de 64 leds

byte bytPointPositionAppleXOld; //Précédent point X de la pomme
byte bytPointPositionAppleYOld; //Précédent point Y de la pomme
byte bytPointPositionAppleX; //Position X de la pierre
byte bytPointPositionAppleY; //Position Y de la pierre
byte bytPointPositionRockX; //Position X de la pierre
byte bytPointPositionRockY; //Position X de la pierre
byte bytPointPositionRockXOld; //Précédent point X de la pierre
byte bytPointPositionRockYOld; //Précédent point Y de la pierre

byte bytAllPointsSnakeX[63]; //Contient toutes les cases de l'axe X du serpent
byte bytAllPointsSnakeY[63]; //Contient toutes les cases de l'axe Y du serpent

byte bytNumberOfCaseOfSnake; //Nombre totale de cases totale du seprent
long lngTime; //variable qui stocke la mesure du temps
boolean blnPlayWithAccel; //Pour savoir si on joue avec l'accéléromètre ou non

boolean blnMoved; //Pour savoir si le serpent a été déplacé par un mouvement de l'utilisateur
boolean blnRestartPutApple; //Pour savoir si on doit replacer la pomme
boolean blnRestartPutRock; //Pour savoir si on doit replacer la pierre
byte ValueForMoveMinus; //Valeur utilisée pour savoir quand on tourne ou non
byte ValueForMovePlus; //Valeur utilisée pour savoir quand on tourne ou non

byte bytBuffer[6]; //Buffer contenant les 6 précieux octets qui nous intéressent
byte bytCountBuffer = 0; //Index courant de buffer

byte joy_x_axis = bytBuffer[0]; //Joystick axe X (0-255)
byte joy_y_axis = bytBuffer[1]; //Joystick axe Y (0-255)
short accel_x_axis = bytBuffer[2] * 4; //Accéléromètre axe X
int accel_y_axis = bytBuffer[3] * 4; //Accéléromètre axe Y
int accel_z_axis = bytBuffer[4] * 4; //Accéléromètre axe Z
byte z_button = 0; //Bouton Z
byte c_button = 0; //Bouton C

/* Définition des images prédéfinies pouvant être affichées  */
boolean BACKGROUND[8][8] = //Tableau pour mettre toutes les leds de la même couleur
{
  {1,1,1,1,1,1,1,1},
  {1,1,1,1,1,1,1,1},
  {1,1,1,1,1,1,1,1},
  {1,1,1,1,1,1,1,1},
  {1,1,1,1,1,1,1,1},
  {1,1,1,1,1,1,1,1},
  {1,1,1,1,1,1,1,1},
  {1,1,1,1,1,1,1,1},
};

boolean TABSNAKE[8][8]; //Tableau qui contient le serpent qui sera affiché

boolean TABAPPLE[8][8]; //Tableau qui contient les pommes qui seront affichées

boolean TABROCK[8][8]; //Tableau qui contient les pierres qui seront affichées

/* Ecrit l'image sur le buffer de sortie. Cette fonction doit être précedé de la fonction fill_buffer(). */
void write_buffer()
{
  digitalWrite(SLAVESELECT, LOW); //Activation
  delay(5);
  for(byte i = 0; i < 64; i++) //Parcours toutes les leds
  {
    shiftOut(DATAOUT, SPICLOCK, MSBFIRST, out_buffer[i]); //Envoi des données pour contrôler la led
  }
  digitalWrite(SLAVESELECT, HIGH); //Désctivation
  delay(5);
}

/*
Rempli le buffer avec l'image (un tableau d'une dimension de données de 64 cases de 1 bits)
dans la couleur spécifiée. Les bits à 0 ne sont pas changé mais ceux qui sont à 1 peuvent
être ajoutés consécutivement. Un appel de fill_buffer() devrait précéder à write_buffer(); //Ecriture des tableaux sur la matrice de leds
Le tampon est rempli en premier pour éviter les erreurs de synchronisation impliqués dans la non-écriture séquentielle.
*/
void fill_buffer(boolean data[8][8], byte color)
{
   byte bytColor;
   for (byte i = 0; i < 8; i++) //Parcours de tout tableau
   {
     for (byte j = 0; j < 8; j++) //Parcours de tout le tableau
     {
       bytColor = data[7 - i][7 - j]; //Récupération de la couleur
       if(bytColor) //S'il y a une couleur autre que noir :
       {
         out_buffer[i * 8 + j] = color % 4; //Ajout de la couleur dans les informations de la led
       }
     }
   }
}

/* Met à jour et récrit tous les tableaux du jeu */
void RefreshAllTAB()
{
  fill_buffer(BACKGROUND, BLACK); //On affiche le fond en noir pour actualiser la disparition de la pierre qui vient d'être effacée
  fill_buffer(TABSNAKE, bytColorSnake); //On affiche le tableau qui contient le serpent
  fill_buffer(TABAPPLE, bytColorApple); //On affiche le tableau qui contient la pomme
  fill_buffer(TABROCK, bytColorRock); //On affiche le tableau qui contient la pierre
  write_buffer(); //Ecriture des tableaux sur la matrice de leds
}

void handshake()
{
  Wire.beginTransmission(0x52);   
  Wire.write(0x00);   
  Wire.endTransmission();
}

/* Fonction utilisée dans la boucle infinie pour gérer les mouvements en fonction de la nunchuk */
void parseNunchuk()
{
  joy_x_axis = bytBuffer[0]; //Joystick axe X (0-255)
  joy_y_axis = bytBuffer[1]; //Joystick axe Y (0-255)
  accel_x_axis = bytBuffer[2] * 4; //Accéléromètre axe X
  accel_y_axis = bytBuffer[3] * 4; //Accéléromètre axe Y
  accel_z_axis = bytBuffer[4] * 4; //Accéléromètre axe Z

  z_button = 0; //Bouton Z
  c_button = 0; //Bouton C

  //Mise à jour des variable sen fonctions de ce qu'on a reçu du buffer :
  if((bytBuffer[5] >> 0) & 1)
    z_button = 1; //Bouton Z non appuyé

  if((bytBuffer[5] >> 1) & 1)
    c_button = 1; //Bouton C non appuyé

  if((bytBuffer[5] >> 2) & 1)
    accel_x_axis += 2; //Mise à jour des données de l'acéléromètre

  if((bytBuffer[5] >> 3) & 1)
    accel_x_axis += 1; //Mise à jour des données de l'acéléromètre

  if((bytBuffer[5] >> 4) & 1)
    accel_y_axis += 2; //Mise à jour des données de l'acéléromètre

  if((bytBuffer[5] >> 5) & 1)
    accel_y_axis += 1; //Mise à jour des données de l'acéléromètre

  if((bytBuffer[5] >> 6) & 1)
    accel_z_axis += 2; //Mise à jour des données de l'acéléromètre

  if((bytBuffer[5] >> 7) & 1)
    accel_z_axis += 1; //Mise à jour des données de l'acéléromètre
 
  if(blnPlayWithAccel == true)
  {
    joy_x_axis = map(accel_x_axis, 0, 1023, 0, 255); //Pour "remdimensionner" les valeurs reçues par l'accéléromètre comme si c'était le joystick
    joy_y_axis = map(accel_y_axis, 0, 1023, 0, 255); //Pour "remdimensionner" les valeurs reçues par l'accéléromètre comme si c'était le joystick
  }
 
  if(blnDeath == false) //On n'exécute les actions seulement si le serpent n'est pas mort
  {
    blnMoved = false; //On redefinit la variable pour dire que le serpent n'a pas encore bougé
    if(joy_x_axis <= ValueForMoveMinus) //Si l'axe y est dirigé vers la gauche :
    {
      if(LastMove != "RIGHT" && blnMoved != true) //Pour que le serpent ne puisse pas revenir directement en arrière, ni bouger 2 fois en un tour
      {
        MoveLeft(); //On déplace le serpent dans la direction voulue
        LastMove = "LEFT"; //On actualise l'information sur le déplacement
        blnMoved = true; //Le serpent a changé de direction
      }
    }
    if(joy_x_axis >= ValueForMovePlus) //Si l'axe x est dirigé vers la droite :
    {
      if(LastMove != "LEFT" && blnMoved != true) //Pour que le serpent ne puisse pas revenir directement en arrière, ni bouger 2 fois en un tour
      {
        MoveRight(); //On déplace le serpent dans la direction voulue
        LastMove = "RIGHT"; //On actualise l'information sur le déplacement
        blnMoved = true; //Le serpent a changé de direction
      }
    }
    if(joy_y_axis <= ValueForMoveMinus) //Si l'axe y est dirigé vers le bas :
    {
      if(LastMove != "UP" && blnMoved != true) //Pour que le serpent ne puisse pas revenir directement en arrière, ni bouger 2 fois en un tour
      {
        MoveDown(); //On déplace le serpent dans la direction voulue
        LastMove = "DOWN"; //On actualise l'information sur le déplacement
        blnMoved = true; //Le serpent a changé de direction
      }
    }
    if(joy_y_axis >= ValueForMovePlus) //Si l'axe y est dirigé vers le haut :
    {
      if(LastMove != "DOWN" && blnMoved != true) //Pour que le serpent ne puisse pas revenir directement en arrière, ni bouger 2 fois en un tour
      {
        MoveUp(); //On déplace le serpent dans la direction voulue
        LastMove = "UP"; //On actualise l'information sur le déplacement
        blnMoved = true; //Le serpent a changé de direction
      }
    }
   
//    DisplayPositionSnakeHead(); //Pour le déboggage, vous pouvez décommenter cette ligne et voir où le serpent se situe dans la console
   
    if(!blnMoved) //Si le serpent n'a pas encore bougé :
    {
        if(LastMove == "UP") //On déplace le serpent dans la même direction qu'avant
        {
          MoveUp(); //On actualise l'information sur le déplacement
        }
        if(LastMove == "DOWN") //On déplace le serpent dans la même direction qu'avant
        {
          MoveDown(); //On actualise l'information sur le déplacement
        }
        if(LastMove == "LEFT") //On déplace le serpent dans la même direction qu'avant
        {
          MoveLeft(); //On actualise l'information sur le déplacement
        }
        if(LastMove == "RIGHT") //On déplace le serpent dans la même direction qu'avant
        {
          MoveRight(); //On actualise l'information sur le déplacement
        }
    }
   
    for(byte i = 1; i < bytNumberOfCaseOfSnake-1; i++) //Parcours de toutes les cases du serpent
    {
      if(bytAllPointsSnakeX[0] == bytAllPointsSnakeX[i] && bytAllPointsSnakeY[0] == bytAllPointsSnakeY[i]) //Si la tête a touché une autre partie du corps :
      {
        GameOver(); //Fin de la partie, le serpent s'est mangé
      }
    }
   
    if(bytNumberOfCaseOfSnake >= 9) //Si le serpent a 9 cases (pour corriger un bug qui fait que quand il se mange en ligne droite à 9, on ne voit que la tête) :
    {
      byte XIsItAllTheSAmeValue = bytAllPointsSnakeX[0]; //On prend la tête comme référence pour vérifier que tous les points ne sont pas sur la même ligne
      byte YIsItAllTheSAmeValue = bytAllPointsSnakeY[0]; //On prend la tête comme référence pour vérifier que tous les points ne sont pas sur la même ligne
      boolean AllIsInALigneXForNow = true; //Par défaut, tous les points sont sur la même ligne
      boolean AllIsInALigneYForNow = true; //Par défaut, tous les points sont sur la même ligne
      for(byte i = 1; i < bytNumberOfCaseOfSnake-1; i++) //Parcours de toutes les cases du serpent
      {
        if(bytAllPointsSnakeX[i] != XIsItAllTheSAmeValue) //Si un point est différent :
        {
          AllIsInALigneXForNow = false; //Le serpent n'est pas tout sur la même ligne
        }
        if(bytAllPointsSnakeY[i] != YIsItAllTheSAmeValue) //Si un point est différent :
        {
          AllIsInALigneYForNow = false; //Le serpent n'est pas tout sur la même ligne
        }
      }
      if(AllIsInALigneXForNow) //Si tous les points ne sont pas sur la même ligne
      {
        GameOver(); //On a perdu
      }
      if(AllIsInALigneYForNow) //Si tous les points ne sont pas sur la même ligne
      {
        GameOver(); //On a perdu
      }
    }
   
    if(bytAllPointsSnakeX[0] == bytPointPositionRockX && bytAllPointsSnakeY[0] == bytPointPositionRockY) //Si la tête du serpent est sur la pierre :
    {
      GameOver(); //Fin de la partie, on s'est pris une pierre dans la tête #Aie
    }
   
    if(bytAllPointsSnakeX[0] == bytPointPositionAppleX && bytAllPointsSnakeY[0] == bytPointPositionAppleY) //Si la tête du serpent est sur la pomme :
    {
      TABAPPLE[bytPointPositionAppleX][bytPointPositionAppleY] = 0; //On supprime la pomme du tableau
      TABROCK[bytPointPositionRockX][bytPointPositionRockY] = 0; //On supprime la pierre du tableau
     
      do //Placement de la pomme sur la matrice :
      {
        blnRestartPutApple = false; //Par défaut, la pomme est placée correctement
        bytPointPositionAppleX = random(0, 8); //On trouve une nouvelle position X aléatoire pour la pomme
        bytPointPositionAppleY = random(0, 8); //On trouve une nouvelle position Y aléatoire pour la pomme
        for(byte i = 1; i < bytNumberOfCaseOfSnake-1; i++) //On passe sur toutes les cases
        {
          if(bytPointPositionAppleX == bytAllPointsSnakeX[i] && bytPointPositionAppleY == bytAllPointsSnakeY[i]) //On regarde si la pomme est sur le point :
          {
            blnRestartPutApple = true; //On doit replacer la pomme
          }
        }
        if(bytPointPositionAppleX == bytAllPointsSnakeX[0] && bytPointPositionAppleY == bytAllPointsSnakeY[0]) //On regarde si la pomme est sur le point :
        {
          blnRestartPutRock = true; //On doit replacer la pierre
        }
      } while(blnRestartPutApple); //On recommance tant que la pomme est sur le serpent
     
      do //Placement de la pierre sur la matrice :
      {
        blnRestartPutRock = false; //Par défaut, la pierre est placée correctement
        bytPointPositionRockX = random(0, 8); //On trouve une nouvelle position X aléatoire pour la pierre
        bytPointPositionRockY = random(0, 8); //On trouve une nouvelle position Y aléatoire pour la pierre
        for(byte i = 1; i < bytNumberOfCaseOfSnake-1; i++) //On passe sur toutes les cases
        {
          if(bytPointPositionRockX == bytAllPointsSnakeX[i] && bytPointPositionRockY == bytAllPointsSnakeY[i]) //On regarde si la pierre est sur le point :
          {
            blnRestartPutRock = true; //On doit replacer la pierre
          }
        }
        if(bytPointPositionRockX == bytAllPointsSnakeX[0] || bytPointPositionRockY == bytAllPointsSnakeY[0]) //On regarde si la pierre est sur la même ligne ou colonne que le point :
        {
          blnRestartPutRock = true; //On doit replacer la pierre
        }
        if(bytPointPositionRockX == bytPointPositionAppleX && bytPointPositionRockY == bytPointPositionAppleY) //On regarde si la pierre est sur la pomme :
        {
          blnRestartPutRock = true; //On doit replacer la pierre
        }
      } while(blnRestartPutRock); //On recommance tant que la pierre est sur le serpent
     
      TABAPPLE[bytPointPositionAppleX][bytPointPositionAppleY] = 1; //On ajoute la pomme sur le tableau
      TABROCK[bytPointPositionRockX][bytPointPositionRockY] = 1; //On ajoute la pierre sur le tableau
     
      bytNumberOfCaseOfSnake++; //On augemente la taille du serpent
     
      lcd.setCursor(8, 0); //On positionne le curseur pour écraser l'ancien score
      lcd.print(bytNumberOfCaseOfSnake); //On affiche le score du joueur
     
      bytAllPointsSnakeX[bytNumberOfCaseOfSnake-1] = bytPointPositionAppleXOld; //On ajoute la nouvelle case dans le tableau du serpent
      bytAllPointsSnakeY[bytNumberOfCaseOfSnake-1] = bytPointPositionAppleYOld; //On ajoute la nouvelle case dans le tableau du serpent
      RefreshAllTAB(); //Met à jour et récrit tous les tableaux du jeu
    }
  }
}

/* Affichage les informations transmises par la nunchuk dans la console */
void DisplayWiiInfos() //Fonction utilisée pour le déboggage
{
  Serial.print(joy_x_axis, DEC);
  Serial.print("\t");
  Serial.print(joy_y_axis, DEC);
  Serial.print("\t");
  Serial.print(accel_x_axis, DEC);
  Serial.print("\t");
  Serial.print(accel_y_axis, DEC);
  Serial.print("\t");
  Serial.print(accel_z_axis, DEC);
  Serial.print("\t");
  Serial.print(z_button, DEC);
  Serial.print("\t");
  Serial.print(c_button, DEC);
  Serial.print("\t");
  Serial.println();
}

/* Affichage de la position de la tête du serpent dans la console */
void DisplayPositionSnakeHead() //Fonction utilisée pour le déboggage
{
  Serial.print("Point X :");
  Serial.print(bytAllPointsSnakeX[0]); //Position X de la tête
  Serial.print(" ");
  Serial.print("Point Y :");
  Serial.println(bytAllPointsSnakeY[0]); //Position Y de la tête
}

/* Gère ce que doit faire le jeu quand le serpent est mort */
void GameOver()
{
  boolean blnBeatBestScore = false; //Par défaut, ce n'est pas le meilleur score
  if(bytNumberOfCaseOfSnake > EEPROM.read(0)) //Si c'est le meilleur score :
  {
    EEPROM.write(0, bytNumberOfCaseOfSnake); //On sauvegarde le meilleur score
    blnBeatBestScore = true;
  }
  boolean DEATHHEAD[8][8] = //Tableau pour dessiner une tête de mort
  {
    {0,1,1,1,1,0,0,0},
    {1,1,1,1,1,0,0,0},
    {1,1,1,0,0,1,1,0},
    {1,1,1,0,1,1,1,1},
    {1,1,1,1,1,0,1,1},
    {1,1,1,0,0,1,1,1},
    {0,1,1,0,1,1,0,0},
    {0,0,0,1,1,0,0,0},
  };
  blnDeath = true; //Le serpent est mort
  for(byte i = 0; i < 5; i++) //On va faire clignoter 5 fois la matrice en rouge-noir
  {
    fill_buffer(BACKGROUND, BLACK); //On affiche le fond en noir
    if(blnBeatBestScore) //Si on a battu le meilleur score :
    {
      fill_buffer(DEATHHEAD, GREEN); //On affiche la tête de mort en rouge
    }
    else
    {
      fill_buffer(DEATHHEAD, RED); //On affiche la tête de mort en rouge
    }
    write_buffer(); //Ecriture des tableaux sur la matrice de leds
    delay(250); //Peremt de visualiser le clignotement
    RefreshAllTAB(); //Met à jour et récrit tous les tableaux du jeu
    delay(250); //Peremt de visualiser le clignotement
  }
  fill_buffer(BACKGROUND, BLACK); //On éteind toutes les leds
  write_buffer(); //Ecriture des tableaux sur la matrice de leds
  lcd.clear(); //On efface tout le texte qui se trouve sur l'écran LCD
  lcd.setCursor(0, 0); //On se place au début de l'écran
  if(blnBeatBestScore) //Si le joueur a fait le meilleur score :
  {
    lcd.print("Meilleur score ! Il est de : "); //On affiche le score du joueur qui vient de battre le record :
  }
  else
  {
    lcd.print("Votre score est de : "); //On affiche le score du joueur :
  }
  lcd.print(bytNumberOfCaseOfSnake);
  if(!blnBeatBestScore) //Si le joueur n'a pas fait le meilleur score :
  {
    lcd.print(" points"); //On affiche "points " seulement quand on a plus de place donc quand le meilleur score n'est pas battu
  }
  lcd.setCursor(0, 1); //On passe à la 2ème ligne
  lcd.print("Appuyez sur Z pour recommencer"); //On indique que pour recommencer, il faut presser sur la touche Z de la nunchuk
  int i = 0; //Le compteur de temps est initialisé à zéro (pour le bouton z)
  lngTime = millis(); //On met l'heure à jour
  do //Boucle infinie tant que l'utilisateur n'appuie pas sur Z
  {
    z_button = 0; //On attend que le buton soit appuyé
    bytCountBuffer = 0; //On remet le compteur des octets reçus à zéro
    handshake();
   
    delay(20); //On attend 50 millisecondes pour ne pas surcharger l'arduino
    if(i >= 15) //On va attendre 15 fois les 20 millisecondes donc 300 millisecondes avant de décaler le texte pour avoir le temps de le lire
    {
      lcd.scrollDisplayLeft(); //On décale tous les caractères de l'écran vers la gauche
      i = 0; //On remet le compteur du temps à zéro
    }
    else //Si le temps désiré n'est pas encore atteint :
    {
      i++; //On incrémente le nombre de fois qu'on a attendu 20 millisecondes (pour le bouton z)
    }
    if(digitalRead(buttonBreadboardPin) == HIGH && (millis() - lngTime) >= intWaitTimeForPushButtonAgain)//Si on appuie sur le bouton et que ça fait 0.5 seconde que l'on a pas appuyé dessus avant :
    {
      if(blnPlayWithAccel == true) //On va changer le mode de commande
      {
        blnPlayWithAccel = false; //On utilise le joystick
        digitalWrite(pinLedYellow, LOW); //On allume la led pour indiquer que le jeu se joue avec l'accéléromètre
      }
      else //Si le bouton n'est pas appuyé ou que l'on avait appuyé il y a moins de intWaitTimeForPushButtonAgain millisecondes :
      {
        blnPlayWithAccel = true; //On utilise l'accéléromètre
        digitalWrite(pinLedYellow, HIGH); //On éteind la led pour indiquer que le jeu se joue avec le joystick
      }
      lngTime = millis(); //On met l'heure à jour
    }
   
    Wire.requestFrom(0x52, 6); //On demande é recevoir les octets du nunchuk
    while(Wire.available()) //Tant qu'on reçoit un octet :
    {
      bytBuffer[bytCountBuffer] = Wire.read(); //On lit l'octet reçu
      bytCountBuffer++; //On incrément le nombre d'octets reçu
    }
    if(bytCountBuffer >= 5) //Si on a reçu tous les octets :
    {
      if((bytBuffer[5] >> 0) & 1) //Si le bouton Z est appuyé :
      {
        z_button = 1; //On définit le bouton Z comme appuyé
      }
    }
  } while(z_button == 1); //On ne fait rien tant que le bouton Z n'est pas appuyé
  StartGame(); //On recommence la partie
}

/* Déplace le serpent vers le haut sur la matrice */
void MoveUp() //Y = Y - 1
{
  TABSNAKE[bytAllPointsSnakeX[bytNumberOfCaseOfSnake-1]][bytAllPointsSnakeY[bytNumberOfCaseOfSnake-1]] = 0; //On efface la dernière case du serpent
  for(byte i = bytNumberOfCaseOfSnake-1; i > 0; i--) //On déplace toutes les cases du serpent
  {
    bytAllPointsSnakeY[i] = bytAllPointsSnakeY[i-1]; //Vaut la case Y précédente
    bytAllPointsSnakeX[i] = bytAllPointsSnakeX[i-1]; //Vaut la case X précédente
  }
  if(bytAllPointsSnakeY[0] == 0) //Si la tête du serpent est au bord :
  {
    bytAllPointsSnakeY[0] = 8; //On la replace de l'autre côté
  }
  bytAllPointsSnakeY[0] = bytAllPointsSnakeY[0] - 1; //On "ajoute" la tête vers le haut
  TABSNAKE[bytAllPointsSnakeX[0]][bytAllPointsSnakeY[0]] = 1; //On ajoute la nouvelle place de la tête sur le tableau du serpent
//  //Ces 3 prochaines lignes sont commentées pour résoudre un bug qui fait disparaitre une case quand on change de côté :
//  if(bytAllPointsSnakeY[0] == 7) //Si le serpent vient de passer par un côté :
//  {
//    TABSNAKE[bytAllPointsSnakeX[bytNumberOfCaseOfSnake-1]][bytAllPointsSnakeY[7]] = 0; //On efface la dernière case du serpent qui est encore de l'autre côté
//  }
  RefreshAllTAB(); //Met à jour et récrit tous les tableaux du jeu
}

/* Déplace le serpent vers le bas sur la matrice */
void MoveDown() //Y = Y + 1
{
  TABSNAKE[bytAllPointsSnakeX[bytNumberOfCaseOfSnake-1]][bytAllPointsSnakeY[bytNumberOfCaseOfSnake-1]] = 0; //On efface la dernière case du serpent
  for(byte i = bytNumberOfCaseOfSnake-1; i > 0; i--) //On déplace toutes les cases du serpent
  {
    bytAllPointsSnakeY[i] = bytAllPointsSnakeY[i-1]; //Vaut la case Y précédente
    bytAllPointsSnakeX[i] = bytAllPointsSnakeX[i-1]; //Vaut la case X précédente
  }
  if(bytAllPointsSnakeY[0] == 7) //Si la tête du serpent est au bord :
  {
    bytAllPointsSnakeY[0] = -1; //On la replace de l'autre côté
  }
  bytAllPointsSnakeY[0] = bytAllPointsSnakeY[0] + 1; //On "ajoute" la tête vers le bas
  TABSNAKE[bytAllPointsSnakeX[0]][bytAllPointsSnakeY[0]] = 1; //On ajoute la nouvelle place de la tête sur le tableau du serpent
  if(bytAllPointsSnakeY[0] == 8) //Si le serpent vient de passer par un côté :
  {
    TABSNAKE[bytAllPointsSnakeX[bytNumberOfCaseOfSnake-1]][bytAllPointsSnakeY[0]] = 0; //On efface la dernière case du serpent qui est encore de l'autre côté
  }
  RefreshAllTAB(); //Met à jour et récrit tous les tableaux du jeu
}

/* Déplace le serpent vers la droite sur la matrice */
void MoveRight() //X = X - 1
{
  TABSNAKE[bytAllPointsSnakeX[bytNumberOfCaseOfSnake-1]][bytAllPointsSnakeY[bytNumberOfCaseOfSnake-1]] = 0; //On efface la dernière case du serpent
  for(byte i = bytNumberOfCaseOfSnake-1; i > 0; i--) //On déplace toutes les cases du serpent
  {
    bytAllPointsSnakeX[i] = bytAllPointsSnakeX[i-1]; //Vaut la case X précédente
    bytAllPointsSnakeY[i] = bytAllPointsSnakeY[i-1]; //Vaut la case Y précédente
  }
  if(bytAllPointsSnakeX[0] == 0) //Si la tête du serpent est au bord :
  {
    bytAllPointsSnakeX[0] = 8; //On la replace de l'autre côté
  }
  bytAllPointsSnakeX[0] = bytAllPointsSnakeX[0] - 1; //On "ajoute" la tête vers la gauche
  TABSNAKE[bytAllPointsSnakeX[0]][bytAllPointsSnakeY[0]] = 1; //On ajoute la nouvelle place de la tête sur le tableau du serpent
//  //Ces 3 prochaines lignes sont commentées pour résoudre un bug qui fait disparaitre une case quand on change de côté :
//  if(bytAllPointsSnakeX[0] == 7) //Si le serpent vient de passer par un côté :
//  {
//    TABSNAKE[bytAllPointsSnakeX[7]][bytAllPointsSnakeY[bytNumberOfCaseOfSnake-1]] = 0; //On efface la dernière case du serpent qui est encore de l'autre côté
//  }
  RefreshAllTAB(); //Met à jour et récrit tous les tableaux du jeu
}

/* Déplace le serpent vers la gauche sur la matrice */
void MoveLeft() //X = X + 1
{
  TABSNAKE[bytAllPointsSnakeX[bytNumberOfCaseOfSnake-1]][bytAllPointsSnakeY[bytNumberOfCaseOfSnake-1]] = 0; //On efface la dernière case du serpent
  for(byte i = bytNumberOfCaseOfSnake-1; i > 0; i--) //On déplace toutes les cases du serpent
  {
    bytAllPointsSnakeX[i] = bytAllPointsSnakeX[i-1]; //Vaut la case X précédente
    bytAllPointsSnakeY[i] = bytAllPointsSnakeY[i-1]; //Vaut la case Y précédente
  }
  if(bytAllPointsSnakeX[0] == 7) //Si la tête du serpent est au bord :
  {
    bytAllPointsSnakeX[0] = -1; //On la replace de l'autre côté
  }
  bytAllPointsSnakeX[0] = bytAllPointsSnakeX[0] + 1; //On "ajoute" la tête vers la droite
  TABSNAKE[bytAllPointsSnakeX[0]][bytAllPointsSnakeY[0]] = 1; //On ajoute la nouvelle place de la tête sur le tableau du serpent
  if(bytAllPointsSnakeX[0] == 8) //Si le serpent vient de passer par un côté :
  {
    TABSNAKE[bytAllPointsSnakeX[0]][bytAllPointsSnakeY[bytNumberOfCaseOfSnake-1]] = 0; //On efface la dernière case du serpent qui est encore de l'autre côté
  }
  RefreshAllTAB(); //Met à jour et récrit tous les tableaux du jeu
}

/* On écrit les lettre "Go" sur la matrice pour se préparer au début du jeu */
void MakeGoOnMatrix()
{
  boolean WRITEG[8][8] = //Tableau pour dessiner la lettre G
  {
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {1,0,0,0,1,1,1,1},
    {1,0,0,0,1,0,0,1},
    {1,0,0,0,0,0,0,1},
    {1,1,1,1,1,1,1,1},
  };
  boolean WRITEO[8][8] = //Tableau pour dessiner la lettre o
  {
    {0,0,0,0,1,1,1,1},
    {0,0,0,0,1,0,0,1},
    {0,0,0,0,1,0,0,1},
    {0,0,0,0,1,1,1,1},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
    {0,0,0,0,0,0,0,0},
  };
  fill_buffer(WRITEG, GREEN); //On affiche la lettre G pour écrire Go sur la matrice
  fill_buffer(WRITEO, ORANGE); //On affiche la lettre o pour écrire Go sur la matrice
  write_buffer(); //Ecriture des tableaux sur la matrice de leds
}

/* Initialisation ou recommencement du jeu */
void StartGame()
{
  lngTime = 0; //On réinitialise le compteur de temps
  bytNumberOfCaseOfSnake = 2; //Taille de sépart du serpent
  lcd.clear(); //On efface tout le texte qu'il y a sur l'écran
  lcd.setCursor(0, 0); //On met le curseur au début de la première ligne
  lcd.print("Score : "); //On affiche l'information pour le score
  lcd.print(bytNumberOfCaseOfSnake);
  lcd.setCursor(0, 1); //On met le curseur au début de la 2ème ligne
  lcd.print("Record : "); //On affiche l'information pour le meilleur score
  lcd.print(EEPROM.read(0)); //On affiche le meilleur score
 
  for(byte i = 0; i < 8; i++) //On efface/initialise toutes les cases de tous les tableaux :
  {
    for(byte j = 0; j < 8; j++) //On efface/initialise toutes les cases de tous les tableaux :
    {
      TABSNAKE[i][j] = 0; //On rempli le tableau avec des 0 pour commencer
      TABAPPLE[i][j] = 0; //On rempli le tableau avec des 0 pour commencer
      TABROCK[i][j] = 0; //On rempli le tableau avec des 0 pour commencer
    }
  }
  if(blnPlayWithAccel) //Si on joue avec l'accéléromètre :
  {
      ValueForMoveMinus = 100; //Sensibilité de l'accéléromètre
      ValueForMovePlus = 150; //Sensibilité de l'accéléromètre
  }
  else //Si on joue avec le joystick :
  {
      ValueForMoveMinus = 64; //Sensibilité du joystick
      ValueForMovePlus = 192; //Sensibilité du joystick
  }
  bytAllPointsSnakeX[0] = random(0, 7); //On place la tête du serpent aléatoirement sur l'axe x
  bytAllPointsSnakeY[0] = bytAllPointsSnakeX[0]; //On place la tête du serpent
  bytAllPointsSnakeX[1] = bytAllPointsSnakeX[0]; //On place la queue du serpent
  bytAllPointsSnakeY[1] = bytAllPointsSnakeX[0] + 1; //On place la queue du serpent
  TABSNAKE[bytAllPointsSnakeX[0]][bytAllPointsSnakeY[0]] = 1; //On place la case du serpent sur le tableau
  TABSNAKE[bytAllPointsSnakeX[1]][bytAllPointsSnakeY[1]] = 1; //On place la case du serpent sur le tableau
  bytNumberOfCaseOfSnake = 2; //Taille de sépart du serpent
  LastMove = "DOWN"; //On le fera partir vers le haut (ne fonctionne pas pour le moment)
  blnDeath = false; //Le serpent est vivant
  blnMoved = false; //L'utilisateur n'a pas encore bougé
  do //Placement de la pomme sur la matrice :
  {
    blnRestartPutApple = false; //Par défaut, la pomme est placée correctement
    bytPointPositionAppleX = random(0, 8); //On trouve une nouvelle position X aléatoire pour la pomme
    bytPointPositionAppleY = random(0, 8); //On trouve une nouvelle position Y aléatoire pour la pomme
    for(byte i = 1; i < bytNumberOfCaseOfSnake-1; i++) //On passe sur toutes les cases
    {
      if(bytPointPositionAppleX == bytAllPointsSnakeX[i] && bytPointPositionAppleY == bytAllPointsSnakeY[i]) //On regarde si la pomme est sur le point :
      {
        blnRestartPutApple = true; //On doit replacer la pomme
      }
    }
    if(bytPointPositionRockX == bytAllPointsSnakeX[0] && bytPointPositionRockY == bytAllPointsSnakeY[0]) //On regarde si la pomme est sur la tête :
    {
      blnRestartPutRock = true; //On doit replacer la pomme
    }
  } while(blnRestartPutApple); //On recommance tant que la pomme est sur le serpent
 
  do //Placement de la pierre sur la matrice :
  {
    blnRestartPutRock = false; //Par défaut, la pierre est placée correctement
    bytPointPositionRockX = random(0, 8); //On trouve une nouvelle position X aléatoire pour la pierre
    bytPointPositionRockY = random(0, 8); //On trouve une nouvelle position Y aléatoire pour la pierre
    for(byte i = 1; i < bytNumberOfCaseOfSnake-1; i++) //On passe sur toutes les cases
    {
      if(bytPointPositionRockX == bytAllPointsSnakeX[i] && bytPointPositionRockY == bytAllPointsSnakeY[i]) //On regarde si la pierre est sur le point :
      {
        blnRestartPutRock = true; //On doit replacer la pomme
      }
    }
    if(bytPointPositionRockX == bytAllPointsSnakeX[0] || bytPointPositionRockY == bytAllPointsSnakeY[0]) //On regarde si la pierre est sur la même ligne ou colonne que le point :
    {
      blnRestartPutRock = true; //On doit replacer la pierre
    }
  } while(blnRestartPutRock); //On recommance tant que la pierre est sur le serpent
 
  TABAPPLE[bytPointPositionAppleX][bytPointPositionAppleY] = 1; //On place la pomme sur le tableau
  TABROCK[bytPointPositionRockX][bytPointPositionRockY] = 1; //On place la pierre sur le tableau
  RefreshAllTAB(); //Met à jour et récrit tous les tableaux du jeu
}

/* Initialisation des pins, de la matrice, de l'écran, de la transmition série et de la calibration du nunchuck */
void setup()

  Serial.begin(9600); //Vitesse de transfert du port série (usb)
 
  randomSeed(analogRead(0)); //Pour avoir vraiment des nombre aléatoire. (Il faut utiliser un pin connecté à rien et non initialisé)
 
  pinMode(DATAOUT, OUTPUT); //Pin pour envoyer les données à la matrice de leds
//  pinMode(DATAIN, INPUT); //Pas utilisé dans ce cas
  pinMode(SPICLOCK, OUTPUT); //Pin pour la synchronisation
  pinMode(SLAVESELECT, OUTPUT);
  digitalWrite(SLAVESELECT, HIGH); //Désactivation
 
  pinMode(pinLedYellow, OUTPUT); //On définit le pin de la led jaune en sortie
  pinMode(buttonBreadboardPin, INPUT); //On définit le pin du bouton en entrée
 
  blnPlayWithAccel = false; //Par défaut, on ne joue pas avec l'aaccéléromètre
  digitalWrite(pinLedYellow, LOW); //On allume la led pour indiquer que le jeu se joue avec l'accéléromètre
 
  Wire.begin(); //On commence la séquence d'initialisation de la nunchuk
  Wire.beginTransmission(0x52);
  Wire.write(0xF0);
  Wire.write(0x55);
  Wire.write(0x00); //Envoie les envois à l'adresse zero.
  Wire.endTransmission(); //Stoppe la transmition
 
//  EEPROM.write(0, 0); //Pour remettre le meilleur score à 0. Attention, le nombre de cycle d'écriture sur l'arduino est limité à 100'000 ! Donc ne pas oublier de décommenter cette ligne !
 
  lcd.begin(16, 2); //On indique le nombre de colonnes et de lignes de l'écran
  lcd.print("Bienvenue sur"); //Message d'accueil
  lcd.setCursor(0, 1); //On met le curseur au début de la deuxième ligne
  lcd.print("Snakeduino !"); //On affiche le nom du jeu
 
  MakeGoOnMatrix(); //On affiche "Go" sur la matrice de leds
 
  lngTime = millis(); //On met l'heure à jour
  for(byte i = 0; i < 100; i++) //On va attendre 2 secondes en regardant si l'utilisateur appuie sur le bouton :
  {
    delay(20); //On attend un petit peu pour pouvoir lire l'écran et se préparer au début du jeu
    if(digitalRead(buttonBreadboardPin) == HIGH && (millis() - lngTime) >= intWaitTimeForPushButtonAgain)//Si on appuie sur le bouton et que ça fait 0.5 seconde que l'on a pas appuyé dessus avant :
    {
      if(blnPlayWithAccel == true) //On va changer le mode de commande
      {
        blnPlayWithAccel = false; //On utilise le joystick
        digitalWrite(pinLedYellow, LOW); //On allume la led pour indiquer que le jeu se joue avec l'accéléromètre
      }
      else
      {
        blnPlayWithAccel = true; //On utilise l'accéléromètre
        digitalWrite(pinLedYellow, HIGH); //On éteind la led pour indiquer que le jeu se joue avec le joystick
      }
      lngTime = millis(); //On met l'heure à jour
    }
  }
 
  StartGame(); //On initialise et démarre le jeu
}

/* Boucle infinie principale qui va appeler la fonction pour les données nunchuck puis faire le sleep de la boucle : */
void loop()
{
  Wire.requestFrom(0x52, 6); //On demande à recevoir les données
  while(Wire.available()) //Tant qu'on reçoit un byte :
  {
    bytBuffer[bytCountBuffer] = Wire.read(); //On lit le byte reçu
    bytCountBuffer++; //On incrémente le nombre de bytes reçu
  }
  if(bytCountBuffer >= 5) //Si on a reçu les 6 bytes :
  {
    parseNunchuk(); //On va analyser ce qu'ils contiennent et bouger le jeu en fonction de ces données
  }
  bytCountBuffer = 0; //On remet le compteur du buffer à zéro
  handshake();
  delay(intSpeedSnake); //On attend quelques millisecondes de pause pour que le serpent n'aie pas trop vite
}


Si vous avez des questions ou des idées d'amélioration, n'hésitez pas Wink




______________________________________________________
Message Publicité 
PublicitéSupprimer les publicités ?


Répondre en citant
Message [Arduino] Snakeduino 
Shocked C'est vraiment jolie ...! ça serai possible avec une Led Matrix plus grande ?




______________________________________________________


Répondre en citant
Message [Arduino] Snakeduino 
Et c'est trente fois plus beau en vrai, il faudra vraiment que je fasse une vidéo parce que là vous ne voyez pas grand chose. Rolling Eyes

Oui bien sur que l'on peut utiliser une matrice plus grande mais elle sera plus chère. Celle-ci, je l'ai acheté 25 Euros sur (watterott) et elle ne peut faire que 3 couleurs (rouge, jaune et orange). Pour la même en RGB c'est 43 Euros, et si on veut par exemple une 32x8 c'est plus de 50 Euros (sans compter les frais de ports). Il y en a des moins cher, mais elles n'ont pas de connexion série donc il faut utiliser quasiment tous les pins de l'arduino et magouiller un peu. Au final tout ce matériel, ça coûte quand même cher.

Mais si j'en avais une, au niveau du code, il faudrait juste changer la taille de la matrice et les dessins (tableaux 2 dimensions) déjà fait.




______________________________________________________
Répondre en citant
Message [Arduino] Snakeduino 
Lut Sablier
woua c est impressionnant




______________________________________________________
Faites paraitre votre batch sur BatchClipboard
Visiter le site web du posteur
Répondre en citant
Message [Arduino] Snakeduino 
C'est vraiment impressionnant... Mais je trouve que c'est un peu cher juste pour jouer a Snake Neutral




______________________________________________________
Mon site web : http://textquestrpg.weebly.com/
Un petit jeu sympa : http://teacher-story.com/t/kT81
Visiter le site web du posteur
Répondre en citant
Message [Arduino] Snakeduino 
Hello ^^

OMG Very Happy super good game sablier Okay Okay
c'est violent comme ça déchire grave ^^
Par contre je suis étoné de voir un code aussi long pour un snake xD j'ai un peu l'habitude j'en ai programmer plusieurs en C,ti-basic et batch et je t'assure que l'on peux faire plus court a mon avis ^^
Aussi faudrait que t'y aille plus mollo sur la notation hongroise... genre mettre "cPointPositionAppleXOld" à la place "bytPointPositionAppleXOld" ou a la rigueur tu peux le replacer par "bPointPositionAppleXOld" vu que le type boolean est un pseudo-type qui est un char Mr. Green
les préfixes couramment admis sont:
Code:
b > boolean
c > char (byte)
i > int ou long
lp,ptr,p > pointeurs


aussi evite l'utilisation de const pour les variables globales, dans ce cas il faut preferer les #define, les const sont surtout pour éviter les effets de bords dans les fonctions.

sinon utilises les structures plutôt que des variables pour les coordonnées, ce sera plus lisible
Code:
typedef struct COORD{
short x;
short y;
} COORD, *LPCOORD;

Enfin tu peux jouer l’économie avec un seul buffer Smile

m'enfin pour ma part ce sera +100 000 rien que pour l'idée qui déchire ^^

@+

EDIT : [troll]Tu sais que y'a des normes pour l'électronique ?
Alors si on pouvait avoir un vrai schéma avec les représentations standard(ISO ou AFNOR) des composants, ce serait cool xD[/troll]




______________________________________________________
--
> Que pensez vous de l'ajout du repertoire point dans $PATH ?
Ma version de troll 18.0.32 beta 3 vient de me faire un core dump.
-+- SE in Guide du Linuxien Pervers : Bien développer son troll -+-

[Dos9]
Visiter le site web du posteur Skype
Répondre en citant
Message [Arduino] Snakeduino 
Salut.

Oui c'est vrai qu'il est long mais il faut dire qu'il y a pas mal de choses à gérer (comme la gestion des mouvements avec la manette, l'affichage des textes sur l'écran LCD, le changement de mode de commande, les "images" affichées sur la matrice, ...) mais on peut sûrement le raccourcir.

La "notation hongroise" ? Mr. Green C'est comme ça que j'ai appris à programmer en cours, en modifiant un peu la méthode pour comprendre tout de suite à quoi sert la variable en plus du type. Mais bon, ça ne change pas grand chose de mettre le type en 3 lettres plutôt qu'une.

Ma notation habituelle :
Citation:

bln > boolean
chr, byt > char (byte)
int, lng > int, long

Je ne savais pas ce que ça change mais je voyais souvent le const utilisé dans les autres scripts, merci.

Je n'ai pas compris ton code. Ce n'est pas du code Arduino, ça change quoi de faire ça (à part la lisibilité) ?

Tu parles de quel 2ème buffer ? Celui pour la nunchuk ?

J'ai déjà fourni un "vrai" schéma, c'est le fichier Fitzing (.fzz) en téléchargement. J'avais affiché seulement la représentation réelle car c'est plus simple pour ceux qui ne connaissent pas. Voilà les 2 autres schémas : http://total-informatique.com/fichiers/perso/uploads/arduino/snakeduino/CaptureCircuitImprime.PNG et http://total-informatique.com/fichiers/perso/uploads/arduino/snakeduino/CaptureVueSchematique.PNG

Oui c'est cher au moins on peut réutiliser le matériel pour en apprendre plus et faire d'autres projets (mais il faut démonter le premier moz_yell).

Je ne peux malheureusement pas faire de vidéo de démo du jeu parce que la matrice est floue quand je la filme et je n'ai pas de trépied pour la caméra. oz_cry

Thanx pour le remarques moz_smile




______________________________________________________
Répondre en citant
Message [Arduino] Snakeduino 
Re !

sablier94 a écrit:
La "notation hongroise" ? Mr. Green C'est comme ça que j'ai appris à programmer en cours, en modifiant un peu la méthode pour comprendre tout de suite à quoi sert la variable en plus du type. Mais bon, ça ne change pas grand chose de mettre le type en 3 lettres plutôt qu'une.

Ma notation habituelle :
Citation:

bln > boolean
chr, byt > char (byte)
int, lng > int, long

D'accord, je comprenais pas trop tes préfixes Mr. Green

Citation:
Je ne savais pas ce que ça change mais je voyais souvent le const utilisé dans les autres scripts, merci.

Bah ça donne la même chose, mais sur le plan de l'utilisation, #define et plus adapté que de const, car si tu ne l'utilises pas, la variable ne sera pas générée dans le code source.

Citation:
Je n'ai pas compris ton code. Ce n'est pas du code Arduino, ça change quoi de faire ça (à part la lisibilité) ?

Enfaite c'est du code C, mais comme arduino est basé sur C et implémente tous les standards de C, tu peux créer des structures Mr. Green
donc tu mets
Code:
typedef struct COORD{
short x;
short y;
} COORD, *LPCOORD;

au sommet de ton code, et ça crée une structure nommée COORD qui contient deux variables (x et y).
puis dans tes définitions tu mets
Code:
COORD iCoord; /*cree une structure COORD */

après tu peux accèder à x et y par:
Code:
iCoord.x ; iCoord.y;

comme ça c'est plus structuré tu n'as plus deux variables complètement autonomes, et comme ça tes noms de variables sont un peux moins à rallonge. la c'est succin comme expliquation, si tu veux y'a un excellent tuto sur le C sur le sdz Razz


Citation:
Tu parles de quel 2ème buffer ? Celui pour la nunchuk ?

Non je parle des trois tableaux TABSNAKE, TABROCK et TABAPPLE. Il suffit de les fusionner dans un seul tableau de type char en donnant des valeurs différentes au bloc du serpents, pierres et pommes, vu qu'a priori il ne peut y avoir ni pomme ni pierre ni serpent simultanément sur la même case. A la limite tu devrais même travailler avec comme seul buffer out_buffer[], dans lequel tu stockerais les case du snake par la valeur ORANGE, des pierres par la valeur RED et des pommes par GREEN

Citation:
J'ai déjà fourni un "vrai" schéma, c'est le fichier Fitzing (.fzz) en téléchargement. J'avais affiché seulement la représentation réelle car c'est plus simple pour ceux qui ne connaissent pas. Voilà les 2 autres schémas : http://total-informatique.com/fichiers/perso/uploads/arduino/snakeduino/CaptureCircuitImprime.PNG et http://total-informatique.com/fichiers/perso/uploads/arduino/snakeduino/CaptureVueSchematique.PNG

ah oui, j'avoue Mea cupla Mort de Rire

@+




______________________________________________________
--
> Que pensez vous de l'ajout du repertoire point dans $PATH ?
Ma version de troll 18.0.32 beta 3 vient de me faire un core dump.
-+- SE in Guide du Linuxien Pervers : Bien développer son troll -+-

[Dos9]
Visiter le site web du posteur Skype
Répondre en citant
Message [Arduino] Snakeduino 
Oui j'avais justement commencé à faire avec un seul buffer mais j'ai changé car c'est plus simple à gérer comme ça je trouve.

Merci pour tes conseils Okay




______________________________________________________
Répondre en citant
Message [Arduino] Snakeduino 
Bonjour,

(petit déterrage) pourriez vous me dire où trouve le fichier LiquidCrystal.h ?

je possède un afficheur DEM 16216 SYH-LY et impossible de le configurer (j'utilise un PIC18f45k22).

Merci d'avance ,

blackmore951



Répondre en citant
Message [Arduino] Snakeduino 
blackmore951 a écrit:
pourriez vous me dire où trouve le fichier LiquidCrystal.h ?


Salut ! C'est le fichier "header" de la librairie LiquidCrystal, trouvable dans l'éditeur arduino (téléchargement => http://arduino.cc/en/Main/Software/) Very Happy

Sinon GG ce code est énorme ! j'adore l'arduino et je viens de découvrir que des personnes l'utilisaient sur ce fofo !
J'ai jamais utilisé une matrice led, mais je pense qu'un écran tft (10-20$ ici => http://www.dx.com/s/tft+screen?category=499&PriceSort=up)
ça serai encore mieux (même si la lib tftscreen est à alléger).
et au lieu d'utiliser un nunchuck, tu peux prendre une board avec un joystick (http://www.dx.com/s/joystick?PriceSort=up&category=436), ce qui est largement moins cher (pas de marque nintendo ^^) et en plus ça allègera le code !



Visiter le site web du posteur
Message [Arduino] Snakeduino 


Montrer les messages depuis:
Répondre au sujet Page 1 sur 1
  



Index | créer un forum | Forum gratuit d’entraide | Annuaire des forums gratuits | Signaler une violation | Conditions générales d'utilisation
Copyright 2008 - 2016 // Batch