Jump to: navigation, search

Système Technique Simple - BA3:Annie Warenghien

Titre : Addiction

ExamenElectro2.jpg

Note d'intention artistique

Mon intention était de montrer qu'avec un simple jeu on peut vite devenir addict à quelque chose. Plus on avance dans le jeu plus on à envie de parcourir de la distance donc si on perd, on veut retenter pour essayer de battre son record.

Synthèse technique détaillant la mise en oeuvre du dispositif technique choisi

  • 1x Carte Arduino UNO
  • 1x Un écran LCD (16x2)
  • 1x Bouton
  • 1x Résistance (220Ω)
  • 17x Cable

J’ai choisi un écran LCD pour créer un jeu simple avec un seul bouton pour le contrôler. Quand on appuie sur le bouton le personnage saut au-dessus des obstacles. Un compteur à était mis en place pour voir le nombre de distance parcourue par le personnage.

Fritzing

Plan addiction.jpg Plan shématique.jpg

Arduino

https://123d.circuits.io/circuits/1023084-arduino-lcd-game?#breadboard

#include <LiquidCrystal.h>
  1. define PIN_BUTTON 2
  2. define PIN_AUTOPLAY 1
  3. define PIN_READWRITE 10
  4. define PIN_CONTRAST 12
  1. define SPRITE_RUN1 1
  2. define SPRITE_RUN2 2
  3. define SPRITE_JUMP 3
  4. define SPRITE_JUMP_UPPER '.'
  5. define SPRITE_JUMP_LOWER 4
  6. define SPRITE_TERRAIN_EMPTY ' '
  7. define SPRITE_TERRAIN_SOLID 5
  8. define SPRITE_TERRAIN_SOLID_RIGHT 6
  9. define SPRITE_TERRAIN_SOLID_LEFT 7
  1. define HERO_HORIZONTAL_POSITION 1
  1. define TERRAIN_WIDTH 16
  2. define TERRAIN_EMPTY 0
  3. define TERRAIN_LOWER_BLOCK 1
  4. define TERRAIN_UPPER_BLOCK 2
  1. define HERO_POSITION_OFF 0
  2. define HERO_POSITION_RUN_LOWER_1 1
  3. define HERO_POSITION_RUN_LOWER_2 2
  1. define HERO_POSITION_JUMP_1 3
  2. define HERO_POSITION_JUMP_2 4
  3. define HERO_POSITION_JUMP_3 5
  4. define HERO_POSITION_JUMP_4 6
  5. define HERO_POSITION_JUMP_5 7
  6. define HERO_POSITION_JUMP_6 8
  7. define HERO_POSITION_JUMP_7 9
  8. define HERO_POSITION_JUMP_8 10
  1. define HERO_POSITION_RUN_UPPER_1 11
  2. define HERO_POSITION_RUN_UPPER_2 12

LiquidCrystal lcd(11, 9, 6, 5, 4, 3); static char terrainUpper[TERRAIN_WIDTH + 1]; static char terrainLower[TERRAIN_WIDTH + 1]; static bool buttonPushed = false;

void initializeGraphics(){

 static byte graphics[] = {
   //position perso
   B01100,
   B01100,
   B00000,
   B01100,
   B01100,
   B01100,
   B01100,
   B01110,
   // saut perso
   B01100,
   B01100,
   B00000,
   B11110,
   B01101,
   B11111,
   B10000,
   B00000,
   B11110,
   B01101,
   B11111,
   B10000,
   B00000,
   B00000,
   B00000,
   B00000,
   // obstacles
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,
   B11000,


 };
 int i;
 for (i = 0; i < 7; ++i) {

lcd.createChar(i + 1, &graphics[i * 8]);

 }
 for (i = 0; i < TERRAIN_WIDTH; ++i) {
   terrainUpper[i] = SPRITE_TERRAIN_EMPTY;
   terrainLower[i] = SPRITE_TERRAIN_EMPTY;
 }

}

// slide des obstacles void advanceTerrain(char* terrain, byte newTerrain){

 for (int i = 0; i < TERRAIN_WIDTH; ++i) {
   char current = terrain[i];
   char next = (i == TERRAIN_WIDTH-1) ? newTerrain : terrain[i+1];
   switch (current){
     case SPRITE_TERRAIN_EMPTY:
       terrain[i] = (next == SPRITE_TERRAIN_SOLID) ? SPRITE_TERRAIN_SOLID_RIGHT : SPRITE_TERRAIN_EMPTY;
       break;
     case SPRITE_TERRAIN_SOLID:
       terrain[i] = (next == SPRITE_TERRAIN_EMPTY) ? SPRITE_TERRAIN_SOLID_LEFT : SPRITE_TERRAIN_SOLID;
       break;
     case SPRITE_TERRAIN_SOLID_RIGHT:
       terrain[i] = SPRITE_TERRAIN_SOLID;
       break;
     case SPRITE_TERRAIN_SOLID_LEFT:
       terrain[i] = SPRITE_TERRAIN_EMPTY;
       break;
   }
 }

}

// condition perso bool drawHero(byte position, char* terrainUpper, char* terrainLower, unsigned int score) {

 bool collide = false;
 char upperSave = terrainUpper[HERO_HORIZONTAL_POSITION];
 char lowerSave = terrainLower[HERO_HORIZONTAL_POSITION];
 byte upper, lower;
 switch (position) {
   case HERO_POSITION_OFF:
     upper = lower = SPRITE_TERRAIN_EMPTY;
     break;
   case HERO_POSITION_RUN_LOWER_1:
     upper = SPRITE_TERRAIN_EMPTY;
     lower = SPRITE_RUN1;
     break;
   case HERO_POSITION_RUN_LOWER_2:
     upper = SPRITE_TERRAIN_EMPTY;
     lower = SPRITE_RUN2;
     break;
   case HERO_POSITION_JUMP_1:
   case HERO_POSITION_JUMP_8:
     upper = SPRITE_TERRAIN_EMPTY;
     lower = SPRITE_JUMP;
     break;
   case HERO_POSITION_JUMP_2:
   case HERO_POSITION_JUMP_7:
     upper = SPRITE_JUMP_UPPER;
     lower = SPRITE_JUMP_LOWER;
     break;
   case HERO_POSITION_JUMP_3:
   case HERO_POSITION_JUMP_4:
   case HERO_POSITION_JUMP_5:
   case HERO_POSITION_JUMP_6:
     upper = SPRITE_JUMP;
     lower = SPRITE_TERRAIN_EMPTY;
     break;
   case HERO_POSITION_RUN_UPPER_1:
     upper = SPRITE_RUN1;
     lower = SPRITE_TERRAIN_EMPTY;
     break;
   case HERO_POSITION_RUN_UPPER_2:
     upper = SPRITE_RUN2;
     lower = SPRITE_TERRAIN_EMPTY;
     break;
 }
 if (upper != ' ') {
   terrainUpper[HERO_HORIZONTAL_POSITION] = upper;
   collide = (upperSave == SPRITE_TERRAIN_EMPTY) ? false : true;
 }
 if (lower != ' ') {
   terrainLower[HERO_HORIZONTAL_POSITION] = lower;
   collide |= (lowerSave == SPRITE_TERRAIN_EMPTY) ? false : true;
 }
 
 byte digits = (score > 99999) ? 5 : (score > 999) ? 4 : (score > 99) ? 3 : (score > 9) ? 2 : 1;  // disatnce parcourue
 
 // Draw the scene
 terrainUpper[TERRAIN_WIDTH] = '\0';
 terrainLower[TERRAIN_WIDTH] = '\0';
 char temp = terrainUpper[16-digits];
 terrainUpper[16-digits] = '\0';
 lcd.setCursor(0.5,0); //action vers le haut
 lcd.print(terrainUpper);
 terrainUpper[16-digits] = temp;  
 lcd.setCursor(0,1);  // position héro
 lcd.print(terrainLower);
 
 lcd.setCursor(16- digits,0); //position du compeur
 lcd.print(score);
 terrainUpper[HERO_HORIZONTAL_POSITION] = upperSave;
 terrainLower[HERO_HORIZONTAL_POSITION] = lowerSave;
 return collide;

}

void buttonPush() {

 buttonPushed = true;

}

void setup(){

 pinMode(PIN_READWRITE, OUTPUT);
 digitalWrite(PIN_READWRITE, LOW);
 pinMode(PIN_CONTRAST, OUTPUT);
 digitalWrite(PIN_CONTRAST, LOW);
 pinMode(PIN_BUTTON, INPUT);
 digitalWrite(PIN_BUTTON, HIGH);
 pinMode(PIN_AUTOPLAY, OUTPUT);
 digitalWrite(PIN_AUTOPLAY, HIGH);
 
 attachInterrupt(0, buttonPush, FALLING);
 
 initializeGraphics();
 
 lcd.begin(16, 2);

}

void loop(){

 static byte heroPos = HERO_POSITION_RUN_LOWER_1;
 static byte newTerrainType = TERRAIN_EMPTY;
 static byte newTerrainDuration = 1;
 static bool playing = false;
 static bool blink = false;
 static unsigned int distance = 0;
 
 if (!playing) {
   drawHero((blink) ? HERO_POSITION_OFF : heroPos, terrainUpper, terrainLower, distance >> 3);
   if (blink) {
     lcd.setCursor(1,0);
     lcd.print("Press bouton");
   }
   delay(10);
   blink = !blink;
   if (buttonPushed) {
     initializeGraphics();
     heroPos = HERO_POSITION_RUN_LOWER_1;
     playing = true;
     buttonPushed = false;
     distance = 0;
   }
   return;
 }
 advanceTerrain(terrainLower, newTerrainType == TERRAIN_LOWER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY);
 advanceTerrain(terrainUpper, newTerrainType == TERRAIN_UPPER_BLOCK ? SPRITE_TERRAIN_SOLID : SPRITE_TERRAIN_EMPTY);
 
 if (--newTerrainDuration == 0) {
   if (newTerrainType == TERRAIN_EMPTY) {
     newTerrainType = (random(2) == 0) ? TERRAIN_UPPER_BLOCK : TERRAIN_LOWER_BLOCK; // haut et bas 
     newTerrainDuration = 2 + random(2);// nombre de obstacle
   } else {
     newTerrainType = TERRAIN_EMPTY;
     newTerrainDuration = 2 + random(100); // distance entre les obstacles
   }
 }
   
 if (buttonPushed) {
   if (heroPos <= HERO_POSITION_RUN_LOWER_2) heroPos = HERO_POSITION_JUMP_1;
   buttonPushed = false;
 }  
 if (drawHero(heroPos, terrainUpper, terrainLower, distance >> 3)) {
   playing = false;  //collision
 } else {
   if (heroPos == HERO_POSITION_RUN_LOWER_2 || heroPos == HERO_POSITION_JUMP_8) {
     heroPos = HERO_POSITION_RUN_LOWER_1;
   } else if ((heroPos >= HERO_POSITION_JUMP_3 && heroPos <= HERO_POSITION_JUMP_5) && terrainLower[HERO_HORIZONTAL_POSITION] != SPRITE_TERRAIN_EMPTY) {
     heroPos = HERO_POSITION_RUN_UPPER_1;
   } else if (heroPos >= HERO_POSITION_RUN_UPPER_1 && terrainLower[HERO_HORIZONTAL_POSITION] == SPRITE_TERRAIN_EMPTY) {
     heroPos = HERO_POSITION_JUMP_5;
   } else if (heroPos == HERO_POSITION_RUN_UPPER_2) {
     heroPos = HERO_POSITION_RUN_UPPER_1;
   } else {
     ++heroPos;
   }
   ++distance;
   
   digitalWrite(PIN_AUTOPLAY, terrainLower[HERO_HORIZONTAL_POSITION + 1] == SPRITE_TERRAIN_EMPTY ? HIGH : LOW);
 }
 delay(20);

}

Références

https://123d.circuits.io/circuits/1023084-arduino-lcd-game?#breadboard