Genius comentado
Tempos atrás eu fiz um Genius (game dos anos 80, vc pode conferir o bicho funcionando aqui embaixo):
Fazer games tem os seus desafios: tem que levar em conta a ergonomia, quer dizer, montar o circuito de maneira que o jogador consiga ter acesso aos comandos. Depois, o programa tem que ser rápido e consistente, de maneira a fazer o jogador ter uma experiência adequada. Acho que ficou legal.
Vc pode ver no vídeo o "meu" Genius funcionando:
Abaixo, como prometido, o código comentado:
A ideia é repetir uma sequência de sons e cores criadas aleatoriamente pelo jogo. Como ele tem muitas coisas interessantes em termos de software, vou fazer um post mais detalhado aqui
Esse é o circuito montado. Usei um tweeter velho desses de carro para fazer o som, ficou legal, bem alto. Um LED de cada cor, um botão correspondente a cada cor e som.
Aqui mais de perto:
E o esquema no Fritzing:
Fazer games tem os seus desafios: tem que levar em conta a ergonomia, quer dizer, montar o circuito de maneira que o jogador consiga ter acesso aos comandos. Depois, o programa tem que ser rápido e consistente, de maneira a fazer o jogador ter uma experiência adequada. Acho que ficou legal.
Vc pode ver no vídeo o "meu" Genius funcionando:
Abaixo, como prometido, o código comentado:
// biblioteca que define as frequências das notas musicais #include <Piches.h> // pino onde está conectado o buzzer (ou auto-falante) #define buzzer 3 // o programa foi feito como uma máquina de estados, estes são os estados possíveis #define waitingStart 0 // esperando o jogo começar #define playingSeq 1 // tocando a sequencia pro usuário repetir #define userTyping 3 // lendo a sequencia que o cara tá teclando #define validatingSeq 4 // validando // pinos onde estáo ligadas as teclas. Devem ser em sequencia, a menor o vermelho. #define kred 11 #define kyellow 10 #define kgreen 9 #define kwhite 8 //pinos onde estão ligados os LEDs. Devem ser em sequencia, o menor o vermelho. #define lred 7 #define lyellow 6 #define lgreen 5 #define lwhite 4 // define modo debug (=1) #define debugging 0 // duração da nota int interval = 500; // intervalo entre as notas int noSound = 200; // guarda a sequência atual int seq[50]; // indexador da sequência tocada int posSeq = 0; // indexador da sequência digitada int posType = 0; // estado corrente int state = waitingStart; // tecla pressionada int key = 0; void setup() { // seta modo dos pinos pinMode(lred, OUTPUT); pinMode(lyellow, OUTPUT); pinMode(lgreen, OUTPUT); pinMode(lwhite, OUTPUT); pinMode(kred, INPUT); pinMode(kyellow, INPUT); pinMode(kgreen, INPUT); pinMode(kwhite, INPUT); noSound = 0; // inicializa gerador de números aleatórios do Arduino: // eu uso o valor lido de uma porta analógica desconectada, // que tem sempre algum valor devido à alta impedância dessas // portas randomSeed(analogRead(0)); // faz uma "gracinha" demo(); noSound = 50; Serial.begin(9600); // cria a prmeira sequência generateSeq(); } void loop() { // máquina de estados: processa os diferentes estados do programa switch(state) { case waitingStart: // reseta o intervalo interval = 500; if (debugging) Serial.println("waitingStart"); // espera o usuário digitar algo key = readKey(false); // quando isso ocorre, muda o estado para o próximo state = playingSeq; return; case playingSeq: if (debugging) Serial.println("playingSeq"); // toca a sequência e seta o próximo estado playSeq(); posType = 0; state = userTyping; return; case userTyping: if (debugging) Serial.println("userTyping"); key = 1; int ok = true; // enquanto o usuário estiver digitando certo, fica nesse estado while(ok) { key = readKey(true); // se o usuário não digitou nada, dançou if (key == 0) break; // toca a nota digitada pelo usuário play(key-(lred-kred)); // valida a tecla digitada ok = validateSeq(key); if (debugging) { Serial.print("ok="); Serial.println(ok); } // se ok... if (ok) { // se o usuário terminou a sequência... if (posType == posSeq) { // dá um intervalo de um segundo... delay(1000); // aumenta o tamanho da próxima sequência posSeq++; // agora o intervalo é 5% menor interval = interval * 0.95; // volta o estado para playingSeq state = playingSeq; return; } else { // usuário ainda não terminou. posType++; } } } // se chegou aqui, o usuário teclou errado. playWrong(); Serial.print("Voce fez "); Serial.println(posSeq); // gera nova sequência generateSeq(); // volta o estado para o inicial state = waitingStart; return; } } int validateSeq(int key) { return (key-(lred-kred)) == seq[posType]; // (key-3) = key to LED } // espera e lê a tecla digitada pelo usuário. Se vallidateMilis = 1, // retorna 0 após 3 segundos int readKey(int validateMilis) { unsigned long ms = millis(); int value = LOW; while(value == LOW) { for (int i = kred; i >= kwhite; i--) { if (validateMilis) if ((millis() - ms) > 3000) { if (debugging) Serial.println("Timeout"); return 0; } value = digitalRead(i); if (value == HIGH) { return i; } } } } // toca uma determinada nota (pitch), com uma determinada duração (duration) void playPich(int pich, int duration) { tone(buzzer, pich); delay(duration); noTone(buzzer); } // toca a Imperial March (tema do Darth Vader no StarWars) void playWrong() { int ritym = 500; for(int i = 0; i < 2; i++) { digitalWrite(lred, HIGH); digitalWrite(lyellow, HIGH); digitalWrite(lgreen, HIGH); digitalWrite(lwhite, HIGH); playPich(NOTE_A3, ritym); playPich(NOTE_A3, ritym); playPich(NOTE_A3, ritym); playPich(NOTE_F3, ritym * 3 / 4); playPich(NOTE_C4, ritym * 1 / 4); playPich(NOTE_A3, ritym); playPich(NOTE_F3, ritym * 3 / 4); playPich(NOTE_C4, ritym * 1 / 4); playPich(NOTE_A3, ritym * 2); playPich(NOTE_E4, ritym); playPich(NOTE_E4, ritym); playPich(NOTE_E4, ritym); playPich(NOTE_F4, ritym * 3 / 4); playPich(NOTE_C4, ritym * 1 / 4); playPich(NOTE_GS3, ritym); playPich(NOTE_F3, ritym * 3 / 4); playPich(NOTE_C4, ritym * 1 / 4); playPich(NOTE_A3, ritym * 2); digitalWrite(lred, LOW); digitalWrite(lyellow, LOW); digitalWrite(lgreen, LOW); digitalWrite(lwhite, LOW); noTone(buzzer); delay(500); } } // toca a demo void demo() { interval = 500; while(interval > 5) { play(lred); play(lyellow); play(lgreen); play(lwhite); interval = interval / 1.5; } } // toca uma nota, pisca o LED correspondente void blink(int led, int pich) { tone(buzzer,pich); digitalWrite(led, HIGH); delay(interval); digitalWrite(led, LOW); noTone(buzzer); delay(noSound); } // toca uma nota void play(int pich) { switch(pich) { case lred: blink(lred,NOTE_C4); break; case lyellow: blink(lyellow,NOTE_E4); break; case lgreen: blink(lgreen,NOTE_G4); break; case lwhite: blink(lwhite,NOTE_AS4); break; } } // gera a sequência de notas, aleatória void generateSeq() { posSeq = 0; if (debugging) Serial.println("generateSeq"); int note; for (int i = 0; i < 50; i++) { seq[i] = random(4) + 4; if (debugging) Serial.println(seq[i]); } } // toca a sequência void playSeq() { for (int i = 0; i <= posSeq; i++) { play(seq[i]); } }
Cara fiz a montagem como você mostrou mas os botões não estão funcionando
ResponderExcluir