Advertisement
LLothar

Scorched Earth for Arduino 2nd edition

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