O jogo mais simples do Arduino com uma tela 1602 - Parte # 1


É isso que temos que conseguir, bem, ele ainda sabe pular, andar e derrotar os cactos malignos que o atacam, mas chegaremos a este passo a passo :)

PARTE # 1 noções básicas


Encomendei para mim um arduino, “tão-tão-tão-brinquedo”, pensei, um pequeno kit (para teste), do qual mais tarde me arrependi. Eu queria liberar o potencial, mas, devido à falta de módulos adicionais, isso não funcionou, tive que experimentar, colocar o arduino no sistema de segurança e observar como os sensores funcionavam, depois decidi fazer um alarme de áudio (usando o prático squeaker do kit), então desmamei os cães em voz alta ou latindo repentinamente :) e então minhas mãos alcançaram a tela 1602. "Hmm ... esta é uma tela real", pensei, mas fiquei desapontado ao descobrir que ele come quase metade de todos os contatos do próprio arduino. Eu vasculhei e encontrei uma placa estranha no kit “i2C” e suspeitava disso! Que o número de furos coincidiu com o número de cafetões no visor. "Hmm, não é fácil ..." pensei, e decidi soldá-los. Um pouco depois, percebi que havia feito a coisa certa e agora minha tela consome apenas dois canais. Ele começou a estudar que tipo de exibição era e o que ele poderia fazer. Tendo estudado material suficiente, descobri que a tela é puramente textual, mas eis que eis que! Ele pode lidar com 8 novos caracteres com dimensões de 5x8 pixels. Bem, então, vamos começar a escrever um jogo! Primeiro, você precisa descobrir que tipo de jogo será, decidi fazer com que parecesse um dinossauro gugl chrome, mas com algumas fichas, por assim dizer, para iniciantes, acho que funcionará :) mas você ainda precisa gerenciar algo, e os botões múltiplos não precisaram pensar muito. Tirei o controle remoto por infravermelho do kit.

imagem

“Esse é o joystick”, murmurei desconfiado, pensando no atraso do controle remoto, na clareza do sensor de infravermelho e na adequação dessa ideia, mas não havia nada a fazer, eu poderia treinar o arduino para trabalhar com o teclado do computador, mas era realmente preguiça para fazer isso. Então comecei a escrever os códigos do controle remoto, para poder trabalhar com eles no futuro. O código para o microcontrolador é o mais simples aqui:

"--------------------------------------------------------------------------" //   IRremote #include <IRremote.h> decode_results results; IRrecv irrecv (A0); //      void setup () { Serial.begin(9600); //   com  irrecv.enableIRIn(); //    } void loop () { if (irrecv.decode( &results )) //      ,    { Serial.println( results.value, HEX ); //          irrecv.resume(); //            } } "--------------------------------------------------------------------------" 

O código do sinal do controle remoto fica assim: “FF18E7” seus códigos serão diferentes, é claro, mas você deve entender a essência e, quando você apelar para esse código, adicionamos “0x” no início e obtemos (0xFF18E7).

Depois de preencher isso no arduino e conectá-lo como deveria, podemos começar a gravar a partir da porta de log do tsiforka, depois de clicar nos botões do dispositivo de infravermelho. Mas aqui só quero esclarecer como conectar o sensor de infravermelho.

Se olharmos para o sensor, vemos três pernas, esquerda (sinal analógico), meio (terra), direita (mais 5V).

imagem

Como ainda tinha pouca ideia de como isso funcionaria, comecei os experimentos. No começo, fiz o código do esboço passo a passo, através de (delay (time)) no começo, não suspeitava que fosse uma má ideia :)
Qual é o batente principal. Este microcontrolador não pode executar multitarefa. Ele considera o código de cima para baixo, passando por todas as ramificações e funções e, após a conclusão, ele inicia novamente. E agora, quando temos muitos desses "atrasos" no código, começamos a perceber atrasos óbvios. A propósito, sim, por que precisamos de muito "atraso"? Quando fazemos um jogo, o número de testes e interações começa a crescer. Por exemplo, um inimigo se move em nossa direção e eu quero pular sobre ele, pressiono o “pulo” e, de acordo com o plano, tenho que ficar no ar por exemplo 0,8f segundos no ar, e este é o jogo inteiro e congela por 0,8f segundos. "Não posso", pensei e comecei a pensar em uma solução. A solução foi encontrada rapidamente. O microcontrolador em si é capaz de ler rapidamente o código do início ao fim (se não o incomoda) e também sabe contar o tempo desde o início de sua inclusão. É disso que precisamos. Agora, apenas criamos variáveis ​​que armazenam o tempo para essa ou aquela ação e uma variável que compara a diferença de que horas são agora e quanto é necessário para ativar o código. O Arduino por segundo, leva 1000 milissegundos, bastante conveniente. Aqui está um trecho quando fica mais claro:

 "--------------------------------------------------------------------------" //    ,  ,        //  long ClearTime = 150; // 150 = 0.15f   ~6    long ClearTimeCheck = 0; // ,       long currentMillis = 0; //   void loop () { currentMillis = millis(); //   =    } void clearscreen () //   { // if (currentMillis - ClearTimeCheck >= ClearTime) //  (  -     0.15f    { ClearTimeCheck = currentMillis; //       lcd.clear(); //   ,     } } "--------------------------------------------------------------------------" 

Não é difícil, certo?

Depois de reescrever todo o código de uma nova maneira, o jogo começou a funcionar rápida e claramente, para simular ações de multitarefa :) Eu percorri um longo caminho. Afinal, ainda precisamos criar um personagem, um tipo de interface e animação. Como podemos criar apenas oito novos personagens, precisamos de alguma forma estragar tudo de maneira inteligente. Não pretendo fazer muitos objetos na tela até agora; portanto, isso pode ser feito para que eu tenha apenas oito objetos ativos na tela em um processamento de código. O que vai ser? Bem, naturalmente o personagem principal, um golpe, um vilão, um coração e um indicador de saúde. Para iniciantes, isso é suficiente. Sim, e eu tenho mais três objetos únicos em estoque.

O personagem principal ficará assim:



O processo de inserir um novo caractere, que eu produzo em código binário (me sinto tão à vontade)
ficará assim:

01110
01110
00100
01110
10101
00100
01110
01010

Se você olhar atentamente, então, a partir de um, veremos nosso personagem, mas, para que ele não fique ocioso, vamos fazer uma animação para ele.



Agora ao nosso código, mais um conjunto de números binários é adicionado, a saber este:

00000
01110
01110
00100
11111
00100
01110
01010

Como fazer uma animação nessa tela, indiquei a lógica acima e agora vamos praticar, no momento, colocá-la no centro da tela e deixá-la parada, e lembre-se, nossa tarefa é usar apenas uma célula de memória para dois sprites de animação. Isso é mais fácil do que parece:

 "--------------------------------------------------------------------------" #include <Wire.h> #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3F,16,2); //   long AnimatedTime = 300; //     long AnimatedTimeCheck = 0; //   (    ) int AnimPlayer = 1; //    int GGpozX = 8; //   int GGpozY = 1; //   1  2   0    long currentMillis = 0; //   //   ,     ,    :) enum { SYMBOL_HEIGHT = 8 }; byte Player_1[SYMBOL_HEIGHT] = {B01110,B01110,B00100,B01110,B10101,B00100,B01110,B01010,}; //  1 byte Player_2[SYMBOL_HEIGHT] = {B00000,B01110,B01110,B00100,B11111,B00100,B01110,B01010,}; //  2 void setup() { lcd.init(); lcd.backlight();//    loop(); PlAn(); } void loop() { if (AnimPlayer != 50) { //    ,       :) // --------------------------- Animated -> // -------------------- Player -> if (AnimPlayer == 1){lcd.createChar(0, Player_1);} //  1   1 //(lcd.createChar(    0  7,   )) if (AnimPlayer == 2){lcd.createChar(0, Player_2);} //  2   2 } // --------------------------- <- Animated currentMillis = millis(); //   =    PlAn(); } void PlAn () { if (AnimPlayer == 1) //   1  { lcd.setCursor(GGpozX, GGpozY); //  ""      lcd.write(0); //          "" } if (AnimPlayer == 2) //  №1 { lcd.setCursor(GGpozX, GGpozY); lcd.write(0); } if (currentMillis - AnimatedTimeCheck >= AnimatedTime) //       { AnimatedTimeCheck = currentMillis; //     if (AnimPlayer == 2){AnimPlayer = 1; return;} //  2   1      if (AnimPlayer == 1){AnimPlayer = 2;} // 1  2           ,         } } "--------------------------------------------------------------------------" 

Depois de começar, vemos o homenzinho, que está no centro da tela, na 2ª linha e balança, por assim dizer.

Conclusão: hoje falei sobre como descobrir dados através da porta infravermelha, como ignorar o atraso do código do microcontrolador e como fazer a animação inicial.

O resto está chegando :) ainda tenho muito o que escrever, então verei como será interessante para você e, nesse caso, amanhã começarei a escrever uma sequência.

Obrigado a todos pela atenção, ciao cacau!

A segunda parte do artigo -> habr.com/post/425367

Source: https://habr.com/ru/post/pt424859/


All Articles