Fork me on GitHub

24/03/13

Snake Game com PIC16F877A

Snake Game com PIC16F877A




Joguinho clássico da cobra.

O objetivo e fazer a cobra engolir a comida. Quando mais ela engolir, maior será o seu tamanho e sua velocidade.

O projeto foi feito utilizando MCU PIC16F877A com clock de 16Mhz e um GLCD(128x64) com controlador KS0108.



DOWNLOAD:
Projeto Snake: snakeGame.zip;

CÓDIGO-FONTE:
MikroC PRO PIC
#include "snake_bmp.c"
#define uchar unsigned char
char GLCD_DataPort at PORTC;
sbit GLCD_CS1 at RB0_bit;
sbit GLCD_CS2 at RB1_bit;
sbit GLCD_RS  at RB2_bit;
sbit GLCD_RW  at RB3_bit;
sbit GLCD_EN  at RB4_bit;
sbit GLCD_RST at RB5_bit;
sbit GLCD_CS1_Direction at TRISB0_bit;
sbit GLCD_CS2_Direction at TRISB1_bit;
sbit GLCD_RS_Direction  at TRISB2_bit;
sbit GLCD_RW_Direction  at TRISB3_bit;
sbit GLCD_EN_Direction  at TRISB4_bit;
sbit GLCD_RST_Direction at TRISB5_bit;
uchar SNAKE[40][2];
uchar dir = 2;
uchar food[2], LENGTH_SNAKE = 5;
uchar posX, posY = 1;
uchar score, *score_txt = "Score: 00";
uchar i;
void criar_comida()
{
food[0] = rand()/264 + 1;
food[1] = rand()/700 + 1;
Glcd_Dot(food[0], food[1], 1);
}
void gameover()
{
    LENGTH_SNAKE = 5;
    PosX = 1;
    PosY = 1;
    score = 0;
    score_txt[8] = '0';
    dir = 2;
    Glcd_Fill(0xFF);
    Glcd_Write_Text("GAME OVER !!!",25,3,0);
    delay_ms(1000);
}
void main()
 {
 TRISD = 255;
 Glcd_Init();
 Glcd_Image(snake_img);
 delay_ms(4000);
 Inicio:
 Glcd_Fill(0x00);
 criar_comida();
 for(i=0;i < 5;i++)
 {
  Glcd_Dot(i,0,1);
 }
 Glcd_Rectangle(0,0,127,50, 1);
 Glcd_Write_Text(score_txt,0,7,1);
 while(1)
{
  if(PORTD.F0==1)  dir = 3;
  if(PORTD.F1==1)  dir = 2;
  if(PORTD.F2==1)  dir = 1;
  if(PORTD.F3==1)  dir = 0;
  if(PORTD.F4==1)
  {
   gameover();
   goto Inicio;
  }
  //para baixo
  if(dir==2){
   PosX++;
   if(PosX > 126){ gameOver(); goto Inicio; }
   SNAKE[LENGTH_SNAKE - 1][0] = PosX;
   SNAKE[LENGTH_SNAKE - 1][1] = PosY;
   for(i=0; i < length_snake - 1; i++)
     {
     SNAKE[i][0] = SNAKE[i+1][0];
     SNAKE[i][1] = SNAKE[i+1][1];
     }
  }
  
  //para direita
  if(dir==3){
   PosY++;
   if(PosY > 49){ gameOver(); goto Inicio; }
   SNAKE[LENGTH_SNAKE - 1][1] = PosY;
   SNAKE[LENGTH_SNAKE - 1][0] = PosX;
   for(i=0; i < length_snake - 1; i++)
     {
     SNAKE[i][1] = SNAKE[i+1][1];
     SNAKE[i][0] = SNAKE[i+1][0];
     }
  }
  
  //para cima
  if(dir==1){
   PosY--;
   if(PosY < 1){ gameOver(); goto Inicio; }
   SNAKE[LENGTH_SNAKE - 1][1] = PosY;
   SNAKE[LENGTH_SNAKE - 1][0] = PosX;
   for(i=0; i < LENGTH_SNAKE - 1; i++)
     {
     SNAKE[i][1] = SNAKE[i+1][1];
     SNAKE[i][0] = SNAKE[i+1][0];
   }
  }
  
  //para esquerda
  if(dir==0){
   PosX--;
   if(PosX < 1){ gameOver(); goto Inicio; }
   SNAKE[LENGTH_SNAKE - 1][1] = PosY;
   SNAKE[LENGTH_SNAKE - 1][0] = PosX;
   for(i=0; i < LENGTH_SNAKE - 1; i++)
   {
     SNAKE[i][1] = SNAKE[i+1][1];
     SNAKE[i][0] = SNAKE[i+1][0];
   }
  }
  
  //desenha a cobra
  for(i=0;i < LENGTH_SNAKE;i++)
  {
   Glcd_Dot(SNAKE[i][0], SNAKE[i][1], 1);
  }
  
  Glcd_Dot(SNAKE[0][0], SNAKE[0][1], 0);//limpa o rastro deixado pela cobra
  //caso encontrar a comida
  if(PosX==food[0] && PosY==food[1])
   {
   LENGTH_SNAKE++;
   if(LENGTH_SNAKE >= 38){//caso voce chegue ao nivel maximo
    LENGTH_SNAKE=5;
    PosX = 1;
    PosY = 1;
    score = 0;
    dir = 2;
    Glcd_Fill(0xFF);
    Glcd_Write_Text("VOCE GANHOU !!!",25,3,0);
    delay_ms(2000);
    goto Inicio;
   }
   criar_comida();
   score++;
   score_txt[7] = score/10 + 48;
   score_txt[8] = score%10 + 48;
   Glcd_Write_Text(score_txt, 0,7,1);
   }
   
  for(i = 0; i < 450/LENGTH_SNAKE; i++)
  {
   delay_ms(1);
  }
 }
}



VIDEO

36 comentários:

  1. tem como fazer com arduino??parabens obrigado lucas-fernandes84@hotma
    il.com valew féra

    ResponderExcluir
    Respostas
    1. Esquece o ruimduino (ou melhor arduino)meu amigo, com ele você nunca será um verdadeiro desenvolvedor de sistemas microcontrolados, se quiser estude o microcontrolador ATMEL que é a base do Arduino...abraços!!!!!

      Excluir
  2. Baixei mas não funcionou, acho que tem algum erro na programação do Pic.
    Sera que pode ver pra mim? Obrg

    ResponderExcluir
    Respostas
    1. Deu uma olhada. compilei o projeto novamente. baixa e testa pra ver.
      Outra coisa tbm, nos testes q fiz, não funcionou no proteus 7.8
      Funcionou perfeitamente no proteus 7.10, visto no video acima, e no proteus 8.

      Excluir
  3. Valeu, você são demais, rodou 100% no Proteus 7.8 SP0

    ResponderExcluir
  4. hola al compilar con el MikroC PRO PIC me manda este error Demo Limit . por favor ayuda

    ResponderExcluir
    Respostas
    1. muchas gracias por tu respuesta. pero ya realice todos los pasos para el crack del programa pero aun así no lo puedo compilar ya que me muestra el mensaje de Demo Limit.

      Excluir
    2. Coloquei um novo crack, testa pra ver se funciona!

      Excluir
  5. hola no habla espanol bien pero in english:how to make this game with the arduino board? thanks

    ResponderExcluir
    Respostas
    1. Arduino sucks do all kind of protest against this shit called arduino ... we'll be true developers you are filling the pockets of such personnel that makes plaque with Atmel and Arduino sells this crap called WE STUDY THE MICROCONTROLLER ...

      TRADUZINDO: arduino é uma merda faço todo tipo de manifestação contra esta merda chamada arduino...gente vamos ser verdadeiros desenvolvedores vocês estão enchendo o bolso desse pessoal que faz plaquinha com o Atmel e vende essa porcaria chamada arduino VAMOS ESTUDAR O MICROCONTROLADOR...

      Excluir
  6. pq não quer compilar? tá dando erro qdo jogo no mikroC ou no Devmic pra compilar ¬¬ me ajuda! por favor

    ResponderExcluir
  7. o MPLAB n tá convertendo pra .HEX ... oq eu faço?

    ResponderExcluir
  8. have you already done this in actual ?we are trying to do it on actual but we dont know if the lcd or the program has the prblem. please help us. thanks!

    ResponderExcluir
  9. Olá,

    Achei seu blog pouco tempo e já sou fã, kkkk, muito bom seu trabalho, nota 10, ajuda muito quem está querendo entrar nesse mundo.

    Uma dúvida cara, aquele arquivo "snake_bmp.c" era uma imagem .bmp convertida por algum software? como que foi feita?

    Valeu cara....

    ResponderExcluir
    Respostas
    1. Esqueci de comentar que o vídeo está fora do ar....

      Excluir
    2. É que eu exclui a conta do Google+, aí o youtube bloqueia os videos...
      Para converte a imagem, eu utilizei a ferramenta GLCD Bitmap Editor do próprio MikroC.

      Abraços!!!

      Excluir
    3. Valeu Cara, você é fera, respondeu em 4 minutos, mas rápido que eu apertar o refresh do navegador.
      Sem problemas quanto ao vídeo, já rodei no Proteus sem problema. também já achei o GLCD Bitmap Editor.
      Parabéns pela dedicação....

      Abraços.

      Excluir
  10. Se não for pedir muito, sou iniciante na área e possuo uma placa de desenvolvimento PICExpert Avançado com um display KS0108B ligados no portB e D de um PIC18f4550 (PIC padrão que veio na placa), e gostaria de compilar esse programa para o PIC18F4550 e gravar com o Micro C (Até o momento só consegui realizar gravações com o MPLab), você poderia me ajudar a realizar essa compilação e gravação?nunca gravei com o micro c e estou um pouco perdido...

    ResponderExcluir
    Respostas
    1. Na verdade o correto é:

      char GLCD_DataPort at PORTB; //D0 a DB7
      sbit GLCD_CS1 at RD0_bit;
      sbit GLCD_CS2 at RD1_bit;
      sbit GLCD_RS at RD2_bit;
      sbit GLCD_RW at RD3_bit;
      sbit GLCD_EN at RD4_bit;
      sbit GLCD_RST at RD5_bit;
      sbit GLCD_CS1_Direction at TRISD0_bit;
      sbit GLCD_CS2_Direction at TRISD1_bit;
      sbit GLCD_RS_Direction at TRISD2_bit;
      sbit GLCD_RW_Direction at TRISD3_bit;
      sbit GLCD_EN_Direction at TRISD4_bit;
      sbit GLCD_RST_Direction at TRISD5_bit;

      Aparece a foto inicial, conta um tempo mas depois ele fica oscilando entre game over e o inicio

      mas está tudo descentralizado...

      Excluir
    2. Esse são os botoes para os comandos, tem que altera-los, veja se na placa eles sao como Pull-up ou pull-down

      if(PORTD.F0==1) dir = 3;
      if(PORTD.F1==1) dir = 2;
      if(PORTD.F2==1) dir = 1;
      if(PORTD.F3==1) dir = 0;
      if(PORTD.F4==1)
      {
      gameover();
      goto Inicio;
      }

      Excluir
    3. Já mudei isso para

      {
      if(PORTA.F0==1) dir = 3;
      if(PORTA.F1==1) dir = 2;
      if(PORTA.F2==1) dir = 1;
      if(PORTA.F3==1) dir = 0;
      if(PORTA.F4==1)
      {
      gameover();
      goto Inicio;

      Só possui 4 botões minha placa, mas posso usar o A0 somente para teste (é um jump na placa).

      Excluir
    4. Obs:Oscilador de 20Mhz já alterei nas opções de projeto (PLL Prescaler selection: divede by 5(20Mhz oscillator input)

      e tabém em Oscillator fequency [MHz]: 20

      Excluir
    5. Voce não deve mexer noPLL Prescaler selection: . Isto é usado somente para comunicação USB. Deixe como No prescaler (4Mhz oscillator...)

      Excluir
    6. Voltei para 4Mhz.

      mas quando inicia a foto parece que está deslocada pela metade...

      e o game over também está...... e sempre fica aparecendo game over (pisca durante 1 segundo e volta a aparecer game over).

      Excluir
    7. se eu segurar o botão ligado no A4 aparece a minhoca indo para a direita, se eu solto aparece game oer (mas tudo deslocado metade do LCD).

      Excluir
    8. Quando o botao A4 recebe nivel logico 1, ele reseta o game...
      inverta os pinos CS1 e CS2 no código, para deslocar a imagem.

      sbit GLCD_CS1 at RD1_bit;
      sbit GLCD_CS2 at RD0_bit;

      Excluir
    9. Inverti conforme vc falou e continuou errado o GLCD.
      Ele mostra a metade da direita na esquerda e a metade da esquerda na direita...

      se ajudar segue o link do esquema da minha placa.

      http://smartradio.com.br/website/pag/dowloads/picexpert/PICEXP2%20Esquema%20(placas%20Rev2).pdf

      Excluir
    10. Consegui fazer o LCD mostrar correto

      mudei conforme você falou (acho que errei na hora de pegar o hexa da primeira vez, desculpa, kkk)

      char GLCD_DataPort at PORTB;
      sbit GLCD_CS1 at RD1_bit; // Mudei
      sbit GLCD_CS2 at RD0_bit; // Mudei
      sbit GLCD_RS at RD2_bit;
      sbit GLCD_RW at RD3_bit;
      sbit GLCD_EN at RD4_bit;
      sbit GLCD_RST at RD5_bit;
      sbit GLCD_CS1_Direction at TRISD1_bit; // Mudei
      sbit GLCD_CS2_Direction at TRISD0_bit; // Mudei
      sbit GLCD_RS_Direction at TRISD2_bit;
      sbit GLCD_RW_Direction at TRISD3_bit;
      sbit GLCD_EN_Direction at TRISD4_bit;
      sbit GLCD_RST_Direction at TRISD5_bit;

      Excluir
    11. Tirei o botão resetv(A4) do programa e ele está respondendo e ligando correto, só falta fazer os botões para cima, baixo e lados funcionarem.

      Percebi que o original recebe nível lógico 0 e quando pressionado muda para 1.

      Minha placa é o contrário (nível lógico 1 e quando pressiono vai para 0). Porém se mudar para:

      if(PORTA.F0==0) dir = 3;
      if(PORTA.F1==0) dir = 2;
      if(PORTA.F2==0) dir = 1;
      if(PORTA.F3==0) dir = 0;

      O Jogo fica dando game over de novo....

      Excluir
  11. Parabéns pelo projeto e por compartilhar seus trabalhos.
    Gostaria de saber se é possível modificar o tamanho da cobra ao começar o game?

    ResponderExcluir
    Respostas
    1. Olá, muito obrigado.
      A variável que controla o tamanho da cobra é essa "LENGTH_SNAKE". Ache todas elas no código e altere seu valor.

      Excluir
  12. Olá! Projeto bem legal, valeu por compartilhar com a gente.
    Eu estou com um probleminha na hora de compilá-lo :/ Ele diz mais ou menos assim: o erro tá no snake_bmp.c e tá na primeira linha do código e também diz assim: "A #device required before this line. Como resolvo posso resolvo isso?

    ResponderExcluir
  13. Otimo projeto!. E bem nessa tbm odeio o arduinoo! Koisa nada a ver uma placa pronta com um Atmel. E ja tem biblioteca p tudo, nao tem nem graca. Como diz nosso amigo "vamos ser programadores de verdade". Fazer as koisas na raça. A proposito otimo site! ;)

    ResponderExcluir

Postagens Relacionadas!!