Système Technique Simple - BA3:Annie Warenghien
Contents
Titre : Addiction
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
Arduino
https://123d.circuits.io/circuits/1023084-arduino-lcd-game?#breadboard
#include <LiquidCrystal.h>
- define PIN_BUTTON 2
- define PIN_AUTOPLAY 1
- define PIN_READWRITE 10
- define PIN_CONTRAST 12
- define SPRITE_RUN1 1
- define SPRITE_RUN2 2
- define SPRITE_JUMP 3
- define SPRITE_JUMP_UPPER '.'
- define SPRITE_JUMP_LOWER 4
- define SPRITE_TERRAIN_EMPTY ' '
- define SPRITE_TERRAIN_SOLID 5
- define SPRITE_TERRAIN_SOLID_RIGHT 6
- define SPRITE_TERRAIN_SOLID_LEFT 7
- define HERO_HORIZONTAL_POSITION 1
- define TERRAIN_WIDTH 16
- define TERRAIN_EMPTY 0
- define TERRAIN_LOWER_BLOCK 1
- define TERRAIN_UPPER_BLOCK 2
- define HERO_POSITION_OFF 0
- define HERO_POSITION_RUN_LOWER_1 1
- define HERO_POSITION_RUN_LOWER_2 2
- define HERO_POSITION_JUMP_1 3
- define HERO_POSITION_JUMP_2 4
- define HERO_POSITION_JUMP_3 5
- define HERO_POSITION_JUMP_4 6
- define HERO_POSITION_JUMP_5 7
- define HERO_POSITION_JUMP_6 8
- define HERO_POSITION_JUMP_7 9
- define HERO_POSITION_JUMP_8 10
- define HERO_POSITION_RUN_UPPER_1 11
- 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