#include #include #include #include LiquidCrystal_I2C lcd(0x27,16,2); byte afk_dino1[8] = {B00000, B00000, B00010, B00010, B00011, B00011, B00001, B00001}; byte afk_dino2[8] = {B00111, B00111, B00111, B00100, B11100, B11100, B11000, B01000}; byte left_leg1[8] = {B00000, B00000, B00010, B00010, B00011, B00011, B00001, B00000}; byte left_leg2[8] = {B00111, B00111, B00111, B00100, B11100, B11100, B11000, B01000}; byte right_leg1[8] = {B00000, B00000, B00010, B00010, B00011, B00011, B00001, B00001}; byte right_leg2[8] = {B00111, B00111, B00111, B00100, B11100, B11100, B11000, B00000}; byte cactus1[8] = {B00000, B00100, B00100, B10100, B10100, B11100, B00100, B00100}; byte cactus2[8] = {B00100, B00100, B10100, B10101, B11101, B00111, B00100, B00100}; byte bird1[8] = {B00001, B00001, B00001, B00001, B01001, B11111, B00000, B00000}; byte bird2[8] = {B00000, B10000, B11000, B11100, B11110, B11111, B00000, B00000}; int button = 11; int buzzer = 10; int dino_column1 = 1; int dino_column2 = 2; int dino_row = 1; int dino_x = 1; int obstacle_row = 0; int obstacle_column = 13; float period = 100; int jump_period = 800; int trigger1 = 1; int trigger2 = 2; int bird_place = 13; int btn_signal = 0; int btn_signal_old = 0; float acceleration = 0.9; int points = 0; int points2 = 0; int RNG = 0; unsigned long clock1 = 0; unsigned long clock2 = 0; int flag = 1; int started=0; int lost=0; volatile int timer_counter = 0; void start_screen() { if(lost==1) { lcd.clear(); lost=0; } lcd.setCursor(3, 0); lcd.print("START"); lcd.setCursor(3, 1); lcd.print("DINO JUMP"); lcd.setCursor(14, dino_row); lcd.write(byte(0)); lcd.setCursor(15, dino_row); lcd.write(byte(1)); if(digitalRead(button)==HIGH) { started=1; lcd.clear(); } } void run() { if (timer_counter<1) { if (flag == 1) { flag = 2; } else if (flag == 2) { flag = 1; } timer_counter=0; } } void cleaner() { int aux; if (millis() > clock1 + period) { clock1 = millis(); obstacle_column = obstacle_column - 1; aux = obstacle_column + 1; lcd.setCursor(aux, 1); //clean downside lcd.print(" "); lcd.setCursor(aux, 0); //clean upside lcd.print(" "); lcd.setCursor(0, 1); //clean behind dinosaur lcd.print(" "); lcd.setCursor(0, 0); lcd.print(" "); if (btn_signal != btn_signal_old) { lcd.setCursor(1, 0); lcd.print(" "); } btn_signal_old = btn_signal; } } void dino_down() { if (dino_x == 0) { if (flag == 1) { lcd.setCursor(dino_column1, dino_row); lcd.write(byte(2)); lcd.setCursor(dino_column2, dino_row); lcd.write(byte(3)); } if (flag == 2) { lcd.setCursor(dino_column1, dino_row); lcd.write(byte(4)); lcd.setCursor(dino_column2, dino_row); lcd.write(byte(5)); } } } void obstacle_generator() { if (RNG == 1) //cactus 1 { obstacle_row = 1; lcd.createChar(6, cactus1); lcd.setCursor(obstacle_column, obstacle_row); lcd.write(byte(6)); } else if (RNG == 2) //cactus 2 { obstacle_row = 1; lcd.createChar(7, cactus2); lcd.setCursor(obstacle_column, obstacle_row); lcd.write(byte(7)); } else //bird { bird_place = obstacle_column; bird_place = bird_place - 1; obstacle_row = 0; lcd.createChar(6, bird1); lcd.setCursor(bird_place, obstacle_row); lcd.write(byte(6)); lcd.createChar(7, bird2); lcd.setCursor(obstacle_column, obstacle_row); lcd.write(byte(7)); } } void collider() { if (digitalRead(button) == HIGH && ( bird_place == 1 || bird_place == 2) && obstacle_row == 0 ) //colision with bird { int note[] = {200, 150}; for (int i = 0; i < 2; i++) { tone(buzzer, note[i], 250); delay(200); } lcd.clear(); lcd.setCursor(3, 0); lcd.print("GAME OVER"); lcd.setCursor(1, 1); lcd.print("death by bird"); delay(2000); lcd.clear(); obstacle_column = 15; period = 100; points = 0; points2 = 0; started=0; lost=1; } if ((obstacle_column == trigger1 || obstacle_column == trigger2) && obstacle_row == 1) //colision with cactus { int note[] = {200, 150}; for (int i = 0; i < 2; i++) { tone(buzzer, note[i], 250); delay(200); } lcd.clear(); lcd.setCursor(3, 0); lcd.print("GAME OVER"); lcd.setCursor(0, 1); lcd.print("death by cactus"); delay(2000); lcd.clear(); points2=0; obstacle_column = 15; period = 100; points = 0; points = 0; period = 100; started=0; lost=1; } } void accelerate() { if (obstacle_column < 0) { obstacle_column = 13; period = period - acceleration; //acceleration of the game RNG = random(0, 3); //decides which obstacle generates next } } void jump() { if (digitalRead(button) == HIGH) { trigger1 = 20; //b,c bigger than LCD columns trigger2 = 20; if (dino_x == 0) { lcd.setCursor(0, 1); // Clean dino from down lcd.print(" "); } dino_x = 1; lcd.setCursor(dino_column1, 0); lcd.write(byte(2)); lcd.setCursor(dino_column2, 0); lcd.write(byte(3)); jump_sound(); } else { trigger1 = 1; //reset values trigger2 = 2; dino_x = 0; } } void jump_sound() { if (millis() > clock2 + jump_period) { clock2 = millis(); tone(buzzer, 450, 200); } } void points_tracker() { if (timer_counter>=1) //points>100 get converted to 1,2,3 etc. { lcd.setCursor(14, 1); lcd.print(points); points = points + 1; if (points == 100) { int note[] = {300, 1050}; // "Level up" sound for (int i = 0; i < 2; i++) { tone(buzzer, note[i], 150); delay(150); points = 0; if (points2 == 100) { points2 = 0; } } points2 = points2 + 1; } lcd.setCursor(14, 1); lcd.print(points); lcd.setCursor(15, 0); lcd.print(points2); btn_signal = digitalRead(button); //state change detector timer_counter=0; } } void game() { run(); dino_down(); obstacle_generator(); collider(); cleaner(); accelerate(); jump(); points_tracker(); } ISR(TIMER1_COMPA_vect) { timer_counter++; } void setup() { for (int i = 2; i <= 17; i++) pinMode(i, OUTPUT); pinMode(button, INPUT_PULLUP); pinMode(buzzer, OUTPUT); lcd.init(); lcd.backlight(); lcd.createChar(0, afk_dino1); lcd.createChar(1, afk_dino2); lcd.createChar(2, right_leg1); lcd.createChar(3, right_leg2); lcd.createChar(4, left_leg1); lcd.createChar(5, left_leg2); lcd.createChar(6, cactus1); lcd.createChar(7, cactus2); cli(); // disable interrupts TCCR1A = 0; TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); OCR1A = 1562; // compare match value for 1 second @ 16MHz with 1024 prescaler // enable timer1 compare interrupt TIMSK1 |= (1 << OCIE1A); sei(); // enable interrupts } void loop() { if(started==0) start_screen(); else game(); }