galoebn
Published © GPL3+

"Hangman" game on E-ink

In this project I show you how to make a Hangman game for an E-ink display.

IntermediateFull instructions provided333
"Hangman" game on E-ink

Things used in this project

Hardware components

ESP32
Espressif ESP32
You can use any ESP32 board
×1
2.9inch E-Ink display module
×1

Story

Read more

Schematics

Schematics

Unfortunately I can't create a Fritzing file because the parts are not available there. Just connect all the wires so that the colors match. You also have to look at the pinout of your specific ESP32 board.

Code

e-ink_hangman

Arduino
#define ENABLE_GxEPD2_GFX 0

#include <GxEPD2_BW.h> // including both doesn't use more code or ram
#include <GxEPD2_3C.h> // including both doesn't use more code or ram
#include <U8g2_for_Adafruit_GFX.h>

GxEPD2_BW<GxEPD2_290_T94_V2, GxEPD2_290_T94_V2::HEIGHT> display(GxEPD2_290_T94_V2(/*CS=5*/ SS, /*DC=*/ 17, /*RST=*/ 16, /*BUSY=*/ 4)); // GDEM029T94, Waveshare 2.9" V2 variant
U8G2_FOR_ADAFRUIT_GFX u8g2Fonts;

uint16_t bg = GxEPD_WHITE;
uint16_t fg = GxEPD_BLACK;
const char abc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char words[] = "HOUSE,CAR,PLANE,WATER,INFORMATION,UNDERSTANDING,KNOWLEDGE,TEMPERATURE,AREA,SOCIETY,ACTIVITY,STORY,INDUSTRY,MEDIA,OVEN,COMMUNITY,DEFINITION,BIVOUAC,CATARACT,CONCOURSE,RUMOUR,FINDING,LAKE,MESSAGE,PHONE,SCENE,DEATH,DISCUSSION,BLOOD,OPINION,CITY,HEART,PHOTO,COLLECTION,IMAGINATION,PASSION,CRITICISM,SOLUTION,ALCOHOL,POSSESSION,DEVICE,ENGINE,ELEVATOR,GUITAR,HOMEWORK,LEADER,TENNIS,CHURCH,COFFE,HAIR,ORANGE,RESTAURANT,SONG,TOWN,ERROR,MEAL,RIVER,CHOCOLATE,COOKIE,GARBAGE,PIANO,POTATO,SALAD,APPLE,BEER,DIAMOND,MIDNIGHT,STRANGER,TIME,WORK,FILM,MONEY,GAME,LIFE,NUMBER,EXPERIENCE,SCHOOL,PRACTICE,RESEARCH,ANSWER,PICTURE,GARDEN,FUTURE,RECORD,NOTHING,WEATHER,CHICKEN,QUESTION,SUN,SPEED,ADVANTAGE,DISCIPLIN,CHALLENGE,SUMMER,VEGETABLE,BREAKFAST,STORM,TELEPHONE,WINTER,HOLIDAY,VACATION,LANDSCAPE,BAR,CHAIR,JACKET,MONITOR,SURPRISE,WEEKEND,ALARM,BICYCLE,CONCERT,SHIP,ENGINEER,";
int abc_pointer = 0;
char word1[] = "h";
int length_word1 = 0;
int number_guessed = 0;
int hangman_progress = 0;
int wrong_x = 150;

bool touch1detected = false;
bool touch2detected = false;

void gotTouch2(){
 touch2detected = true;
}
void gotTouch1(){
 touch1detected = true;
}


void(* resetFunc) (void) = 0;


void new_word(){
  strcpy(word1, "");
  int x = random(1, 114);
  int count = 0;
  int j = 0;
  for(; x > 0; x--){
    count = 0;
    while(words[j] != words[5]){
      ++count;
      ++j;
    }
    ++j;
  }
  for(int i = j-count-1 ; i < j-1; i++){
    strncat(word1, &words[i], 1);
  }
  length_word1 = count;
  return;
}


void draw_hangman(){
  display.setPartialWindow(185, 18, 200, 200);
  display.firstPage();
  bool lost = false;
  do{
    switch(hangman_progress){
      case 11:
        display.drawRect(258, 75, 5, 24, fg);
        lost = true;
      case 10:
        display.drawRect(251, 75, 5, 24, fg);
      case 9:
        display.fillRect(257, 54, 23, 5, fg);
      case 8:
        display.fillRect(234, 54, 23, 5, fg);
      case 7:
        display.fillRoundRect(250, 53, 14, 25, 3, fg);
      case 6:
        display.drawCircle(257, 48, 5, fg);
      case 5:
        display.drawLine(257, 23, 257, 43, fg);
      case 4:
        display.drawLine(217, 45, 247, 23, fg);
      case 3:
        display.fillRect(217, 20, 45, 6, fg);
      case 2:
        display.fillRect(217, 20, 6, 80, fg);
      case 1:
        display.fillTriangle(185, 120, 285, 120, 220, 95, fg);
        break;
      default:
        break;
    }
  }while(display.nextPage());

  if(lost){
    display.setPartialWindow(0, 35, 150, 35);
    display.firstPage();
    do{
      display.fillScreen(GxEPD_WHITE);
      u8g2Fonts.setCursor(10, 70); 
      u8g2Fonts.print("You lost!");
    }
    while(display.nextPage());
    delay(3000);
    resetFunc();
  }

}


void setup()
{
  touchAttachInterrupt(T3, gotTouch2, 70);
  touchAttachInterrupt(T4, gotTouch1, 70);

  randomSeed(analogRead(0));
  Serial.begin(115200);
  
  display.init();
  display.setTextColor(GxEPD_BLACK);
  display.setRotation(1);
  
  u8g2Fonts.setFont(u8g2_font_logisoso16_tr);

  u8g2Fonts.setForegroundColor(fg);         // apply Adafruit GFX color
  u8g2Fonts.setBackgroundColor(bg);

  u8g2Fonts.begin(display); // connect u8g2 procedures to Adafruit GFX
  delay(1000);

  display.firstPage();
  do
  {
    display.fillScreen(GxEPD_WHITE);
    u8g2Fonts.setCursor(10, 30); 
    u8g2Fonts.println("A");
    //u8g2Fonts.setCursor(10, 110);
    new_word();
    //u8g2Fonts.println(word1);

    for(int i = length_word1-1; i >= 0; i--){
      display.fillRect(11+i*12, 112, 8, 3, fg);
    }
      
  }
  while (display.nextPage());
}


void loop(){
  
  touch2detected = false;
  touch1detected = false;
  while(!touch2detected && !touch1detected){delay(10);}
  if(touch1detected){
    abc_pointer += 1;
    if(abc_pointer > 25){abc_pointer = 0;}
    
    display.setPartialWindow(0, 0, 50, 50);
    display.firstPage();
  
    do{
      display.fillScreen(GxEPD_WHITE);
      u8g2Fonts.setCursor(10, 30); 
      u8g2Fonts.println(abc[abc_pointer]);
    }
    while(display.nextPage());
  }

  else if(touch2detected){
    char character = abc[abc_pointer];
    bool character_found = false;
    for(int i = 0; i < length_word1; i++){
      if(word1[i] == character){
        character_found = true;
        display.setPartialWindow(11+i*12, 80, 10, 30);
        display.firstPage();
        do{
          display.fillScreen(GxEPD_WHITE);
          u8g2Fonts.setCursor(11+i*12, 110); 
          u8g2Fonts.println(abc[abc_pointer]);
        }
        while(display.nextPage());
        
        ++number_guessed;
        if(number_guessed == length_word1){
          display.setPartialWindow(0, 35, 150, 35);
          display.firstPage();
          do{
            display.fillScreen(GxEPD_WHITE);
            u8g2Fonts.setCursor(10, 70); 
            u8g2Fonts.print("You won!");
          }
          while(display.nextPage());
          delay(3000);
          resetFunc();
        }
        
      }
  }

  if(!character_found){
    ++hangman_progress;
    draw_hangman();
    display.setPartialWindow(wrong_x, 0, 200, 14);
    display.firstPage();
    do{
      u8g2Fonts.setFont(u8g2_font_7x14_tr);
      u8g2Fonts.setCursor(wrong_x, 13); 
      u8g2Fonts.print(abc[abc_pointer]);
      u8g2Fonts.setFont(u8g2_font_logisoso16_tr);
      wrong_x += 13;
    }while(display.nextPage());
  }
  
  delay(100);
  }

}

Credits

galoebn
9 projects • 5 followers
Contact

Comments

Please log in or sign up to comment.