Jogos retro arduino com um display oled

Já se perguntou o quanto trabalho é preciso para escrever seus próprios jogos retro? Como é fácil Pong para codificar para o Arduino? Junte-me como eu mostrar-lhe como construir um mini-consola de jogos retro Arduino alimentado, e como codificar Pong do zero. Aqui está o resultado final:

Plano de construir

Este é um circuito bastante simples. UMA potenciômetro (Vaso) vai controlar o jogo, e um OLED irá ser impulsionada pelo Arduino. Este será produzido em uma placa de ensaio, no entanto, você pode querer fazer deste um circuito permanente e instalá-lo em um caso. Nós escrevemos sobre recriando Pong antes, no entanto hoje eu vou mostrar-lhe como escrever o código a partir do zero, e quebrar todas as partes.Como recriar o jogo Pong clássico Usando ArduinoComo recriar o jogo Pong clássico Usando ArduinoPong foi o primeiro videogame que nunca que atingiu o mercado de massa. Pela primeira vez na história, o conceito de um "videogame" foi trazido para a casa da família, graças à Atari 2600 -...consulte Mais informação

Video: Jogo com Arduino e Display Nokia LCD

O que você precisa

Setup Retro Arduino

Aqui está o que você precisa:

  • 1 x Arduino (qualquer modelo)
  • 1 x 10k potenciômetro
  • 1 x 0,96 "I2C Display OLED
  • 1 x Tábua
  • masculino Assorted gt; Fios de montagem do sexo masculino
Diymall 0,96" Inch I2c IIC Serial 128x64 Oled LCD LED Módulo Branco exibição para Arduino 51 Msp420 Stim32 SCRDiymall 0,96" Inch I2c IIC Serial 128x64 Oled LCD LED Módulo Branco exibição para Arduino 51 Msp420 Stim32 SCRlink do documento: https://drive.google.com/open?id=0B8DSGdAr8_31UEItMmx6ZDJIOWs Compre Agora No Amazon $ 9,99

Qualquer Arduino deve funcionar, então vá para a guia de compra se você não tem certeza de qual modelo comprar.

Estes displays OLED são muito cool. Eles podem normalmente ser adquiridos em branco, azul, amarelo, ou uma mistura dos três. Eles existem em cores, porém estes adicionar um outro nível totalmente à complexidade e custo deste projeto.

O circuito

Este é um circuito bastante simples. Se você não tem muita experiência com o Arduino, confira essas projetos iniciantes primeiro.10 grandes projetos Arduino para Iniciantes10 grandes projetos Arduino para IniciantesCompletando um projeto Arduino lhe dá uma sensação de satisfação como nenhum outro. A maioria dos iniciantes não tem certeza por onde começar, porém, e projetos, mesmo para iniciantes pode parecer um pouco assustador.consulte Mais informação

Aqui está:

pong Breadboard

Olhando para a frente do pote, conectar o pino da esquerda para +5V e o pino direito de chão. Ligue o pino do meio para 0 pino analógico (A0).

O OLED está ligado utilizando o protocolo I2C. Conectar VCC e GND ao Arduino +5V e chão. Conectar SCL para analógico cinco (A5). Conectar SDA para 4 analógico (A4). A razão pela qual este está ligado aos pinos analógicos é simples- estes pinos conter os circuitos necessários para o protocolo I2C. Certifique-se de que estes estão conectados corretamente, e não atravessou. Os pinos exatas irá variar dependendo do modelo, mas A4 e A5 são usados ​​no Nano e Uno. Verifique a documentação biblioteca Wire para o seu modelo se você não está usando um Arduino ou Nano.

pot Test

Enviar este código de teste (certifique-se de selecionar a bordo e porta correta do Ferramentas gt; Borda e Ferramentas gt; Porta menus):

vazio configuração() {// colocar o seu código de configuração aqui, para executar uma vez:Serial.início(9600)- // série configuração}vazio laço() {// coloque o código principal aqui, para executar repetidamente:Serial.println(analogRead(A0))- // imprimir o valor do potedemora(500)-}

Agora, abra o monitor serial (Canto superior direito gt; Serial monitor) E virar o pote. Você deve ver o valor exibido no monitor serial. Totalmente anti-horário deve ser zero, e totalmente no sentido horário deve ser 1023:

monitor serial Pong

Você vai ajustar isso mais tarde, mas por agora está tudo bem. Se nada acontecer, ou as alterações de valor sem ter que fazer nada, desligue e verifique o circuito.

Teste OLED

Gráficos OLED

O display OLED é um pouco mais complexo para configurar. Você precisa instalar duas bibliotecas para conduzir a exibição primeiro. Faça o download das bibliotecas Adafruit_SSD1306 e Adafruit-GFX do Github. Copiar os arquivos para a pasta de bibliotecas. Isso varia dependendo do seu sistema operacional:

  • Mac OS: / Users / usuário / Documentos / Arduino / bibliotecas
  • Linux: / Home / usuário / Sketchbook
  • Janelas: / Users / Arduino / bibliotecas

Agora carregar um esboço de teste. Vamos para Arquivo gt; Exemplos gt; Adafruit SSD1306 gt; ssd1306_128x64_i2c. Isso deve lhe dar um grande esboço contendo muitos gráficos:

Gráficos OLED

Se nada acontecer após o carregamento, desligue e verifique suas conexões. Se os exemplos não estão nos menus, pode ser necessário reiniciar o Arduino IDE.

O código

Agora é hora para o código. Eu estarei explicando cada passo, para pular para o final, se você quiser apenas para obtê-lo correr. Esta é uma boa quantidade de código, por isso, se você não se sentir confiante, veja estes 10 recursos livres, e estes 5 grandes recursos aprender a código.Learn To Código: 10 Grátis e fantásticos recursos online para aprimorar suas habilidadesLearn To Código: 10 Grátis e fantásticos recursos online para aprimorar suas habilidadesCodificação. Um tema que é evitado por muitos. Há uma abundância de recursos e ferramentas livres, todos os quais estão disponíveis online. Claro que você pode fazer alguns cursos sobre o tema em uma próxima ...consulte Mais informação

Video: Пример работы с OLED LCD Display Module I2C 0.96 в среде Arduino

Comece incluindo as bibliotecas necessárias:

#incluir #incluir #incluir #incluir 

SPI e FIO são duas bibliotecas do Arduino para lidar com a comunicação I2C. Adafruit_GFX e Adafruit_SSD1306 são as bibliotecas instaladas anteriormente.

Em seguida, configurar o display:

Adafruit_SSD1306 exibição(4)-

Em seguida, configurar todas as variáveis ​​necessárias para executar o jogo:

int resolução[2] = {128, 64}, bola[2] = {20, (resolução[1] / 2)}-const int PIXEL_SIZE = 8, WALL_WIDTH = 4, PADDLE_WIDTH = 4, BALL_SIZE = 4, RAPIDEZ = 3-int playerScore = 0, aiScore = 0, playerPos = 0, aiPos = 0-Caracteres ballDirectionHori = `R`, ballDirectionVerti = `S`-boolean InProgress = verdade-

Estes armazenar todos os dados necessários para executar o jogo. Alguns destes armazenar a localização da bola, o tamanho da tela, a localização do jogador e assim por diante. Observe como algumas delas são const o que significa que são constantes, e nunca vai mudar. Isso permite que o Arduino pouco as coisas velocidade compilador para cima.

A resolução da tela e localização bola são armazenados em matrizes. Arrays são coleções de coisas semelhantes, e para a bola, armazenar as coordenadas (X e Y). Acessando elementos em matrizes é fácil (não inclua este código em seu arquivo):

resolução[1]-


Como matrizes começam a zero, este vai retornar do segundo elemento na matriz resolução (64). Atualizando elementos é ainda mais fácil (mais uma vez, não inclua este código):

Video: 1-Day Project: Arduino Uno and I2C OLED Display Challenge

bola[1] = 15-

Dentro void setup (), configurar o display:

vazio configuração() {exibição.início(SSD1306_SWITCHCAPVCC, 0x3C)-exibição.exibição()-}

A primeira linha diz a biblioteca Adafruit que dimensões e comunicações do protocolo seu monitor está usando (neste caso, 128 X 64 e I2C). A segunda linha (display.display ()) Conta a tela para mostrar o que está armazenado no buffer (que é nada).

Criar dois métodos chamados drawBall e eraseBall:

vazio drawBall(int X, int y) {exibição.drawCircle(X, y, BALL_SIZE, BRANCO)-}vazio eraseBall(int X, int y) {exibição.drawCircle(X, y, BALL_SIZE, PRETO)-}

Estes assumem a X e y coordena da bola e desenhá-lo na tela usando o drawCircle método a partir das bibliotecas de exibição. Este usa a constante BALL_SIZE definido anteriormente. Tente mudar isso e ver o que acontece. Este método drawCircle aceita uma cor do pixel - PRETO ou BRANCO. Como esta é uma tela monocromática (uma cor), branco equivale a um pixel sendo, e preto transforma o pixel off.

Agora crie um método chamado moveAi:

vazio moveAi() {eraseAiPaddle(aiPos)-E se (bola[1] gt; aiPos) {++aiPos-}outro E se (bola[1] lt; aiPos) {--aiPos-}drawAiPaddle(aiPos)-}

Este método lida com mover o Inteligência artificial ou AI jogador. Este é completamente um oponente de computador simples - Se a bola está acima da pá, mover para cima. Ele é abaixo da pá, mover para baixo. Muito simples, mas funciona bem. Os símbolos de incremento e decremento são utilizados (++aiPos e -aiPos) Para adicionar ou subtrair um do aiPosition. Você pode adicionar ou subtrair um número maior de fazer a AI se mover mais rápido e, portanto, ser mais difícil de bater. Veja como você faria isso:

aiPos += 2-

E:

aiPos -= 2-

o além Equals e é igual a menos sinais são abreviada para adicionar ou subtrair dois de / para o valor corrente de aiPos. Aqui está outra maneira de fazer isso:

aiPos = aiPos + 2-

e

aiPos = aiPos - 1-

Observe como esse método apaga primeiro a raquete, e depois chama-lo novamente. Isto tem que ser feito assim. Se a nova posição da raquete foi elaborado, haveria duas pás sobrepostas na tela.

o drawNet método utiliza dois circuitos para extrair o líquido:

vazio drawNet() {para (int Eu = 0- Eu lt; (resolução[1] / WALL_WIDTH)- ++Eu) {drawPixel(((resolução[0] / 2) - 1), Eu * (WALL_WIDTH) + (WALL_WIDTH * Eu), WALL_WIDTH)-}}

Este utiliza o WALL_WIDTH variáveis ​​para definir o seu tamanho.

Criar métodos chamados drawPixels e erasePixels. Assim como os métodos de bola, a única diferença entre estes dois é a cor dos pixels:

vazio drawPixel(int posX, int posY, int dimensões) {para (int X = 0- X lt; dimensões- ++X) {para (int y = 0- y lt; dimensões- ++y) {exibição.drawPixel((posX + X), (posY + y), BRANCO)-}}}vazio erasePixel(int posX, int posY, int dimensões) {para (int X = 0- X lt; dimensões- ++X) {para (int y = 0- y lt; dimensões- ++y) {exibição.drawPixel((posX + X), (posY + y), PRETO)-}}}

Mais uma vez, ambos estes métodos usam dois para loops para desenhar um grupo de pixels. Em vez de ter que chamar cada pixel usando as bibliotecas drawPixel método, os loops de desenhar um grupo de pixels com base nas dimensões indicadas.

o drawScore método usa os recursos de texto da biblioteca para escrever o jogador e pontuação AI para a tela. Estes são armazenados em playerScore e aiScore:

vazio drawScore() {exibição.setTextSize(2)-exibição.SetTextColor(BRANCO)-exibição.setCursor(45, 0)-exibição.println(playerScore)-exibição.setCursor(75, 0)-exibição.println(aiScore)-}

Este método também tem um eraseScore contraparte, que define os pixels de preto ou off.

Os quatro métodos finais são muito semelhantes. Eles desenhar e apagar o aparelho e pás AI:

vazio erasePlayerPaddle(int linha) {erasePixel(0, linha - (PADDLE_WIDTH * 2), PADDLE_WIDTH)-erasePixel(0, linha - PADDLE_WIDTH, PADDLE_WIDTH)-erasePixel(0, linha, PADDLE_WIDTH)-erasePixel(0, linha + PADDLE_WIDTH, PADDLE_WIDTH)-erasePixel(0, linha + (PADDLE_WIDTH + 2), PADDLE_WIDTH)-}

Observe como eles chamam o erasePixel método de criação anterior. Estes métodos de desenhar e apagar a pá adequado.

Há um pouco mais lógica no circuito principal. Aqui está todo o código:

#incluir #incluir #incluir #incluir Adafruit_SSD1306 exibição(4)-int resolução[2] = {128, 64}, bola[2] = {20, (resolução[1] / 2)}-const int PIXEL_SIZE = 8, WALL_WIDTH = 4, PADDLE_WIDTH = 4, BALL_SIZE = 4, RAPIDEZ = 3-int playerScore = 0, aiScore = 0, playerPos = 0, aiPos = 0-Caracteres ballDirectionHori = `R`, ballDirectionVerti = `S`-boolean InProgress = verdade-vazio configuração() {exibição.início(SSD1306_SWITCHCAPVCC, 0x3C)-exibição.exibição()-}vazio laço() {E se (aiScore gt; 9 || playerScore gt; 9) {// verifica estado do jogoem progresso = falso-}E se (em progresso) {eraseScore()-eraseBall(bola[0], bola[1])-E se (ballDirectionVerti == `VOCÊ`) {// move bola para cima na diagonalbola[1] = bola[1] - RAPIDEZ-}E se (ballDirectionVerti == `D`) {// move bola para baixo na diagonalbola[1] = bola[1] + RAPIDEZ-}E se (bola[1] lt; = 0) { // devolver a bola fora do topo ballDirectionVerti = `D`-} se (bola [1] gt; = resolução [1]) {// devolver a bola fora da parte inferiorballDirectionVerti = `VOCÊ`-}E se (ballDirectionHori == `R`) {bola[0] = bola[0] + RAPIDEZ- // bola movimentoE se (bola[0] gt; = (resolução[0] - 6)) {// bola está na borda AI da telaE se ((aiPos + 12) gt; = bola[1] && (aiPos - 12) lt; = bola[1]) { // bola bate AI pá if ​​(bola [1] gt; (AiPos + 4)) {// desviar a bola para baixoballDirectionVerti = `D`-}outro E se (bola[1] lt; (aiPos - 4)) {// desviar a bola para cimaballDirectionVerti = `VOCÊ`-}outro {// desviar a bola em linha retaballDirectionVerti = `S`-}// direção da bola mudançaballDirectionHori = `EU`-}outro {// GOAL!bola[0] = 6- // move bola para o outro lado da telaballDirectionVerti = `S`- // redefinir bola para deslocamento em linha retabola[1] = resolução[1] / 2- // move bola para o meio da tela++playerScore- // pontuação jogador aumento}}}E se (ballDirectionHori == `EU`) {bola[0] = bola[0] - RAPIDEZ- // bola movimentoE se (bola[0] lt; = 6) { // bola está na borda jogador da tela if ((playerPos + 12) gt; = bola [1] && (12) - playerPos lt; = bola [1]) {// bola atinge jogador pá se (bola [1] gt; (PlayerPos + 4)) {// desviar a bola para baixoballDirectionVerti = `D`-}outro E se (bola[1] lt; (playerPos - 4)) { // desviar a bola para cima ballDirectionVerti = `U`-} else {// desviar a bola em linha reta ballDirectionVerti =` S`-} // mudar de direção bola ballDirectionHori = `R`-} else {bola [0] = resolução [0] - 6- // mover a bola para o outro lado da tela ballDirectionVerti = `S`- // repor bola a bola movimento rectilíneo [1] = resolução [1] / 2- // mover a bola para o meio da tela ++ // aiScore- aumentar AI pontuação}}} drawBall (bola [0], bola [1]) - erasePlayerPaddle (playerPos) - playerPos = analogRead (A2) - // li playerPos jogador potenciómetro = mapa (playerPos, 0, 1023, 8, 54) - // valor convertido 0-1023 8 - 54 drawPlayerPaddle (playerPos) - moveAi () - drawNet () - drawScore () -} else {// alguém ganhou display.clearDisplay () - display.setTextSize (4) - display.setTextColor (BRANCO) - display.setCursor (0, 0) - // descobrir quem se (aiScore gt; playerScore) {exibição.println("VOCÊ PERDEU!")-}outro E se (playerScore gt; aiScore) {exibição.println("VOCÊ GANHA!")-}}exibição.exibição()-}vazio moveAi() {// move o remo AIeraseAiPaddle(aiPos)-E se (bola[1] gt; aiPos) {++aiPos-}outro E se (bola[1] lt; aiPos) {--aiPos-}drawAiPaddle(aiPos)-}vazio drawScore() {// desenha pontuação AI e jogadorexibição.setTextSize(2)-exibição.SetTextColor(BRANCO)-exibição.setCursor(45, 0)-exibição.println(playerScore)-exibição.setCursor(75, 0)-exibição.println(aiScore)-}vazio eraseScore() {// apagar pontuações AI e jogadorexibição.setTextSize(2)-exibição.SetTextColor(PRETO)-exibição.setCursor(45, 0)-exibição.println(playerScore)-exibição.setCursor(75, 0)-exibição.println(aiScore)-}vazio drawNet() {para (int Eu = 0- Eu lt; (resolução[1] / WALL_WIDTH)- ++Eu) {drawPixel(((resolução[0] / 2) - 1), Eu * (WALL_WIDTH) + (WALL_WIDTH * Eu), WALL_WIDTH)-}}vazio drawPixel(int posX, int posY, int dimensões) {// desenha grupo de pixelspara (int X = 0- X lt; dimensões- ++X) {para (int y = 0- y lt; dimensões- ++y) {exibição.drawPixel((posX + X), (posY + y), BRANCO)-}}}vazio erasePixel(int posX, int posY, int dimensões) {// grupo de apagamento de pixelspara (int X = 0- X lt; dimensões- ++X) {para (int y = 0- y lt; dimensões- ++y) {exibição.drawPixel((posX + X), (posY + y), PRETO

Artigos relacionados