LLothar

Scorched Earth for Arduino

Mar 8th, 2015
1,788
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //DISPLAY INI start
  2. #include <SPI.h>
  3. #include <Wire.h>
  4. #include <Adafruit_GFX.h>
  5. #include <Adafruit_SSD1306.h>
  6.  
  7. #define OLED_RESET 4
  8. Adafruit_SSD1306 display(OLED_RESET);
  9.  
  10. #define NUMFLAKES 10 //probably not needed leftovers from OLED demo
  11. #define XPOS 0
  12. #define YPOS 1
  13. #define DELTAY 2
  14.  
  15.  
  16. #define LOGO16_GLCD_HEIGHT 64
  17. #define LOGO16_GLCD_WIDTH  128
  18. static const unsigned char PROGMEM logo16_glcd_bmp[] = //Here I make the initial splash screen
  19. {
  20. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  21. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  22. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  23. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  24. 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
  25. 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
  26. 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
  27. 0xC0, 0x3F, 0xC0, 0xFF, 0x80, 0x1F, 0xF0, 0x03, 0xF8, 0x7E, 0x00, 0x00, 0xFE, 0x03, 0xF8, 0x07,
  28. 0xC0, 0xFF, 0xC3, 0xFF, 0xC0, 0x7F, 0xFC, 0x03, 0xF8, 0xFE, 0x00, 0x03, 0xFF, 0x87, 0xF8, 0x07,
  29. 0xC3, 0xFF, 0xC7, 0xFF, 0xC0, 0xFF, 0xFF, 0x03, 0xF8, 0xFE, 0x00, 0x07, 0xFF, 0xC7, 0xF8, 0x07,
  30. 0xC3, 0xFF, 0xCF, 0xFF, 0xC3, 0xFF, 0xFF, 0x83, 0xF9, 0xFC, 0x00, 0x0F, 0xFF, 0xE7, 0xF8, 0x07,
  31. 0xC7, 0xFF, 0xDF, 0xFF, 0xC3, 0xFF, 0xFF, 0x03, 0xF9, 0xFC, 0x00, 0x0F, 0xFF, 0xF7, 0xF8, 0x07,
  32. 0xC7, 0xFF, 0xDF, 0xFF, 0xC7, 0xFF, 0xFE, 0x03, 0xF9, 0xFC, 0x00, 0x0F, 0xFF, 0xF7, 0xF8, 0x07,
  33. 0xC7, 0xFF, 0xDF, 0xFF, 0x87, 0xFF, 0xFC, 0x03, 0xFB, 0xFC, 0x00, 0x0F, 0xE7, 0xF3, 0xF8, 0x07,
  34. 0xC7, 0xF0, 0x1F, 0xE0, 0x0F, 0xF8, 0x18, 0x03, 0xFB, 0xF8, 0x00, 0x1F, 0xC3, 0xFB, 0xF8, 0x07,
  35. 0xC7, 0xF0, 0x0F, 0xF0, 0x0F, 0xF0, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x1F, 0xC3, 0xFB, 0xF8, 0x07,
  36. 0xC7, 0xF0, 0x07, 0xF8, 0x0F, 0xE1, 0xFF, 0xF3, 0xFF, 0xF0, 0x00, 0x1F, 0xC7, 0xF3, 0xF8, 0x07,
  37. 0xC7, 0xFF, 0xC7, 0xFE, 0x0F, 0xE3, 0xFF, 0xF3, 0xFF, 0xF0, 0x00, 0x1F, 0xCF, 0xF7, 0xF8, 0x07,
  38. 0xC7, 0xFF, 0xC3, 0xFF, 0x0F, 0xE3, 0xFF, 0xF3, 0xFF, 0xFC, 0x00, 0x1F, 0xDF, 0xF7, 0xF8, 0x07,
  39. 0xC7, 0xFF, 0xC0, 0xFF, 0x8F, 0xE3, 0xFF, 0xE3, 0xFF, 0xFC, 0x00, 0x1F, 0xDF, 0xE7, 0xF8, 0x07,
  40. 0xC7, 0xFF, 0xC0, 0x7F, 0xCF, 0xE3, 0xFF, 0xE3, 0xFF, 0xFE, 0x08, 0x1F, 0xDF, 0xE7, 0xF8, 0x07,
  41. 0xC7, 0xFF, 0xC0, 0x3F, 0xCF, 0xE1, 0xFF, 0xE3, 0xF8, 0xFE, 0x01, 0x1F, 0xDF, 0xC7, 0xF8, 0x07,
  42. 0xC7, 0xF0, 0x00, 0x3F, 0xCF, 0xF0, 0x1F, 0xE3, 0xF8, 0xFE, 0x00, 0x5F, 0xCF, 0x07, 0xF8, 0x07,
  43. 0xC7, 0xF0, 0x00, 0x7F, 0xC7, 0xFC, 0x3F, 0xC3, 0xF8, 0xFE, 0x03, 0xFF, 0xC0, 0x03, 0xFC, 0x07,
  44. 0xC7, 0xF0, 0x1F, 0xFF, 0xC7, 0xFF, 0xFF, 0xC3, 0xF8, 0xFE, 0x23, 0xFF, 0xC0, 0x03, 0xFF, 0xE7,
  45. 0xC7, 0xF0, 0x1F, 0xFF, 0xC3, 0xFF, 0xFF, 0x83, 0xF8, 0xFE, 0x7F, 0xFF, 0xC0, 0x03, 0xFF, 0xE7,
  46. 0xC7, 0xF0, 0x1F, 0xFF, 0xC1, 0xFF, 0xFF, 0x03, 0xF8, 0xFE, 0x7F, 0xDF, 0xC0, 0x03, 0xFF, 0xE7,
  47. 0xC7, 0xF0, 0x1F, 0xFF, 0x80, 0xFF, 0xFE, 0x03, 0xF8, 0xFE, 0x3F, 0x1F, 0xC0, 0x01, 0xFF, 0xE7,
  48. 0xC7, 0xF0, 0x1F, 0xFF, 0x00, 0x7F, 0xFC, 0x03, 0xF8, 0xFE, 0x06, 0x1F, 0xC0, 0x00, 0xFF, 0xE7,
  49. 0xC7, 0xF0, 0x1F, 0xFC, 0x00, 0x1F, 0xF8, 0x03, 0xF8, 0xFE, 0x00, 0x1F, 0xC0, 0x00, 0x7F, 0xE7,
  50. 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
  51. 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
  52. 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
  53. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  54. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  55. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  56. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  57. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  58. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  59. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  60. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  61. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  62. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  63. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  64. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  65. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  66. 0x87, 0xFF, 0xE7, 0xFF, 0xFF, 0xFF, 0xF7, 0xFF, 0xFF, 0x8E, 0x3F, 0xFF, 0x9F, 0xFF, 0xFF, 0xFF,
  67. 0xDB, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x7F, 0xFB, 0xDF, 0xFF, 0xFF, 0xFF,
  68. 0xDB, 0xFF, 0xF7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF, 0x7F, 0xFB, 0xDF, 0xFF, 0xFF, 0xFF,
  69. 0xDB, 0x18, 0x34, 0xD3, 0x1C, 0x73, 0xF7, 0xF8, 0x3F, 0xDF, 0x7C, 0x71, 0xC7, 0x3D, 0x31, 0x97,
  70. 0xC6, 0xEB, 0xB5, 0xEE, 0xEB, 0xAD, 0xE7, 0xFB, 0xBF, 0xDF, 0x7B, 0xBB, 0xDA, 0xDE, 0xEE, 0xAB,
  71. 0xCE, 0xEE, 0x73, 0xEE, 0x0B, 0xF1, 0xF7, 0xFE, 0x7F, 0xDF, 0x7B, 0xBB, 0xDB, 0x1E, 0xE0, 0xAB,
  72. 0xD6, 0xED, 0xF3, 0xEE, 0xFB, 0xED, 0xF7, 0xFD, 0xFF, 0xDF, 0x7B, 0xBB, 0xDA, 0xDE, 0xEF, 0xAB,
  73. 0xD6, 0xEB, 0xB5, 0xEE, 0xEB, 0xAD, 0xF7, 0xFB, 0xBF, 0xDB, 0x6B, 0xBA, 0xDA, 0xDE, 0xEE, 0xAB,
  74. 0x93, 0x18, 0x24, 0xC7, 0x1C, 0x72, 0xF7, 0xF8, 0x3F, 0x82, 0x0C, 0x7D, 0xDB, 0x2C, 0x71, 0xAB,
  75. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  76. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xCF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  77. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  78. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  79. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  80. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  81. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  82. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  83. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
  84. };
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91. #if (SSD1306_LCDHEIGHT != 64) //probably not needed
  92. #error("Height incorrect, please fix Adafruit_SSD1306.h!");
  93. #endif
  94.  
  95. //DISPLAY INI END
  96.  
  97. //bullet
  98.  
  99.  
  100.  
  101. byte rounds = 1; //round counter
  102. byte led = 13; //default LED
  103. byte speaker = 11; //speaker pin
  104. byte knob = 0; //analog knob
  105.  
  106. byte landscape[128]; //landscape is an array containing height data. This is a byte, not int, as I am running out of memory. Adafruit takes 82% of RAM so no much left for the game itself
  107. byte tankAX = 15; //hard coded tank A position in X axis
  108. byte tankBX = 113; //hard coded tank B position in X axis
  109. bool playerA = true; //PlayerA starts. When false that means player B is playing
  110.  
  111. void GenerateLandscape(){ //function to generate landscape -
  112.   landscape[0] = 63; //very left is at zero. Note that adafruit library has 0,0 on the top left corner, thats why it is 63, so pixel no.64
  113.   landscape[31] = random(32,63); // 1/4 from the left edge, random height from a range
  114.   landscape[63] = random(20,63); // middle of the screen, again a random height.
  115.   landscape[95] = random(32,63); // 3/4 towards right edge, random height.
  116.   landscape[127] = 63; //right edge, at zero
  117.  
  118.   float increment = landscape[31] - landscape[0]; //this + below function generates slopes between the randomly generated heights. This should be a loop, but there are just 3 gaps to fill and I was lazy.
  119.   increment = increment/32;
  120.   for (byte i = 1; i <= 31; i++){
  121.     landscape[0+i] = landscape[0]+increment*i;
  122.     }
  123.  
  124.   increment = landscape[63] - landscape[31];
  125.   increment = increment/32;
  126.   for (byte i = 1; i <= 31; i++){
  127.     landscape[31+i] = landscape[31]+increment*i;
  128.     }    
  129.    
  130.    
  131.   increment = landscape[95] - landscape[63];
  132.   increment = increment/32;
  133.   for (byte i = 1; i <= 31; i++){
  134.     landscape[63+i] = landscape[63]+increment*i;
  135.     }  
  136.    
  137.   increment = landscape[127] - landscape[95];
  138.   increment = increment/32;
  139.   for (byte i = 1; i <= 31; i++){
  140.     landscape[95+i] = landscape[95]+increment*i;
  141.     }  
  142.    
  143. }
  144.  
  145.  
  146. void draw_terrain(){ //for drawing terrain. I use fast line drawing.
  147.     for (int i = 0; i < 129; i++) {
  148.   display.drawFastVLine(i,landscape[i],63, 1);
  149.   }
  150. }
  151.  
  152.  
  153. void draw_tanks(){ //tanks are just circles of a set radius. X position fixed, Y position taken from the landscape array.
  154.   display.drawCircle(tankAX, landscape[tankAX], 4, 1);
  155.   display.drawCircle(tankBX, landscape[tankBX], 4, 1);
  156.  
  157.   display.setCursor(80,0); //drawing the rounds number
  158.   display.print("Round ");
  159.   display.print(rounds);
  160. }
  161.  
  162.  
  163. void shoot(){ //this really is the main loop of the game. Everything takes place here.
  164.  int tankX; //tank is the current tank Variable for X position
  165.   int tankY;
  166.   int targetX; //target is the enemy tank
  167.   int targetY;
  168.   float bulletX; //variable for bullets This is position on X axis
  169.   float bulletY; //variable for bullets This is position on Y axis
  170.   float bulletXX; //convention is that XX is the velocity of the bullet in the X direction
  171.   float bulletYY; //
  172.   float angle = 1; //angle in radians. All calculations are in radians by default
  173.   float power = 45;
  174.   bool aim1 = true; //aim1 is for angle
  175.   bool aim2 = true; //aim2 is for power
  176.   int button;
  177.  
  178.  
  179.   if (playerA == true){ //assign correct coordinates for tank (current player) and target (enemy)
  180.     tankX = tankAX;
  181.     tankY = landscape[tankAX];
  182.     targetX = tankBX;
  183.     targetY = landscape[tankBX];
  184.   }
  185.   if (playerA ==false){
  186.     tankX = tankBX;
  187.     tankY = landscape[tankBX];
  188.     targetX = tankAX;
  189.     targetY = landscape[tankAX];
  190.     }
  191.    
  192.  
  193.  
  194.   while (aim1 == true){ //in this loop you make angle aim
  195.     angle = analogRead(knob); //read the analog input
  196.     angle = angle / 670 * 3.1416; //convert analog input to radians. I divide by 670 and not 1023 because I used 3.3V as reference. I just had it on the board for the OLED and was easier than dragging 5V just for potentiometer. Zero to Pi is 0 to 180 degrees.
  197.     display.setCursor(0,0); //writing the current angle value
  198.     display.print("Angle:");
  199.     display.println(angle);
  200.     display.drawLine(tankX, tankY, tankX + cos(angle)*15, tankY - sin(angle)*15,1); //this draws the turret.
  201.     draw_terrain();
  202.     draw_tanks();
  203.     display.display();
  204.     display.clearDisplay();
  205.     delay(10); //delay so I won't work at crazy framerates (can cause screen flickering in OLED). ~100FPS should be fast enough.
  206.    
  207.     button = digitalRead(2); //read button state
  208.        
  209.     if (button == 0){ //detect click.
  210.         delay(50); //wait 50ms and see if it was really pressed. Lame button noise detection.
  211.         if (button ==0){
  212.         aim1= false;  
  213.         }
  214.     }
  215.  
  216.      
  217.     }
  218.    
  219.     delay(100); //I give you 100ms to get your finger off that button. Kinda Lame as well, and should be easy to fix with few lines.
  220.   while (aim2 == true){//now power selection
  221.     power = analogRead(knob);
  222.     power = power / 670; //again, divide by 670 due to 3.3v as reference. This makes power to be a range of 0 to 1. I use floats so that's cool.
  223.    
  224.     display.setCursor(0,0);
  225.     display.print("Angle:");
  226.     display.println(angle); //display the angle
  227.     display.print("Power:");
  228.     display.println(power); //and current power
  229.     display.drawLine(tankX, tankY, tankX + cos(angle)*15, tankY - sin(angle)*15,1); //draw turret Would be cool to modify it so it gets larger when the power is higher ;)
  230.     draw_terrain();
  231.     draw_tanks();
  232.     display.display();
  233.     display.clearDisplay();
  234.     delay(10); //100FPS limiter here as well
  235.     button = digitalRead(2); //read button state
  236.         if (button == 0){ //detect click, lame way again, sorry
  237.         delay(50);
  238.         if (button ==0){
  239.         aim2= false;  
  240.         }
  241.     }
  242.  
  243.  
  244.    
  245.   }
  246.  
  247.   //now angle and power is set. Let's get this bullet going!
  248.  
  249.   bool hit = false; //hit is true when you hit.
  250.   bulletXX = cos(angle)*5*power; //calculating bullet velocity. I multiply by 5 to get a nice distance between calculations. This was trial end error. I do not need to calculate sub-pixel movement of the bullet, so if at high power I get movement by ~3 pixels that's ok.
  251.   bulletYY = -sin(angle)*5*power;
  252.   bulletX = tankX; //bullet starts at current player position
  253.   bulletY = tankY;  
  254.   float distance; //distance is used for hit-miss calculations. I wanted to have doppler effect driven sounds, but it turned out to be weird. It worked and all, but was not ear-pleasing.
  255.   float distanceX;
  256.   float distanceY;
  257.  
  258.   while(hit == false){ //loop for the bullet to fly
  259.      
  260.     display.drawLine(tankX, tankY, tankX + cos(angle)*15, tankY - sin(angle)*15,1); //draw turret
  261.     draw_terrain();
  262.     draw_tanks();
  263.     display.drawPixel(bulletX, bulletY, WHITE); //this is the bullet trace. I do not clear the screen inside of this while-loop, so I do not need an array to store the old bullet positions.
  264.  
  265.    
  266.  
  267.     distanceX = targetX - bulletX; //calculat the distance between the bullet and the target
  268.     distanceY = targetY - bulletY;
  269.     distance = sqrt(distanceX*distanceX+distanceY*distanceY);
  270.  
  271.     display.display();
  272.    
  273.     if (distance < 5){ //if you are closer than 5 pixels - consider this a hit
  274.       display.setCursor(10,30);
  275.       display.print("Player "); //some congratulations
  276.       if (playerA == true){
  277.         display.print("1 WINS!!!");
  278.       }else{
  279.         display.print("2 WINS!!!");
  280.       }
  281.       display.display();
  282.      
  283.       tone(speaker,440,2000); //a monotone noise for the winner!
  284.       hit = true; //hit! leave that while loop!
  285.      
  286.      
  287.      
  288.       delay(5000); //5 sec delay after hitting a target
  289.     }
  290.    
  291.    
  292.     int intbulletX = bulletX; // convert the bullet X position to int.
  293.     if (bulletY  > landscape[intbulletX] || bulletY > 63 ){ //detect hitting the ground or going below the screen.
  294.       hit = true;  //yeah, I make it hit=true, but you are hitting the ground buddy ;)
  295.     }
  296.    
  297.    
  298.    
  299.     bulletYY = bulletYY + 0.07; //bullet Y velocity changes due to gravity. I add a number (got by trial and error) so that velocity will "increase", but increase is in "down" direction - remember the adafruit having 0.0 at top left.
  300.     bulletX = bulletX + bulletXX; //position X affected by velocity
  301.     bulletY = bulletY + bulletYY; //position Y affected by velocity
  302. tone(speaker,440+bulletY); //tone o 440Hz plus the height of the bullet
  303.   }
  304.   //this part is when you leave the while loop of the current bullet flight.
  305. noTone(speaker);
  306. aim1= true;
  307. aim2 = true;
  308. }
  309.  
  310.  
  311. void setup() {
  312.  
  313.   Serial.begin(9600);
  314.  
  315.   // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  316.   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3D (for the 128x64)
  317.   // init done
  318.  
  319.  
  320.   display.clearDisplay();  // Clear the buffer.
  321.  
  322.  
  323.  
  324.   // initialize the digital pin as an output.
  325.   pinMode(led, OUTPUT);
  326.   pinMode(speaker, OUTPUT);
  327.   pinMode(knob, INPUT);
  328.   pinMode(2, INPUT);     //button
  329.   digitalWrite(2, HIGH); //enabled pull-up, so no resistor needed for button operations. Neat-o.
  330.   randomSeed(analogRead(0)); //random seed for landscape generation
  331.  
  332.   display.drawBitmap(0, 0,  logo16_glcd_bmp, 128, 64, 1); //splash screen
  333.   display.display();
  334.   delay(3000);
  335.   display.clearDisplay();
  336.  
  337.  
  338.  
  339.  
  340.  
  341.   display.setTextSize(1);
  342.   display.setTextColor(WHITE);
  343.  
  344.  
  345.  
  346.  
  347.   GenerateLandscape();
  348. }
  349.  
  350. // the loop routine runs over and over again forever:
  351. void loop() {  
  352.  
  353.  
  354. shoot(); //call shooting
  355.  
  356.    
  357. display.display();
  358. display.clearDisplay();
  359. delay(1000); //one second delay between shots
  360.  
  361. if (playerA == true){ //switch between player A and B
  362. playerA = false;}else{
  363.   playerA = true;
  364.    rounds++;} //increment round count after switch from B to A
  365.  
  366.  
  367. }
RAW Paste Data