Sugestions for book or online having trouble with bitmap

newer user. just got into tvout. the demo sketch worked perfect. but on other 2 projects i keep getting error "bitmap.h not found" just looking for a source to learn more so i can figure this out. Thanks!

Edit
i'm mearly asking for suggestions for how / where to learn more. i've already bought 2 books and they both suck. plz no negative comments.

Hello brstroh601

Post your sketch, well formated, with comments and in so called code tags "</>" to see how we can help.

Have a nice day and enjoy programming in C++ and learning.

1 Like

fetching my crystal ball, don’t go anywhere

Hello, that's my crystal ball !!!

What the heck are you guys on about, asking for code and going on about your crystal balls. (Which, btw OP, is a smart arse way of saying they can't see your code.)

OP simply asked for an info source, not help with code. (Sure, Programming Questions is maybe not the best place to have posted, but probably as good as anywhere.)

Those responses to a brand new user, represent the worst and none of the best of this forum.

1 Like

i think i just need to better educate myself, but here is the code.

/**************************************************************************
 *  
 *  ARDUINO SPACE INVADERS 1.2
 *  
 *  Jan/2022  Giovanni Verrua
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *   
 *   Connections to Arduino Uno/Nano:
 *   
 *   Connect a button to pin 12 (digital) and +5V (button Fire / Start)
 *   Connect a 100 kohm resistor between pin 12 (digital) and GND
 *   
 *   If you want to use a Wheel, connect a 100 k ohm potentiomenter to: 
 *           GND (left pin), +5V (right pin), A0 (middle pin)
 *           
 *   If you wan to use two buttons for left and right (like the original arcade)
 *   Connect two buttons to pin 4 and +5V (but.left), and pin 5 and +5V (but.right)
 *   Connect two 100 kohm resistors between pin 5 and GND, and pin 6 and GND*   
 *   
 *   TV composite out: 
 *   Connect  1k ohm resistor from pin 9 to TV out (+)
 *   Connect 470 ohm resistor from pin 7 to TV out (+)   
 *   Connect GND                         to TV out (-)
 *   
 *   Audio:
 *   Connect a speaker between pin 11 and GND
 *   
 *   Release history
 *   
 *  1.2 - added audio effects 
 *      - added an option for using buttons or potentiometer 
 *        to control the cannon (see: #define USE_WHEEL) 
 *      - emproved the size of the cannon (you can go back to the   
 *        old size changing cn1, cn2, cn3 with ca1, ca2, ca3 
 *        (look in the cannon section below)
 *      
 *  1.1 fixed some bugs 
 *  1.0 initial release
 * 
 **************************************************************************/

#include <TVout.h>
#include "bitmap.h"
#include <fontALL.h>

//----------------------------------------------------------------------------------

//#define USE_WHEEL  activate this if you want to use potentiometer instead of buttons

#define CANNON_SPEED  20 //higher value, slower cannon - only for button control
#define BUTTON_LEFT   4
#define BUTTON_RIGHT  5
#define BUTTON_FIRE   12   

#define WHEEL_MOVE   A0  //Analog  A0 - potentiometer
#define RATIO_WHEEL  8.2 //Ratio Video X resolution Vs. potentiometer resolution

//----------------------------------------------------------------------------------

#define CAN_Y_POS 86       //Cannon Y Position
#define SHD_Y_POS 70       //Shield Y Position

#define ASHIP_SPEED 50      //higher value, slower ship   (must to be >0)
#define ALIEN_SPEED 20      //higher value, slower aliens (must to be >0)

TVout TV;

int gamSt = 0;  //0 = menu, 1 = in game, 2 = game over


//int canMove = 0; //cannon move (wheel value)
//int canShot = 0; //cannon shot (button pressed)

int canPosX = 0; //cannon position
int canOldX = 0; //cannon old position
int canFire = 0; //cannon fire 1 = bullet flying, 0 = idle

int canFirX = 0; //bullet X position
int canFirY = 0; //bullet Y position

//int lives = 3;
int aSound = 0;
int gLevel = 0; 

int begiY = 0; //Y begin
int shftY = 1; //Y movement
int shftX = 0; //X movement
int direX = 1; //X direction (1 ; -1)
int corrZ = 0;
int coluR = 8; //rightmost column with at least 1 alien
int rwLow = 4; //last lower row with at least 1 alien
int alien = 5*9; //aliens still alive
int aliFire = -1; //alien fire 1 = bomb falling, 0 = idle
int aliFirX = 0; //bomb X position
int aliFirY = 0; //bomb Y position

int aMatrix[5][9] = { {0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0},
                      {0,0,0,0,0,0,0,0,0} };                      
  

//===================================================================================== SETUP
void setup() {

   
    //Serial.begin(9600);
    TV.begin(_PAL); //128x96 default

#ifdef USE_WHEEL 
    pinMode(WHEEL_MOVE,INPUT);     
#else    
    pinMode(BUTTON_LEFT,INPUT);
    pinMode(BUTTON_RIGHT,INPUT);
#endif

    pinMode(BUTTON_FIRE,INPUT);
    canFire = 0;
    canOldX = -2;  
    gamSt = 0;        

}


//===================================================================================== AlienReset
void AlienReset() {
 
 for (int i=0;i<5;i++){     
   for (int j=0;j<9;j++){    

      aMatrix[i][j] = 1;      
    }
  }   

  begiY = gLevel*2; //Y begin - every level 2 pixels lower
  shftY = 1; //Y movement
  shftX = 0; //X movement
  direX = 1; //X direction (1 ; -1)
  corrZ = 0;
  coluR = 8; //rightmost column with at least 1 alien
  rwLow = 4; //last lower row with at least 1 alien
  alien = 5*9; //aliens still alive
  aliFire = -1;
}


//============================================================================= AlienCheck
void AlienCheck() {

   alien = 0;
   for (int i=0;i<5;i++){  
      for (int j=0;j<9;j++){
         if (aMatrix[i][j] == 1) alien ++; //how many aliens still alive
      }       
   }
  
 
  if (alien >0){  //checking what are the leftmost and rightmost columns with at least 1 alien alive
    
    //shift all the columns leftward if the leftmost column is all empty
   // if (shftX == 0 && direX == -1) {//solo quando sto tornando, cos evito di fare degli scatti bruschi
   
      if (aMatrix[0][0] == 0 && aMatrix[1][0] == 0 && aMatrix[2][0] == 0 && aMatrix[3][0] == 0 && aMatrix[4][0] == 0){
        for (int i=0;i<5;i++){        
           for (int j=0;j<8;j++){
               aMatrix[i][j] = aMatrix[i][j+1] ;          
           }
        }

        for (int i=0;i<5;i++){
            aMatrix[i][8] = 0;
        }
      }
    // }

    //check if the rightmost column (that at last check had at least 1 alien) is now empty
    if (aMatrix[0][coluR] == 0 && aMatrix[1][coluR] == 0 && aMatrix[2][coluR] == 0 && aMatrix[3][coluR] == 0 && aMatrix[4][coluR] == 0) coluR -- ;

    //check if the lowest row (that at lat check had at least 1 alien) is now empty
    if (aMatrix[rwLow][0] == 0 && aMatrix[rwLow][1] == 0 && aMatrix[rwLow][2] == 0 && aMatrix[rwLow][3] == 0 && aMatrix[rwLow][4] == 0 && 
        aMatrix[rwLow][5] == 0 && aMatrix[rwLow][6] == 0 && aMatrix[rwLow][7] == 0 && aMatrix[rwLow][8] == 0) rwLow -- ;     
    
  }

}

//============================================================================= AlienDraw()
void alienDraw() {


     TV.draw_rect( 0, 00+begiY+shftY-corrZ, 127, (10*rwLow)+9, 0, 0 );  //deleting the old aliens position      
      for (int j=0;j<=coluR;j++){  //drawing the columns, considering the left/rightmost columns with at least 1 alien alive

          if( shftX % 2 == 0){
           if (aMatrix[0][j] == 1) TV.bitmap((j)*10+(shftX*2), begiY+00+shftY, a3a);
           if (aMatrix[1][j] == 1) TV.bitmap((j)*10+(shftX*2), begiY+10+shftY, a2a);
           if (aMatrix[2][j] == 1) TV.bitmap((j)*10+(shftX*2), begiY+20+shftY, a2a);
           if (aMatrix[3][j] == 1) TV.bitmap((j)*10+(shftX*2), begiY+30+shftY, a1a);
           if (aMatrix[4][j] == 1) TV.bitmap((j)*10+(shftX*2), begiY+40+shftY, a1a);
          }
        else {
           if (aMatrix[0][j] == 1) TV.bitmap((j)*10+(shftX*2), begiY+00+shftY, a3b);
           if (aMatrix[1][j] == 1) TV.bitmap((j)*10+(shftX*2), begiY+10+shftY, a2b);
           if (aMatrix[2][j] == 1) TV.bitmap((j)*10+(shftX*2), begiY+20+shftY, a2b);
           if (aMatrix[3][j] == 1) TV.bitmap((j)*10+(shftX*2), begiY+30+shftY, a1b);
           if (aMatrix[4][j] == 1) TV.bitmap((j)*10+(shftX*2), begiY+40+shftY, a1b);
         }
     } 

     aSound++;
     if (aSound >3) aSound = 0;
     TV.tone(100 - aSound*22,50); 
     //TV.delay_frame(3);    NOOOO!!!!!!!!!! This will compromise the game speed, don't activate!       
}


//============================================================================= AlienMove
void AlienMove() {

  shftX += direX;

  corrZ = 0;
  if (begiY+shftY >=2) corrZ = 2;
         
  if ( (shftX<= 20 + (8-coluR)*5 && direX == 1) || (shftX>=0 && direX == -1) ){  //checking the horizontal movement of the aliens, considering the left/rightmost columns with at least 1 alien alive
      
     alienDraw() ;
  } 
  else {
    
    shftY = shftY + 2;
    direX = direX *-1;
    shftX += direX;  //don't remove!
           
    alienDraw() ;        
   }  
  
}


//============================================================================= AlienHit
void alienHit() {

  for (int j=0;j<=coluR;j++){  //drawing the columns, considering the left/rightmost columns with at least 1 alien alive
    for (int i=0;i<=4;i++){  //drawing the columns, considering the left/rightmost columns with at least 1 alien alive
      if  (canFirX >=(j)*10+(shftX*2) && canFirX <=(j)*10+(shftX*2)+8 && canFirY >= begiY+ i*10 +shftY && canFirY <= begiY+ i*10 +shftY+8) { 
          aMatrix[i][j] = 0; 
          j = coluR+1; 
          i = 5;           
          canFire = -1;  
          TV.tone(2000,50);
          TV.delay_frame(1);
       }
    }
   }

   alienDraw() ; 
  
}


//===================================================================================== LOOP
void loop() {

  unsigned long miab = millis() ;  //delay - alien bomb
  unsigned long micb = millis() ;  //delay - cannon bullet
  unsigned long mill = millis() ;  //delay - aliens
  unsigned long mish = millis() ;  //delay - ship
  
#ifndef USE_WHEEL 
  unsigned long cand = millis() ;  //cannon delay
#endif
  
  int canMove = 0;   
  int Score = 0;
  int lives = 3;
  int shpMove = 0;
  int shpPosX = 0;

  //-----------------------------------------------------------------------------------------------------MENU              
  if (gamSt == 0){   //MENU

        TV.clear_screen();           
        TV.bitmap(0,  0, logo);
        TV.bitmap(0, 32, start);   

        delay(500);     

        while ( digitalRead(BUTTON_FIRE) == 0){                                     
           //canShot = digitalRead(BUTTON_FIRE); //cannon shot    
         }
                  
         gamSt = 1; 
         delay(300);
  }
    
 
 //-----------------------------------------------------------------------------------------------------IN GAME
 
  if (gamSt == 1){   // IN GAME

     Score = 0;
     lives = 3;
     canOldX = -2;
     aSound = 3;
     gLevel = 0;  
   
     TV.clear_screen();
     TV.bitmap(10,SHD_Y_POS,shd);
     TV.bitmap(35,SHD_Y_POS,shd);
     TV.bitmap(60,SHD_Y_POS,shd);     
     TV.bitmap(85,SHD_Y_POS,shd);
     AlienReset(); 
     AlienCheck();
     
     delay(50);

/* shouldn't be needed....
#ifdef USE_WHEEL     
     canMove = analogRead(WHEEL_MOVE); //cannon move
#endif
     
     canShot = digitalRead(BUTTON_FIRE); //cannon shot    
*/
     
     shftY = 0 ;     
     //-----------------------------------------------------------------------------------------------------Main Cycle-begin-\
     
     while (  (shftY/2  < 19 + (4 - rwLow)*5) && gamSt != 2 ) {  //Vertical moving. 
          
        
        //-------------------------------------------------------------Cannon-begin-\ 
        
        

        //-----------------------------------cannon move

#ifdef USE_WHEEL     //------------------------------------- using potentiometer -----------------------------------------------| 
        canMove = analogRead(WHEEL_MOVE); //cannon move
        canPosX = canMove / RATIO_WHEEL ; 

        if (canPosX -1 == canOldX || canPosX + 1 == canOldX) canPosX = canOldX; //Avoiding flickering 
        
#else               //------------------------------------- using buttons left and right----------------------------------------|

        if (cand + CANNON_SPEED < millis()) {
          cand = millis() ;        
          if (digitalRead(BUTTON_LEFT )==1 && canPosX >0  ) canPosX-- ;
          if (digitalRead(BUTTON_RIGHT)==1 && canPosX <110) canPosX++ ;
        }
#endif             //-----------------------------------------------------------------------------------------------------------|

        if (canOldX != canPosX) {
           TV.bitmap(canOldX, CAN_Y_POS, cnn); 
           if (lives == 3) TV.bitmap(canPosX, CAN_Y_POS, cn3);    //use ca3 instead of cn3 if you want a wider cannon
           if (lives == 2) TV.bitmap(canPosX, CAN_Y_POS, cn2);    //use ca2 instead of cn2 if you want a wider cannon
           if (lives == 1) TV.bitmap(canPosX, CAN_Y_POS, cn1);    //use ca1 instead of cn1 if you want a wider cannon      
           canOldX = canPosX;
        }

        
        //-----------------------------------cannon fire
        
        //canShot = digitalRead(BUTTON_FIRE); //cannon shot     
        
        if (canFire == -1){ //cannon fire 1 = bullet flying, 0 = idle -1 = Hit          
           TV.draw_line(canFirX,canFirY,  canFirX,canFirY+4,0);
           canFire = 0;                      
        }

        
        if (canFire == 0){ //cannon fire 1 = bullet flying, 0 = idle
            if (digitalRead(BUTTON_FIRE) == 1 && micb < millis() ) {
                canFire = 1;
                canFirX = canPosX+8; //bullet X position
                canFirY = 81; //bullet Y position              
             }   
         }         
         
        if (canFire == 1){ //cannon fire 1 = bullet flying, 0 = idle
          
          if (micb+10 < millis()){      
                         
             if (TV.get_pixel(canFirX,canFirY-1) == 1){

                 if (shpMove == 1 && canFirY < 10) {
                    //hit the ship
                     TV.tone(2000,50);
                     Score += 10;
                     shpMove = 0;
                     canFire = -1; 
                     TV.draw_rect(00,00,128,9,0,0);                      
                     TV.draw_line(canFirX,canFirY-2,canFirX,canFirY+4,0); 
                     //micb = millis() + 200; //delay before next shot
                  
                 }
                 else {
                 
                    if (canFirY <=begiY+(10*rwLow)+9+shftY){                               
                       //hit an alien
                       alienHit();
                       Score ++; 
                       //micb = millis() + 200;  //delay before next shot
                   
                       if ((00+begiY+shftY-corrZ) > 4 && shpMove == 0){             
                            TV.select_font(font4x6);
                            TV.print(00,00,"SCORE:"); 
                            TV.print(40,00,Score); 
                          }
                     
                    }
                    else{
                       //hit the shield
                       canFire = -1; 
                       TV.draw_line(canFirX,canFirY-2,canFirX,canFirY+4,0); 
                       //micb = millis() + 200; //delay before next shot
                    }
                 }

               micb = millis() + 200; //delay before next shot  
               TV.draw_line(canFirX,canFirY,canFirX,canFirY+4,0);
               canFire = -1; //error trap 
              }
             else
              {
               canFirY --;  
               micb = millis();
               if (canFirY <= 0){
                  canFire = 0;
                  TV.draw_line(canFirX,canFirY,canFirX,canFirY+4,0);
                  micb = millis() + 200; //delay before next shot
               }

             }
             
             if (canFire == 1){                    
                TV.draw_line(canFirX,canFirY+1,canFirX,canFirY+4,0);
                TV.draw_line(canFirX,canFirY,  canFirX,canFirY+3,1);
               }
           }
         
        }
        
        if (alien == 0){
          gLevel++;
          TV.clear_screen();          
          AlienReset(); 
          TV.bitmap(10,SHD_Y_POS,shd);
          TV.bitmap(35,SHD_Y_POS,shd);
          TV.bitmap(60,SHD_Y_POS,shd);     
          TV.bitmap(85,SHD_Y_POS,shd);
          canFire = 0; 
          canOldX = -2;                   
        }

        //-------------------------------------------------------------Cannon-end---/

        //-------------------------------------------------------------Ship begin--\

        if ((00+begiY+shftY-corrZ) > 8 ){   //if there's enough space in the upper part of the screen

           if (shpMove == 0){
              if (mish + 15000+random(10000,25000) < millis()){  //every 25-40 seconds              
                 shpMove = 1;                 
                 TV.draw_rect(00,00,128,9,0,0);
                 mish = millis() - ASHIP_SPEED - 1 ;
                 shpPosX = 1;  //not = 0!
              }            
           }

           if (shpMove == 1){
              if (mish + ASHIP_SPEED < millis()){
                 TV.bitmap(shpPosX-1,0,cnn);
                 TV.bitmap(shpPosX,0,shp);
                 shpPosX++ ;               
                 mish = millis(); 

                 if (shpPosX >= 112){
                     shpMove = 0;
                     TV.draw_rect(00,00,128,9,0,0);                                          
                 }
              }
           }
          
          
        }


        //-------------------------------------------------------------Aliens-begin-\
        
        if (mill + ALIEN_SPEED*alien < millis()){
           mill = millis();
           AlienCheck();
           AlienMove();
           
           if ((00+begiY+shftY-corrZ) > 4  && shpMove == 0){
             
               TV.select_font(font4x6);
               TV.print(00,00,"SCORE:"); 
               TV.print(40,00,Score); 
            }   
                                
        }
        
        //-------------------------------------------------------------Aliens-end---/

        //--------------------------------------------------------Aliens bomb-begin-\
                
        //----------------------------------------------------
        if (aliFire == -1){  // end of bomb fall
          //TV.draw_line(aliFirX,aliFirY,  aliFirX,aliFirY+4,0);
           aliFire = 0;
           miab = millis() + 40*alien ;
        }

        //----------------------------------------------------
        if (aliFire == 0){   //0 = idle - waiting for the next bomb                               

           if (miab+10 < millis()){  //drop the bomb at the right time    
            
             aliFirY = begiY+(10*rwLow)+9+shftY; //bomb Y position
             aliFire = 1;                         

             //to be improved: should not drop bomb from an empty column
             if (canPosX >=(shftX*2) && canPosX <=10*coluR+(shftX*2)){ //the cannon is below the aliens                 
                 aliFirX = canPosX+8+random(-4,+4); //bomb X position = center of cannon                             
              }
              
             if (canPosX < shftX*2){ //drop the bomb as closest as possible to the cannon                
                aliFirX = shftX*2;                                  
              }
              
              if (canPosX > 10*coluR+(shftX*2)){ //drop the bomb as closest as possible to the cannon                
                aliFirX = 10*coluR+(shftX*2);                                      
              } 
              
              //check if there's at least an alien over it
              int fndAlien = 0;                        
              
              for (int i=aliFirY;i >begiY+9+shftY;i-=3){
                  if (TV.get_pixel(aliFirX,i) == 1) fndAlien = 1;
              }
              
              if (fndAlien==0){  //the cannon is under an empty column, so there's no need to drop a bomb
                 aliFire = 0;
              }
              
            }                
         }         
         
        //----------------------------------------------------
        if (aliFire == 1){   //bomb dropping 
          if (miab+10 < millis()){      
                         
             TV.draw_line(aliFirX,aliFirY-1,aliFirX,aliFirY-4,0);
             TV.draw_line(aliFirX,aliFirY,aliFirX,aliFirY-3,1);

             if (TV.get_pixel(aliFirX,aliFirY+1) == 1){           
             
                 aliFire = -1;   
                 TV.draw_line(aliFirX,aliFirY,aliFirX,aliFirY-3,0);    
                 
                 if (aliFirY+1 >=CAN_Y_POS) {                    
                  
                    //hit the cannon.                                                
                    for (int i=0;i<27;i++){
                        TV.tone(70,10);
                        TV.delay_frame(1);
                        TV.bitmap(canPosX, CAN_Y_POS, hit);
                        delay(5);
                        TV.tone(40,10);
                        TV.delay_frame(1);
                        if (lives == 3) TV.bitmap(canPosX, CAN_Y_POS, cn3);    //use ca3 instead of cn3 if you want a wider cannon 
                        if (lives == 2) TV.bitmap(canPosX, CAN_Y_POS, cn2);    //use ca2 instead of cn2 if you want a wider cannon
                        if (lives == 1) TV.bitmap(canPosX, CAN_Y_POS, cn1);    //use ca1 instead of cn1 if you want a wider cannon
                        delay(5);
                    }    

                    lives --;
     
                    delay(500); 
          
                    if (lives <=0) gamSt = 2;     
                    if (lives == 3) TV.bitmap(canPosX, CAN_Y_POS, cn3);    //use ca3 instead of cn3 if you want a wider cannon 
                    if (lives == 2) TV.bitmap(canPosX, CAN_Y_POS, cn2);    //use ca2 instead of cn2 if you want a wider cannon
                    if (lives == 1) TV.bitmap(canPosX, CAN_Y_POS, cn1);    //use ca1 instead of cn1 if you want a wider cannon 
     
                  }    
                 else {
                   //hit the shield. Just open an hole. 
                   TV.draw_line(aliFirX,aliFirY+2,aliFirX,aliFirY-3,0);    
                 }
              }
             else
              {
               aliFirY ++;  
               miab = millis();
               if (aliFirY >= 92){
                  aliFire = -1;
                  TV.draw_line(aliFirX,aliFirY,aliFirX,aliFirY-4,0);
               }
             }
           }         
        }

        //--------------------------------------------------------Aliens bomb-end---/
     }
     //-----------------------------------------------------------------------------------------------------Main Cycle-end--- /
     gamSt = 2 ;
   }

      //-----------------------------------------------------------------------------------------------------GAME OVER 
      if (gamSt == 2){  //GAME OVER
        gamSt = 0;     
        TV.clear_screen();           
        TV.bitmap(0,  0, logo);
        TV.bitmap(0, 32, over); 
        TV.select_font(font6x8);
        TV.print(40,90,"SCORE:"); 
        TV.print(76,90,Score);       
        delay(1000);
        
        //must to release and press again the button before to continue
        while ( digitalRead(BUTTON_FIRE) == 1){                                     
           //canShot = digitalRead(BUTTON_FIRE); //cannon shot    
         }
      
        while ( digitalRead(BUTTON_FIRE) == 0){                                     
           //canShot = digitalRead(BUTTON_FIRE); //cannon shot    
         }

      }
      
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.