ENIB 2024 : Space Invador de l'espace

De Les Fabriques du Ponant
Révision datée du 25 janvier 2024 à 11:19 par Erellrch (discussion | contributions) (Code Arduino)
Aller à : navigation, rechercher

Space Invador de l'espace

description (résumé)

éventuelle photo de l'équipe

Introduction

L'objectif de notre jeu est de tuer l'ennemi. Notre Space Invador se compose de 16x16 leds représentant un vaisseau et des ennemis à abattre. Grâce aux boutons poussoirs, nous pouvons commander la position du vaisseau et donc diriger les tirs.

Outil et matériel

· Carte arduino
· 16x16 leds
· Boutons poussoirs
· Câbles électroniques

fichiers à joindre

Code Arduino

<syntaxhighlight lang="Arduino" line>

  1. include <FastLED.h>
  2. include <SPI.h>
  1. define NUM_STRIPS 1
  2. define NUM_LEDS_PER_STRIP 256

CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP];

int color[5] {0x000000,0x000001,0x010000,0x000100,0x010100}; int position, position_vaisseau = 4, delay_tire = 0, level = 1; bool vivant = true, en_partie = true, ennemi = true;

int level_actuelle[16][16];

const int level_1[16][16] { \

 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
 {0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0}, \
 {0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0}, \
 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}  \

};

const int level_2[16][16] { \

 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
 {0, 0, 2, 2, 0, 0, 2, 2, 2, 2, 0, 0, 2, 2, 0, 0}, \
 {0, 0, 2, 2, 0, 0, 0, 2, 2, 0, 0, 0, 2, 2, 0, 0}, \
 {0, 0, 0, 0, 0, 0, 0, 2, 2, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0}  \

};

const int level_3[16][16] { \

 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
 {0, 0, 0, 2, 0, 0, 0, 2, 2, 0, 0, 0, 2, 0, 0, 0}, \
 {0, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 2, 2, 2, 0, 0}, \
 {0, 0, 2, 0, 2, 0, 0, 2, 2, 0, 0, 2, 0, 2, 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, 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, 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, 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, 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, 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, 0, 0}  \

};

const int level_4[16][16] { \

 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
 {0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0}, \
 {0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0}, \
 {0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0}, \
 {0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0}, \
 {0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0}, \
 {0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 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, 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, 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, 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, 0, 0, 0, 0, 0}, \
 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}  \

};

const int game_over[16][16] { \

 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
 {2, 2, 2, 0, 2, 2, 2, 0, 2, 0, 2, 0, 2, 2, 2, 0}, \
 {2, 0, 0, 0, 2, 0, 2, 0, 2, 2, 2, 0, 2, 0, 0, 0}, \
 {2, 0, 2, 0, 2, 2, 2, 0, 2, 0, 2, 0, 2, 2, 0, 0}, \
 {2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 0, 0}, \
 {2, 2, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 2, 2, 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, 0}, \
 {0, 2, 2, 2, 0, 2, 0, 2, 0, 2, 2, 2, 0, 2, 2, 2}, \
 {0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2}, \
 {0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 2, 0, 0, 2, 2, 0}, \
 {0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 0, 0, 2, 0, 2}, \
 {0, 2, 2, 2, 0, 0, 2, 0, 0, 2, 2, 2, 0, 2, 0, 2}, \
 {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}, \
 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}  \

};

const int win[16][16] { \

 {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}, \
 {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}, \
 {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}, \
 {0, 2, 0, 0, 0, 2, 0, 2, 2, 2, 0, 2, 0, 0, 2, 0}, \
 {0, 2, 0, 2, 0, 2, 0, 0, 2, 0, 0, 2, 2, 0, 2, 0}, \
 {0, 2, 0, 2, 0, 2, 0, 0, 2, 0, 0, 2, 0, 2, 2, 0}, \
 {0, 0, 2, 0, 2, 0, 0, 2, 2, 2, 0, 2, 0, 0, 2, 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, 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, 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, 0}  \

};


void setup() {

 // tell FastLED there's 60 NEOPIXEL leds on pin 2
 FastLED.addLeds<NEOPIXEL, 2>(leds[0], NUM_LEDS_PER_STRIP);
 // tell FastLED there's 60 NEOPIXEL leds on pin 3
 FastLED.addLeds<NEOPIXEL, 3>(leds[1], NUM_LEDS_PER_STRIP);
 // tell FastLED there's 60 NEOPIXEL leds on pin 4
 FastLED.addLeds<NEOPIXEL, 4>(leds[2], NUM_LEDS_PER_STRIP);
 Serial.begin(9600); 
 memcpy(level_actuelle,level_1,sizeof(level_1));
 
 pinMode(A0,INPUT);
 pinMode(D7,INPUT);

}


void affiche() {

 //carte
 for(int x = 0; x < 16; x++) {
   for(int y = 0; y < 16;y++){
     if (x%2 == 1){
       position = x*16+y;
     }
     else{
       position = x*16+15-y;
     }
     leds[0][position] = color[level_actuelle[x][y]];
   }
 }
 FastLED.show();

}

void create_vaisseau(){

 //pos entre 2 et 15
 clear();
 level_actuelle[13][position_vaisseau] = 1;
 level_actuelle[13][position_vaisseau-1] = 1;
 level_actuelle[12][position_vaisseau-1] = 1;
 level_actuelle[13][position_vaisseau-2] = 1;
 level_actuelle[14][position_vaisseau-2] = 1;
 level_actuelle[14][position_vaisseau] = 1;
 FastLED.show();

}

void clear(){

 for(int x = 10; x < 15; x++) {
   for(int y = 0; y < 16;y++){
     if (level_actuelle[x][y] == 1){
       level_actuelle[x][y] = 0;
     }
   }
 }

}


void move(){

 position_vaisseau = int(analogRead(A0)*16/1024);
 if (position_vaisseau >= 16){
   position_vaisseau = 15;
 }
 else if (position_vaisseau <= 1){
   position_vaisseau = 2;
 }

}

void tirer() {

 if (true) {
   level_actuelle[11][position_vaisseau-1] = 103;
 }

}

void tick(){

 ennemi = false;
 for(int x = 0; x < 16; x++) {
   for(int y = 0; y < 16;y++){
     if (level_actuelle[x][y] == 3){ //tire joueur
       if (x==0){
         level_actuelle[x][y] = 0;
       }
       else if ((level_actuelle[x-1][y]==4) || (level_actuelle[x-1][y]==104)){
         level_actuelle[x-1][y] = 3;
         level_actuelle[x][y] = 104;
       }
       else if (level_actuelle[x-1][y]!=0){
         level_actuelle[x-1][y] = 0;
         level_actuelle[x][y] = 0;
       }
       else{
         level_actuelle[x-1][y] = 3;
         level_actuelle[x][y] = 0;
       }
     }
   
     else if (level_actuelle[x][y] == 2){ //vaisseau enemi
       ennemi = true;
       if ((level_actuelle[x+1][y] == 0)&(random(0,40)==1)){
         level_actuelle[x+1][y] = 104; //chiffre temporaire pour pas refaire son action
       }
     }
     else if (level_actuelle[x][y] == 104){
       level_actuelle[x][y] = 4;
     }
     else if (level_actuelle[x][y] == 103){
       level_actuelle[x][y] = 3;
     }
     else if (level_actuelle[x][y]== 4){
       if (x==15){
         level_actuelle[x][y] = 0;
       }
       if ((level_actuelle[x+1][y] == 0) &(x<15)){
         level_actuelle[x+1][y] = 104;
         level_actuelle[x][y] = 0;
       }
       else if (level_actuelle[x+1][y] == 3){
         level_actuelle[x+1][y] = 104;
         level_actuelle[x][y] = 3;
       }
       else if (level_actuelle[x+1][y] == 1){
         level_actuelle[x][y] = 0;
         //game over
         en_partie = false;
         vivant = false;
       }
     }
   }
 }

}

void loop() {

 while (en_partie){
   tick();
   affiche();
   create_vaisseau();
   if ((digitalRead(D7)) & (delay_tire == 0)){
     tirer();
     delay_tire = 2;
   }
   else if (delay_tire !=0){
     delay_tire -= 1;
   }
   move();
   if (!ennemi){
     if (level == 4){
       en_partie = false;
     }
     else{
       level +=1;
     }
     if(level==2){
       memcpy(level_actuelle,level_2,sizeof(level_2));
     }
     else if(level==3){
       memcpy(level_actuelle,level_3,sizeof(level_3));
     }
     else if(level==4){
       memcpy(level_actuelle,level_4,sizeof(level_4));
     }
   }
   delay(75);
 }
 if (vivant){
   memcpy(level_actuelle,win,sizeof(win));
 }
 else{
   memcpy(level_actuelle,game_over,sizeof(game_over));
 }
 affiche();
 delay(200);
 if (digitalRead(D7)){
     memcpy(level_actuelle,level_1,sizeof(level_1));
     level = 1;
     vivant = true;
     en_partie = true;
 }

}

étapes de fabrication

étape 1

Création du code arduino et test de celui-ci sur la carte.

vignette]

étape 2

Création de la maquette en carton.

vignette] vignette]

étape 3

Test du jeu.

Troubleshouting

Difficultés rencontrées : création du code arduino
Solutions : test du code, analyse des erreurs, aide des intervenants

Sources et documentation complémentaire

ne pas modifier sous cette ligne