El circuito esquemático de Arduino Bomber se observa en la siguiente imagen:

(click para ampliar)

Lista de Componentes
2 Resistencias 470Ω 0.25W
2 Resistencias 68Ω 0.25W
2 Resistencias 10KΩ 0.25W
1 Potenciómetro Lineal 10KΩ
1 Pulsador N.A. Rojo [tamaño grande]
1 Buzzer Pasivo 5V
1 Transistor NPN 2SC1815
1 Conector VGA Hembra para chasis
1 Placa Arduino Nanino
Librería VGAx desarrollada por Sandro Maffiodo

// Arduino Bomber for VGA output - Version 2.0, using VGAUtils.h
// written by Rob Cai - June the 14th, 2015

//A0: 5V Passive Buzzer (Buzzer Pasivo 5V)
//A1: 10K Lineal Potentiometer (Potenciometro Lineal 10K)
//A2: Push-Button (Pulsador N.A.)

#include <VGAX.h>
#include <VGAXUtils.h>
#include <math.h>

#define FNT_NANOFONT_HEIGHT        6
#define FNT_NANOFONT_SYMBOLS_COUNT 95
//#define BUTTON_PIN A0 //NB: by default, this pin (A0) is used in the VGAx library to generate the audio.
                      //    It is better to connect the button to another pin, for instance pin 2 (A2)
                      //    and use the next line insted of this one.
#define WHEEL_PIN  A1
#define BUTTON_PIN A2

VGAX vga;
VGAXUtils vgaU;

//data size=570 bytes
const unsigned char fnt_nanofont_data[FNT_NANOFONT_SYMBOLS_COUNT][1+FNT_NANOFONT_HEIGHT] PROGMEM={
{ 1, 128, 128, 128, 0, 128, 0, }, //glyph '!' code=0
{ 3, 160, 160, 0, 0, 0, 0, }, //glyph '"' code=1
{ 5, 32, 160, 240, 120, 32, 32, },  //glyph '#' = 'planeR' code=2
{ 3, 80, 32, 112, 112, 32, 0, },  //glyph '$' = 'bomb' code=3
{ 5, 32, 40, 120, 240, 32, 32, },  //glyph '%' = 'planeL' code=4
{ 5, 96, 144, 104, 144, 104, 0, },  //glyph '&' code=5
{ 5, 248, 248, 248, 248, 248, 248, },  //glyph ''' = 'rectangle 5 x 6' code=6
{ 2, 64, 128, 128, 128, 64, 0, }, //glyph '(' code=7
{ 2, 128, 64, 64, 64, 128, 0, },  //glyph ')' code=8
{ 3, 0, 160, 64, 160, 0, 0, },  //glyph '*' code=9
{ 3, 0, 64, 224, 64, 0, 0, }, //glyph '+' code=10
{ 2, 0, 0, 0, 0, 128, 64, },  //glyph ',' code=11
{ 3, 0, 0, 224, 0, 0, 0, }, //glyph '-' code=12
{ 1, 0, 0, 0, 0, 128, 0, }, //glyph '.' code=13
{ 5, 8, 16, 32, 64, 128, 0, },  //glyph '/' code=14
{ 4, 96, 144, 144, 144, 96, 0, }, //glyph '0' code=15
{ 3, 64, 192, 64, 64, 224, 0, },  //glyph '1' code=16
{ 4, 224, 16, 96, 128, 240, 0, }, //glyph '2' code=17
{ 4, 224, 16, 96, 16, 224, 0, },  //glyph '3' code=18
{ 4, 144, 144, 240, 16, 16, 0, }, //glyph '4' code=19
{ 4, 240, 128, 224, 16, 224, 0, },  //glyph '5' code=20
{ 4, 96, 128, 224, 144, 96, 0, }, //glyph '6' code=21
{ 4, 240, 16, 32, 64, 64, 0, }, //glyph '7' code=22
{ 4, 96, 144, 96, 144, 96, 0, },  //glyph '8' code=23
{ 4, 96, 144, 112, 16, 96, 0, },  //glyph '9' code=24
{ 1, 0, 128, 0, 128, 0, 0, }, //glyph ':' code=25
{ 2, 0, 128, 0, 0, 128, 64, },  //glyph ';' code=26
{ 3, 32, 64, 128, 64, 32, 0, }, //glyph '<' code=27
{ 3, 0, 224, 0, 224, 0, 0, }, //glyph '=' code=28
{ 3, 128, 64, 32, 64, 128, 0, },  //glyph '>' code=29
{ 4, 224, 16, 96, 0, 64, 0, },  //glyph '?' code=30
{ 4, 96, 144, 176, 128, 112, 0, },  //glyph '@' code=31
{ 4, 96, 144, 240, 144, 144, 0, },  //glyph 'A' code=32
{ 4, 224, 144, 224, 144, 224, 0, }, //glyph 'B' code=33
{ 4, 112, 128, 128, 128, 112, 0, }, //glyph 'C' code=34
{ 4, 224, 144, 144, 144, 224, 0, }, //glyph 'D' code=35
{ 4, 240, 128, 224, 128, 240, 0, }, //glyph 'E' code=36
{ 4, 240, 128, 224, 128, 128, 0, }, //glyph 'F' code=37
{ 4, 112, 128, 176, 144, 112, 0, }, //glyph 'G' code=38
{ 4, 144, 144, 240, 144, 144, 0, }, //glyph 'H' code=39
{ 3, 224, 64, 64, 64, 224, 0, },  //glyph 'I' code=40
{ 4, 240, 16, 16, 144, 96, 0, },  //glyph 'J' code=41
{ 4, 144, 160, 192, 160, 144, 0, }, //glyph 'K' code=42
{ 4, 128, 128, 128, 128, 240, 0, }, //glyph 'L' code=43
{ 5, 136, 216, 168, 136, 136, 0, }, //glyph 'M' code=44
{ 4, 144, 208, 176, 144, 144, 0, }, //glyph 'N' code=45
{ 4, 96, 144, 144, 144, 96, 0, }, //glyph 'O' code=46
{ 4, 224, 144, 224, 128, 128, 0, }, //glyph 'P' code=47
{ 4, 96, 144, 144, 144, 96, 16, },  //glyph 'Q' code=48
{ 4, 224, 144, 224, 160, 144, 0, }, //glyph 'R' code=49
{ 4, 112, 128, 96, 16, 224, 0, }, //glyph 'S' code=50
{ 3, 224, 64, 64, 64, 64, 0, }, //glyph 'T' code=51
{ 4, 144, 144, 144, 144, 96, 0, },  //glyph 'U' code=52
{ 3, 160, 160, 160, 160, 64, 0, },  //glyph 'V' code=53
{ 5, 136, 168, 168, 168, 80, 0, },  //glyph 'W' code=54
{ 4, 144, 144, 96, 144, 144, 0, },  //glyph 'X' code=55
{ 3, 160, 160, 64, 64, 64, 0, },  //glyph 'Y' code=56
{ 4, 240, 16, 96, 128, 240, 0, }, //glyph 'Z' code=57
{ 2, 192, 128, 128, 128, 192, 0, }, //glyph '[' code=58
{ 5, 128, 64, 32, 16, 8, 0, },  //glyph '\' code=59
{ 2, 192, 64, 64, 64, 192, 0, },  //glyph ']' code=60
{ 5, 32, 80, 136, 0, 0, 0, }, //glyph '^' code=61
{ 4, 0, 0, 0, 0, 240, 0, }, //glyph '_' code=62
{ 2, 128, 64, 0, 0, 0, 0, },  //glyph '`' code=63
{ 3, 0, 224, 32, 224, 224, 0, },  //glyph 'a' code=64
{ 3, 128, 224, 160, 160, 224, 0, }, //glyph 'b' code=65
{ 3, 0, 224, 128, 128, 224, 0, }, //glyph 'c' code=66
{ 3, 32, 224, 160, 160, 224, 0, },  //glyph 'd' code=67
{ 3, 0, 224, 224, 128, 224, 0, }, //glyph 'e' code=68
{ 2, 64, 128, 192, 128, 128, 0, },  //glyph 'f' code=69
{ 3, 0, 224, 160, 224, 32, 224, },  //glyph 'g' code=70
{ 3, 128, 224, 160, 160, 160, 0, }, //glyph 'h' code=71
{ 1, 128, 0, 128, 128, 128, 0, }, //glyph 'i' code=72
{ 2, 0, 192, 64, 64, 64, 128, },  //glyph 'j' code=73
{ 3, 128, 160, 192, 160, 160, 0, }, //glyph 'k' code=74
{ 1, 128, 128, 128, 128, 128, 0, }, //glyph 'l' code=75
{ 5, 0, 248, 168, 168, 168, 0, }, //glyph 'm' code=76
{ 3, 0, 224, 160, 160, 160, 0, }, //glyph 'n' code=77
{ 3, 0, 224, 160, 160, 224, 0, }, //glyph 'o' code=78
{ 3, 0, 224, 160, 160, 224, 128, }, //glyph 'p' code=79
{ 3, 0, 224, 160, 160, 224, 32, },  //glyph 'q' code=80
{ 3, 0, 224, 128, 128, 128, 0, }, //glyph 'r' code=81
{ 2, 0, 192, 128, 64, 192, 0, },  //glyph 's' code=82
{ 3, 64, 224, 64, 64, 64, 0, }, //glyph 't' code=83
{ 3, 0, 160, 160, 160, 224, 0, }, //glyph 'u' code=84
{ 3, 0, 160, 160, 160, 64, 0, },  //glyph 'v' code=85
{ 5, 0, 168, 168, 168, 80, 0, },  //glyph 'w' code=86
{ 3, 0, 160, 64, 160, 160, 0, },  //glyph 'x' code=87
{ 3, 0, 160, 160, 224, 32, 224, },  //glyph 'y' code=88
{ 2, 0, 192, 64, 128, 192, 0, },  //glyph 'z' code=89
{ 3, 96, 64, 192, 64, 96, 0, }, //glyph '{' code=90
{ 1, 128, 128, 128, 128, 128, 0, }, //glyph '|' code=91
{ 3, 192, 64, 96, 64, 192, 0, },  //glyph '}' code=92
{ 3, 96, 192, 0, 0, 0, 0, },  //glyph '~' code=93
{ 4, 48, 64, 224, 64, 240, 0, },  //glyph '£' code=94
};

static const char str1[] PROGMEM="#"; //planeR
static const char str2[] PROGMEM="%"; //planeL
static const char str3[] PROGMEM="$"; //bomb
static const char str4[] PROGMEM="'"; //rectangle 5 x 6
static const char str9[] PROGMEM="'''''''"; //clear 'Hit' banner
static const char str10[] PROGMEM="Hit !!!"; //'Hit' banner
static const char str11[] PROGMEM="Arduino VGA Bomber";
static const char str12[] PROGMEM="by Roberto Melzi";
static const char str13[] PROGMEM="VGAx library";
static const char str14[] PROGMEM="by Sandro Maffiodo";
static const char str15[] PROGMEM="Game Over!!!";

void line(float x1, float y1, float x2, float y2, int c){
  int divisions = int(1.1*1*sqrt(pow((y2 - y1),2) + pow((x2 - x1),2)));
  for (int i = 0; i <= divisions; i++){
    int x = int(x1 + i*(x2 - x1)/divisions);
    int y = int(y1 + i*(y2 - y1)/divisions);
    if(x > 0 && x < VGAX_WIDTH && y > 0 && y < VGAX_HEIGHT){
      vga.putpixel(x, y, c);
    }
  }
}

void cls(){
   vga.clear(0);
}

int shot = 12; //number of framer before next shot is possible ---------------------
unsigned char x,y;
boolean buttonStatus = 0;
int wheelPosition;
int BomberX;
float bombX;
float bombY;
float bombV0;
float bombV0y;
float bombX0;
float bombY0;
float aereoX;
float aereoY;
float Vaereo;
int ricarica = 0;
int aereoColpito = 0;
int bombaColpita = 1;
int t = 0;
int score = 40;
int maxScore = 116;
int level = 0;
int frame = 0;
int state = 1;
float bombX_0;
float bombY_0;
int planeX;
int planeY;
int planeX0;
int planeY0;
int BomberX0;
float radius;
float x0;
float y0;
float x1;
float y1;
int color;
int counterMenu = 0;
int counterMenu2 = 0;

void parameterIni() {
  aereoX = 10 + random(VGAX_WIDTH - 20);
  aereoY = 10 + random(VGAX_HEIGHT/4);
  bombX0 = aereoX;
  bombY0 = aereoY + 4;
  Vaereo = 0.1 + random(20)/100;
  bombV0 = Vaereo - random(-10,10)/100.;
  bombV0y = random(10)/100.;
  score = 40;
  level = 0;
  buttonStatus = 0;
  counterMenu = 0;
}

void processInputs() {
  wheelPosition = analogRead(WHEEL_PIN);
  buttonStatus = digitalRead(BUTTON_PIN) ;
}

void drawMenu() {
  counterMenu2++;
  vga.delay(10);
  if (counterMenu2 > 50){
    counterMenu++;
    vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str11, 20, 12, (counterMenu%3) + 1);
    vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str12, 30, 22, ((counterMenu + 1)%3) + 1);
    vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str13, 20, 32, (counterMenu%3) + 1);
    vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str14, 30, 42, ((counterMenu + 2)%3) + 1);
    counterMenu2 = 0;
  }
}

// this is the main function to draw the game screen
void drawGameScreen() {
   //draw plane ----------------------------------------------
   if(Vaereo > 0 && planeX != planeX0) {
      vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str4, planeX0, planeY0, 0);
      vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str1, planeX, planeY, 1);
   }
   if(Vaereo < 0 && planeX != planeX0) {
      vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str4, planeX0, planeY0, 0);
      vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str2, planeX, planeY, 1);
   }
   //draw bomb -----------------------------------------------
   vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str3, bombX_0, bombY_0, 0);
   vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str3, bombX, bombY, 2);
   //draw score line ----------------------------------------
   vgaU.draw_line(VGAX_WIDTH - (maxScore - 1),1,VGAX_WIDTH-score-1,1,0);
   vga.putpixel(VGAX_WIDTH - maxScore,1,(level + 2)%3 + 1);
   vgaU.draw_line(VGAX_WIDTH - 1 ,1,VGAX_WIDTH-score,1,3);
   //draw ground ---------------------------------------------
   vgaU.draw_row(VGAX_HEIGHT-1,VGAX_WIDTH,1,2);
   //draw bombard --------------------------------------------
   //BomberX = int((((1024 - wheelPosition) / 8) * (VGAX_WIDTH - 12))/ 128 + 6);
   if (BomberX != BomberX0) {
      vgaU.draw_column(BomberX0, VGAX_HEIGHT-4, VGAX_HEIGHT-7, 0);
      vgaU.draw_row(VGAX_HEIGHT-4, BomberX0-2, BomberX0+3, 0);
      vgaU.draw_row(VGAX_HEIGHT-3, BomberX0-5, BomberX0+6, 0);
      vgaU.draw_row(VGAX_HEIGHT-2, BomberX0-5, BomberX0+6, 0);

      vgaU.draw_column(BomberX, VGAX_HEIGHT-4, VGAX_HEIGHT-7, 3);
      vgaU.draw_row(VGAX_HEIGHT-4, BomberX-2, BomberX+3, 3);
      vgaU.draw_row(VGAX_HEIGHT-3, BomberX-5, BomberX+6, 3);
      vgaU.draw_row(VGAX_HEIGHT-2, BomberX-5, BomberX+6, 3);
   }
   // draw shot ----------------------------------------------
   if ( ricarica == shot - 1) {
      line(BomberX0,VGAX_HEIGHT-8,BomberX0,0,0);
      //vgaU.draw_column(BomberX0, 1, VGAX_HEIGHT-8, 0);
      //vgaU.draw_line(BomberX0, 2, BomberX0, VGAX_HEIGHT-8, 0);
   }
   if ( ricarica == shot) {
      line(BomberX,VGAX_HEIGHT-8,BomberX,0,1);
      //vgaU.draw_column(BomberX, 1, VGAX_HEIGHT-8, 1);
      //vgaU.draw_line(BomberX, 2, BomberX, VGAX_HEIGHT-8, 1);
   }
}

void setup() {
  //Serial.begin(9600); // this gives flickers...
  pinMode(WHEEL_PIN, INPUT);
  pinMode(BUTTON_PIN, INPUT);

  vga.begin();
}

void loop() {

  processInputs();

  if(state == 1) {
     drawMenu();
     vga.delay(10);
  }

  if (buttonStatus == 1 && state == 1){
     buttonStatus == 0;
     vga.clear(0);
     parameterIni();
     state = 2;
  }

  if(state == 2) {

     // this is exectuted just after a shot -----------------------
     if (ricarica == shot) {
        if (BomberX > aereoX - 2 - level && BomberX < aereoX + 2 + level) { // plane is hit ------------------
           aereoX = -10;
           score += 8;
           vga.tone(110);
           vga.delay(60);
           vga.noTone();
         }
         if (BomberX > (bombX - 2 ) && BomberX < (bombX + 2)) { // bomb is hit ----------------
            //bombX0 = 2*VGAX_WIDTH;
            //bombY0 = -100.;
            //bombV0 = 0;
            bombY0 = aereoY + 4;
            bombX0 = aereoX;
            bombV0 = Vaereo - 0.1*level + random(-100,100)/1000.;
            bombV0y = 0.1*level + random(100)/1000.;
            t = 0;
            score += 8;
            vga.tone(165);
            vga.delay(60);
            vga.noTone();
          }
     }

     // plane has escaped ----------------------------------------------------
     if(aereoX > VGAX_WIDTH || aereoX < 0) {
        score += -4 - level;
        Vaereo = random(200)/1000.0 + 0.2 + 0.2*level;
        aereoY = random(VGAX_HEIGHT*2/3*100)/100.0 + 2;
        if(random(1000) > 500)
           {aereoX = 10;}
        else {
           aereoX = VGAX_WIDTH-10;
           Vaereo = -Vaereo;
        }
     }

     // plane position -------------------------------------------------------
     aereoX += Vaereo;

     // bomb position and trajectory -----------------------------------------
        bombX = bombX0 + bombV0*t;
        bombY = bombY0 + bombV0y*t + t*t/(600 - 200*level);
        if(bombY > VGAX_HEIGHT - 5 || bombX < 0 || bombX > VGAX_WIDTH){
          if(bombX >= BomberX - 6 && bombX < BomberX + 6){
             //Bomber has been hit -------------------------------------------
             vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str10, 50, 10, 1);
             vga.tone(880);
             vga.delay(200);
             vga.tone(440);
             vga.delay(200);
             vga.tone(220);
             vga.delay(200);
             vga.tone(110);
             vga.delay(200);
             vga.noTone();
             vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str9, 50, 10, 0);
             vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str9, 51, 10, 0);
             score += -30;
          }
          bombY0 = aereoY + 4;
          bombX0 = aereoX;
          bombV0 = Vaereo - 0.1*level + random(-100,100)/1000.;
          bombV0y = 0.1*level + random(100)/1000.;
          t = 0;
       }
       else
       {t = t + 1;}

       // check the shot ---------------------------------------------------------
       if(ricarica != 0 ) {
          ricarica += -1;
       }
       if ( buttonStatus == 1 && ricarica == 0) {
          score += -1;
          ricarica = shot;
          BomberX0 = BomberX;
          buttonStatus = 0;
        }

        // check score state and Game Over --------------------------------------
        if(score < 0) {
           buttonStatus == 0;
           vga.delay(300);
           vga.tone(660);
           vga.delay(200);
           vga.tone(330);
           vga.delay(200);
           vga.tone(165);
           vga.delay(200);
           vga.tone(82);
           vga.delay(200);
           vga.noTone();
           state = 3;
        }
        if (score > maxScore) {
          score = maxScore/2;
          vga.tone(440);
          vga.delay(100);
          vga.tone(880);
          vga.delay(100);
          vga.noTone();
          level++;
        }

     planeX = int(aereoX);
     planeY = int(aereoY);
     BomberX = int((((1024 - wheelPosition) / 8) * (VGAX_WIDTH - 12))/ 128 + 6);

     drawGameScreen();

     bombX_0 = bombX;
     bombY_0 = bombY;
     planeX0 = planeX;
     planeY0 = planeY;
     BomberX0 = BomberX;
   }

   if(state == 3){
     vga.printPROGMEM((byte*)fnt_nanofont_data, FNT_NANOFONT_SYMBOLS_COUNT, FNT_NANOFONT_HEIGHT, 3, 1, str15, 40, 20, 1);
     vga.delay(200);
     if(buttonStatus == 1){
        parameterIni();
        state = 1;
        vga.clear(0);
     }
   }
}

(click para ampliar)

(click para ampliar)

(click para ampliar)

(click para ampliar)

(click para ampliar)

Anuncios

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s