segunda-feira, 18 de julho de 2011

Projeto: Fazendo o jogo do Pong com o arduino


O jogo do Pong é o primeiro videogame com fins lucrativos. O jogo é composto de duas "raquetes" (uma para cada jogador) e o objetivo é rebater a bola, evitando o ponto do seu oponente.


A imagem acima dá uma idéia melhor de como o jogo funciona. A idéia deste projeto é utilizar dois potenciômetros ao arduino e enviar a posição angular do potenciômetro para o computador através da comunicação serial. Utilizando o processing, vamos ler a porta serial e utilizar os dados recebidos para definir a posição das raquetes. A montagem do circuito é trivial.
O código do arduino é igualmente simples. Vamos ler os valores das portas analógicas e passá-los através da comunicação serial, no seguinte formato: os dois valores dos potenciômetros separados por ";".


void setup(){
Serial.begin(9600);
}
void loop(){
Serial.print(analogRead(A0));
Serial.print(";");
Serial.println(analogRead(A2));
}

Simples assim, sem nenhum mistério. Agora só precisamos fazer o código do processing para receber e interpretar as informações. Não irei colocar muitos comentários sobre o código, se alguém tiver alguma dúvida, pode postar nos comentários que eu respondo.


// Importa a biblioteca de comunicação serial
import processing.serial.*;

Serial myPort; // Cria um objeto
float raio = 20; //Raio da bola
int X, Y; //Posição X e Y da bola
float vx=2, vy=2; // Componentes X e Y da velocidade da bola
float vx0=vx, vy0=vy; // Velocidades iniciais
int p1=0; //Pontuação do jogador 1 e 2
int p2=0;
int x1=15; // Posição X das duas "raquetes"
int x2=785;
float y1=0; // Posição Y das duas "raquetes"
float y2=0;
int tam=100; // tamanho da raquete
String[] vector;

void setup(){
size( 800, 400 ); //tamanho da janela
myPort = new Serial(this, Serial.list()[0], 9600); // Inicia a comunicação com a porta serial 0
PFont f = createFont("SansSerif", 40, true); //Define a fonte utilizada no placar
textFont(f,40);
strokeWeight( 1 ); // Largura das linhas
frameRate( 44 ); // Velocidade dos quadros
X = width / 2;
Y = (height-100) / 2;
myPort.bufferUntil('\n'); //Só inicia quando houver a primeira comunicação serial.
}


void draw(){
background( 255 ); //Define a cor de fundo
////////////////////////////////////////////////////
// Pega as informações recebidas pela porta
// serial e atribui as posições X e Y das raquetes
////////////////////////////////////////////////////
if(myPort.available()>1){
String inString= myPort.readString(); // Lê tudo que foi obtido pela porta serial
String[] teste =split(inString,"\n"); // Divide em linhas
String[] vector = split(teste[teste.length-2],";"); // pega a penúltima e separa num vetor
y1 = float(vector[0]);
y2 = float(vector[1]);
y1 = map(y1, 0, 1023, 0, height-tam-100); // renormaliza pelo tamanho útil da janela.
y2 = map(y2, 0, 1023, 0, height-tam-100);
}

fill( 0, 121, 184 );
ellipse( X, Y, raio, raio );
fill(255,0,0);
rect(x1,y1,-10,tam);
fill(0,0,255);
rect(x2,y2,10,tam);
X+=vx;
Y+=vy;
////////////////////////////////////
// Colisão com as raquetes
////////////////////////////////////
if(X < x1+raio/2 && (Y > y1 && Y < y1+tam)){
X-=vx;
vx*=-1.1;
}
if(X > x2-raio/2 && (Y > y2 && Y < y2+tam)){
X-=vx;
vx*=-1.1;
}
////////////////////////////////
//Fronteiras horizontais
////////////////////////////////
if(X > x2-raio/2 || X < x1-raio/2){
if(X > x2-raio/2){
p1++;
}
if(X < x1-raio/2){
p2++;
}
X = width / 2;
Y = (height-100) / 2;
vx0=-1*vx0;
vx=vx0;
vy=vy0;
fill( 0, 121, 184 );
ellipse( X, Y, raio, raio );
vx=vx0;
vy=vy0;
delay(2000);
}
/////////////////////////////////////////
// Fronteiras verticais
////////////////////////////////////////
if(Y > height-100-raio/2 || Y < raio/2){
Y-=vy;
vy*=-1;
}
/////////////////////////////////////////
// Placar
/////////////////////////////////////////
fill(0);
line(0,height-100,width,height-100);
text("Placar:",10,height-10);
fill(255,0,0);
text(p1, 350, height-10);
fill(0);
text("X",400,height-10);
fill(0,0,255);
text(p2, 450, height-10);
}


13 comentários:

  1. Pergunta... como carrego os 2 codigos pra dentro do arduino...

    carreguei o primeiro ... tudo certo ....

    ao carregar o segundo, da erros assim

    sketch_jul21b.cpp:6: erro: ‘import’ does not name a type
    sketch_jul21b.cpp:10: erro: ‘Serial’ does not name a type
    sketch_jul21b.cpp:34: erro: expected unqualified-id before ‘[’ token
    sketch_jul21b.cpp: In function ‘void setup()’:
    sketch_jul21b.cpp:40: erro: ‘size’ was not declared in this scope
    sketch_jul21b.cpp:42: erro: ‘myPort’ was not declared in this scope
    sketch_jul21b.cpp:42: erro: expected type-specifier before ‘Serial’
    sketch_jul21b.cpp:42: erro: expected `;' before ‘Serial’
    sketch_jul21b.cpp:44: erro: ‘PFont’ was not declared in this scope
    sketch_jul21b.cpp:44: erro: expected `;' before ‘f’
    sketch_jul21b.cpp:46: erro: ‘f’ was not declared in this scope
    sketch_jul21b.cpp:46: erro: ‘textFont’ was not declared in this scope
    sketch_jul21b.cpp:48: erro: ‘strokeWeight’ was not declared in this scope
    sketch_jul21b.cpp:50: erro: ‘frameRate’ was not declared in this scope
    sketch_jul21b.cpp:52: erro: ‘width’ was not declared in this scope
    sketch_jul21b.cpp:54: erro: ‘height’ was not declared in this scope
    sketch_jul21b.cpp: In function ‘void draw()’:
    sketch_jul21b.cpp:66: erro: ‘background’ was not declared in this scope
    sketch_jul21b.cpp:76: erro: ‘myPort’ was not declared in this scope
    sketch_jul21b.cpp:80: erro: expected unqualified-id before ‘[’ token
    sketch_jul21b.cpp:82: erro: expected unqualified-id before ‘[’ token
    sketch_jul21b.cpp:84: erro: ‘vector’ was not declared in this scope
    sketch_jul21b.cpp:88: erro: ‘height’ was not declared in this scope
    sketch_jul21b.cpp:96: erro: ‘fill’ was not declared in this scope
    sketch_jul21b.cpp:98: erro: ‘ellipse’ was not declared in this scope
    sketch_jul21b.cpp:102: erro: ‘rect’ was not declared in this scope
    sketch_jul21b.cpp:118: erro: ‘Xy1’ was not declared in this scope
    sketch_jul21b.cpp:118: erro: expected `)' before ‘X’
    sketch_jul21b.cpp: At global scope:
    sketch_jul21b.cpp:124: erro: expected unqualified-id before ‘if’
    sketch_jul21b.cpp:126: erro: expected constructor, destructor, or type conversion before ‘*=’ token
    sketch_jul21b.cpp:128: erro: expected declaration before ‘}’ token

    ResponderExcluir
    Respostas
    1. Não cara, o primeiro código você carrega no arduino e o outro voccê carrega no processing

      Excluir
  2. Virmal,
    O segundo codigo deve rodar pelo computador usando um programa chamado Processing (www.Processing.org). Por isso você teve todos esses erros. Se tiver qualquer problema, posta pra gente que resolvemos.

    ResponderExcluir
  3. expecting RPAREN, found 'X'
    processing.app.SketchException: Syntax error, maybe a missing right parenthesis?
    at processing.mode.java.JavaBuild.preprocess(JavaBuild.java:314)
    at processing.mode.java.JavaBuild.preprocess(JavaBuild.java:197)
    at processing.mode.java.JavaBuild.build(JavaBuild.java:156)
    at processing.mode.java.JavaBuild.build(JavaBuild.java:135)
    at processing.mode.java.JavaMode.handleRun(JavaMode.java:176)
    at processing.mode.java.JavaEditor$20.run(JavaEditor.java:481)
    at java.lang.Thread.run(Thread.java:662)

    ResponderExcluir
  4. Tem algum erro neste fonte, eu acho....

    pois rodei outros exemplos que vem junto com o processing e nao deu erro nenhum com eles rodou redondinho....

    o que ser[a ????

    Obrigado !!!

    ResponderExcluir
  5. Virmal,
    Realmente havia um problema. O html estava dando conflito com o código e sumindo com alguns sinais de > e < . Agora ele deve rodar direitinho. Pode testar.

    ResponderExcluir
  6. muito bom ....

    Agora deu certinho, ficou bem interessante, agora podiamos tentar jogar essa imagem para uma saida RCA.

    ResponderExcluir
  7. Este comentário foi removido pelo autor.

    ResponderExcluir
  8. Consegui compilar porem as barras que deveriam se mover de acordo com os potenciometros nao se movem.

    ResponderExcluir
  9. Os erros encontrados foram:


    Exception in thread "Animation Thread" java.lang.ArrayIndexOutOfBoundsException: 2
    at sketch_aug02b.draw(sketch_aug02b.java:63)
    at processing.core.PApplet.handleDraw(Unknown Source)
    at processing.core.PApplet.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:662)

    ResponderExcluir
  10. deu tudo certo, tudo rodou, mas as barras não se mexem com os potenciômetros.

    ResponderExcluir
  11. boas so agora vi este projecto, apesar de ja ter uns anos, gostaria de o executar. pergunto, como faço para que corra num ecran VGA de um pc?
    Obrigado

    ResponderExcluir
  12. meu email é adenilsongarciadacruz@gmail.com

    estou utilizando esse programa de jogo para ensinar meus alunos na escola estadual de ensino médio integral no estado de são paulo.

    durante alguns minutos o programa funciona bem, mas após ele trava e segue a mensagem:


    map(NaN, 0, 1023, 0, 250) called, which returns NaN (not a number)
    Could not run the sketch (Target VM failed to initialize).
    For more information, read revisions.txt and Help ? Troubleshooting.


    como corrigir ou o que esta fazendo esse erro.

    aguardo resposta


    abraços


    adenilson

    ResponderExcluir