ENIB 2022 : Catch the middle

De Les Fabriques du Ponant
Révision datée du 17 janvier 2022 à 16:09 par Emmanuel (discussion | contributions) (projet réalisé par :)
Aller à : navigation, rechercher

Photo du projet

Catch the middle IS3.jpg

Projet réalisé par :

-Yann Le Masson
-Hugo Boulouard
-Malo Cadier
-Léo Orveillon

Que fait ce projet ?

Jeux ludique dans lequel la réactivité prime.

Une lumière se balade le long du ruban, le joueur doit appuyer sur le bouton dès que la lumière arrive au centre.

La lumière accélère au fil du temps

Le projet fonctionne autour d'une carte arduino sur laquelle on branche un bouton et un ruban de leds

Liste des composants

  • Bouton poussoir style Arcade
  • Arduino nano
  • 2 rubans de LED adressable (85 LEDs pour être exacte)
  • Carton
  • Câbles mini-USB
  • Câbles

Outils

  • Cutter
  • Marqueur noir
  • Pistolet à colle
  • Scotch
  • Fer à souder

Réalisation

Branchez tous les rubans de LEDs en série

Ensuite, suivez le schéma ci-dessous :

Schema elec catch the middle.jpg

Code

#include "FastLED.h"                    //bibliothèque pour controler le ruban led
#define NUM_LEDS 86
#define NUM_OF_LEDS_BY_LEVEL 17         // nombre de leds par niveau
#define NUM_OF_LEVELS 5                  // nombre de niveaux
#define PIN_BTN 3                       // Entree du bouton
#define PIN_LEDS 2                      // Sortie du ruban led

// Dans ce programme nous avons utilisé presque intégralement des variables globales

CRGB leds[NUM_LEDS];
int level = 0;        // niveau auquel le joueur est
int delay_level = 30; // délai qui permet de controler la vitesse de déplacement de la led
auto color = CRGB::Purple; // couleur de la led qui se déplace
int score = 0;           // socre du joueur
const double coef[] = {1, 1.4, 1.7, 1.9, 2, 2.2}; // coefficient multiplicateur de point par niveau
int last_point = 0;     // sauvegarde de la derniere led allumée pour la rallumer après flash()


// Déclarations de fonctions
int compute_score(int score_of_level);    // calcul du score par niveau
int up();           // deplacement led
int down();         // deplacement led dans l'autre sense
void level_up();    // passage de niveau
void flash();       // animation de victoire d'un niveau


void setup() {
  FastLED.addLeds<NEOPIXEL, 2>(leds, NUM_LEDS);     // setup du ruban de led sur la sortie PIN_LEDS => 2
  pinMode(PIN_BTN, INPUT);                          // setup du bouton dur l'entrée PIN_BTN => 3
  Serial.begin(9600);                               // setup moniteur série pour debug
}

void loop() {

  int score_of_level;
  if (score_of_level = up())              // led avance dans un sense
  {
    score += compute_score(score_of_level);       // ajout score du niveau
    level_up();
  }
  else if (score_of_level = down())       // led avance dans l'autre sense
  {
    score += compute_score(score_of_level);       // ajout score du niveau
    level_up();
  }


}

int compute_score(int score_of_level)
{
  return (NUM_OF_LEDS_BY_LEVEL/2 - (int)abs((level * NUM_OF_LEDS_BY_LEVEL + NUM_OF_LEDS_BY_LEVEL / 2) - score_of_level)) * coef[level] + 1;
  // On calcul le nombre de leds d'un niveau moins la différence entre la led du joueur et celle du milieu on ajoute 2 et on multiplie par le coefficient de points du level
}

int up()
{
  for (int i = NUM_OF_LEDS_BY_LEVEL * level; i <= (NUM_OF_LEDS_BY_LEVEL * level + NUM_OF_LEDS_BY_LEVEL - 1); i++)
  {
    if (digitalRead(PIN_BTN))   // appuie sur le bouton
    {
      while (digitalRead(PIN_BTN))    // blocage du bouton tant que celui-ci n'a pas été relaché
      {
        delay(2);
      }
      last_point = i-1;     // on concerve la valeur de la led choisie pour la réafficher après le flash
      return i - 1;   // renvoie la position de la led au moment de l'appuie sur le bouton
    }
    leds[i - 1] = CRGB::Black;
    delay(3);

    leds[level * NUM_OF_LEDS_BY_LEVEL + NUM_OF_LEDS_BY_LEVEL / 2] = CRGB::White;
    leds[i] = color;

    FastLED.show();
    delay(delay_level);
  }
  leds[NUM_OF_LEDS_BY_LEVEL * level + 20] = CRGB::Black;
  FastLED.show();
  delay(delay_level);
  return 0;

}

int down()
{

  for (int i = NUM_OF_LEDS_BY_LEVEL * level +  NUM_OF_LEDS_BY_LEVEL - 1; i >= NUM_OF_LEDS_BY_LEVEL * level ; i--)
  {
    if (digitalRead(PIN_BTN))
    {
      while (digitalRead(PIN_BTN))
      {
        delay(2);
      }
      last_point = i+1;
      return i + 1;   // renvoie la position de la led au moment de l'appuie sur le bouton
    }
    leds[i + 1] = CRGB::Black;
    delay(3);

    leds[level * NUM_OF_LEDS_BY_LEVEL + NUM_OF_LEDS_BY_LEVEL / 2] = CRGB::White;
    leds[i] = color;

    FastLED.show();
    delay(delay_level);
  }
  leds[NUM_OF_LEDS_BY_LEVEL] = CRGB::Black;
  FastLED.show();
  delay(delay_level);
  return 0;


}
void flash()   // fonction de décoration qui fait clignoter les leds en blanc avant le passage de niveau
{
  for (int cpt = 0; cpt < 4; cpt++) 
  {
    for (int i = NUM_OF_LEDS_BY_LEVEL * level; i <= (NUM_OF_LEDS_BY_LEVEL * level + NUM_OF_LEDS_BY_LEVEL - 1); i++)  // On met toute les leds du niveau en blanc
    {
      leds[i] = CRGB::White;
    }
    FastLED.show();

    delay(100);
    for (int i = NUM_OF_LEDS_BY_LEVEL * level; i <= (NUM_OF_LEDS_BY_LEVEL * level + NUM_OF_LEDS_BY_LEVEL - 1); i++) // On éteint toutes les leds du niveau
    {
      leds[i] = CRGB::Black;
    }
    FastLED.show();
    delay(100);
  }
  leds[last_point] = CRGB::Red;
}

void score_leds()   // affichage du score avec les leds
{
  for (int i = 0; i < score; i++)
  {
    leds[i] = CRGB::Red;

    FastLED.show();
    delay(10);
  }
}

void reset_leds()   // on éteint toutes les leds
{
  for (int i = 0; i < NUM_LEDS; i++)
  {
    leds[i] = CRGB::Black;

  }
  FastLED.show();
}

void animation_attente()
{
    for(int i = 0; i < NUM_LEDS; i++)
    {
      leds[i].red = random(0,255);
      leds[i].green = random(0,255);
      leds[i].blue = random(0,255);
    }
    FastLED.show();
  
}
void level_up()   // changement de niveau
{
  flash();  // animation
  level++;  // incrémentation de la variable niveau
  delay_level -= 4; // le jeu devient de plus en plus rapide
  if (level >= NUM_OF_LEVELS)   // fin du jeu
  {
    reset_leds();
    score_leds();   // affichage score
    delay(3000);
    reset_leds();
    while (!digitalRead(PIN_BTN))   // on attend que l'utilisateur appuie sur un bonton
    {
      animation_attente();
      delay(200);
    }
    while (digitalRead(PIN_BTN))  // on vérifie que le bouton n'est pas resté appuyé
    {
      delay(10);
    }
    // on réinitialise le jeu
    level = 0;      
    reset_leds();
    score = 0;
    delay_level = 30;


  }


}

Catégories