max
Published

Speed Math Cannon Game using Arduino in EWsim

Building a speed math cannon game in EWsim

BeginnerFull instructions provided6 hours59

Things used in this project

Story

Read more

Schematics

Speed Math Cannon Game using Arduino in EWsim

open zip file in EWsim

Code

Speed Math Cannon Game using Arduino in EWsim

Arduino
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

const int POT_AIM_PIN=A0;
const int BUTTON_PIN=2;
int lastButtonState=HIGH;
int score=0,wrongCount=0;
bool gameOver=false;
int numA=0,numB=0,correctAnswer=0;
char opSymbol='x';
struct Target{float x,y,speed;int value;bool active;}; Target targets[3];
bool bulletActive=false;
float bulletX=64,bulletY=52,bulletVx=0,bulletVy=0;
String feedbackMsg="";
unsigned long feedbackTimer=0;

void generateNewQuestion(){
 int op=random(0,2);
 if(op==0){opSymbol='x';numA=random(2,10);numB=random(2,10);correctAnswer=numA*numB;}
 else{opSymbol='+';numA=random(10,45);numB=random(10,45);correctAnswer=numA+numB;}
 int c=random(0,3);
 for(int i=0;i<3;i++){
  targets[i].x=random(15,95); targets[i].y=18+i*9;
  targets[i].speed=(random(5,15)/10.0)*(random(0,2)?1:-1);
  targets[i].active=true;
  if(i==c) targets[i].value=correctAnswer;
  else{
   int w; do{w=correctAnswer+random(-10,11);}while(w<=0||w==correctAnswer);
   targets[i].value=w;
  }
 }
}

void setup(){
 pinMode(BUTTON_PIN,INPUT_PULLUP);
 display.begin(SSD1306_SWITCHCAPVCC,0x3C);
 randomSeed(analogRead(A2));
 generateNewQuestion();
}

void loop(){
 if(gameOver){
  display.clearDisplay();
  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(14,8);
  display.print("GAME");
  display.setCursor(14,28);
  display.print("OVER");
  display.setTextSize(1);
  display.setCursor(20,50); 
  display.print("Score: "); 
  display.print(score);
  display.setCursor(10,58); 
  display.print("Press Fire");
  display.display();
  if(digitalRead(BUTTON_PIN)==LOW){
    delay(300);
    score=0;
    wrongCount=0;
    gameOver=false;
    bulletActive=false;
    feedbackMsg="";
    generateNewQuestion();
  }
  return;
 }

 int rawAim=analogRead(POT_AIM_PIN);
 float deg=map(rawAim,0,1023,165,15);
 float rad=deg*3.14159/180.0;

 int cur=digitalRead(BUTTON_PIN);
 if(lastButtonState==HIGH&&cur==LOW&&!bulletActive){
  bulletActive=true;bulletX=64;bulletY=52;
  float s=4.5; bulletVx=s*cos(rad); bulletVy=-s*sin(rad);
 }
 lastButtonState=cur;

 if(bulletActive){
  bulletX+=bulletVx; bulletY+=bulletVy;
  if(bulletX<0||bulletX>128||bulletY<12||bulletY>64) bulletActive=false;
  for(int i=0;i<3;i++) if(targets[i].active){
    float dx=bulletX-targets[i].x,dy=bulletY-targets[i].y;
    if(sqrt(dx*dx+dy*dy)<8){
      bulletActive=false;
      if(targets[i].value==correctAnswer){
        score+=10; feedbackMsg="CORRECT! +10"; feedbackTimer=millis(); generateNewQuestion();
      }else{
        score=max(0,score-5); wrongCount++; feedbackMsg="WRONG! -5"; feedbackTimer=millis(); targets[i].active=false;
        if(wrongCount>=3) gameOver=true;
      }
      break;
    }
  }
 }
 for(int i=0;i<3;i++) if(targets[i].active){
   targets[i].x+=targets[i].speed; 
   if(targets[i].x<10||targets[i].x>118) targets[i].speed*=-1;
   
 }

 display.clearDisplay();
 display.setTextSize(1); 
 display.setTextColor(SSD1306_WHITE);
 display.setCursor(2,2); 
 display.print(numA); 
 display.print(" "); 
 display.print(opSymbol); 
 display.print(" ");
 display.print(numB); 
 display.print("=?");
 display.setCursor(80,2);
 display.print("P:");
 display.print(score);
 display.setCursor(2,54); 
 display.print("W:"); 
 display.print(wrongCount); 
 display.print("/3");
 display.drawLine(0,11,127,11,SSD1306_WHITE);
 for(int i=0;i<3;i++) if(targets[i].active){
  int tx=targets[i].x,ty=targets[i].y;
  display.drawCircle(tx,ty,7,SSD1306_WHITE);
  display.setCursor(tx-(targets[i].value>9?5:2),ty-3); 
  display.print(targets[i].value);
 }
 int x2=64+12*cos(rad),y2=58-12*sin(rad);
 display.drawLine(64,58,x2,y2,SSD1306_WHITE); 
 display.fillCircle(64,60,4,SSD1306_WHITE);
 if(bulletActive) display.fillCircle((int)bulletX,(int)bulletY,2,SSD1306_WHITE);
 if(millis()-feedbackTimer<1000 && feedbackMsg!="")
 {
   
   display.fillRect(14,24,100,16,SSD1306_WHITE);
   display.setTextColor(SSD1306_BLACK); 
   display.setCursor(22,28); 
   display.print(feedbackMsg);
 }
 display.display();
 delay(20);
}

Credits

max
4 projects • 3 followers
Electronic hobbyist

Comments