Meteor defense project

Dependencies:   N5110 mbed

Revision:
50:082feedcdd22
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Weapon/Weapon.cpp	Thu May 04 16:55:26 2017 +0000
@@ -0,0 +1,542 @@
+#include "Weapon.h"
+
+Weapon::Weapon()
+{
+
+}
+
+Weapon::~Weapon()
+{
+
+}
+void Weapon::init() { //the wonderful thing about structs.
+    //printf("ld = %d, bd = %d, br = %d, bc = %d, dd = %d, dr = %d, sc = %d, srr = %d \n",laser.damage, bomb.damage, bomb.range, bomb.cooldown, drone.damage, drone.range, shield.capacity, shield.regenRate);
+    _bombRange = 10 + 2 * bomb.range ;
+    _laserDamage = 8 + laser.damage * 4;
+    _bombDamage = 40 + bomb.damage * 10;
+    _bombCooldown = 70 - bomb.cooldown * 5;
+    _shieldCapacity = 80 + shield.capacity * 50; 
+    _shieldRegenRate = 4 + shield.regenRate;
+    _droneDamage = 1 + drone.damage;
+    _droneRange = 30 + drone.range;
+    _cannonDamage = 20 + 10 * cannon.damage;
+    _cannonCapacity = 1280 + 320 * cannon.capacity;
+    _cannonRegenRate = 4 + cannon.regenRate;
+    //printf("bombRange = %d \n",_bombRange);
+    //printf("shield init complete \n");
+} 
+void Weapon::droneInit(int x, int y, int a, int b, int damage, int range){
+    d_x = x;
+    d_y = y;
+    d_side = a;
+    d_scan = b;
+    _droneDamage = damage;
+    _droneRange = range;
+    //printf("drone.damage = %d, drone.range = %d \n",drone.damage.drone.range);
+    //printf("actual drone damage = %d, drone range = %d \n",_droneDamage,_droneRange);
+    //printf("drone init done");
+}
+void Weapon::drawPlayer(Gamepad &pad, N5110 &lcd){
+        float angle = pad.get_direction();
+        int lala = pad.get_angle();
+        //printf("Direction = %f, Magnitude = %f \n",angle,mag);
+        //player position - fixed.
+        lcd.drawRect(42,46,3,2,FILL_BLACK);
+        //weapon position
+        if (angle == 0) { //
+            //printf("do nothing \n");
+        } else if (angle == 1) {
+            lcd.setPixel(43,45); lcd.setPixel(43,44);
+        } else if (angle == 2 ) {
+            lcd.setPixel(45,45); lcd.setPixel(46,44);
+        } else if (angle == 8){
+            lcd.setPixel(41,45); lcd.setPixel(40,44);
+        } else if (angle == 7){
+            lcd.setPixel(41,46); lcd.setPixel(40,46);
+        } else if (angle == 3){
+            lcd.setPixel(45,46); lcd.setPixel(46,46);
+        } 
+}       
+void Weapon::weaponMath(Gamepad &pad) {
+    //_laserDamage = 8 + var.laserDamage * 2;
+    //if button A is pressed. shoot laser 
+    int joyangle = pad.get_angle();
+    Vector2D mapped_coord = pad.get_mapped_coord();
+    //printf("mapped coord = %f, %f\n",mapped_coord.x,mapped_coord.y);
+    //printf("pad.get_angle = %d \n",joyangle);
+
+    //calculate the gradient of line 
+    m = mapped_coord.y / mapped_coord.x ;
+    int x1 = 43;
+    int y1 = 46;
+    //printf("m = %f \n",m);
+    //calculate the y-intercept of the line 
+    c = y1 + m * x1;  
+}
+void Weapon::laser_Main(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    //screen is divided into 4 parts for better line resolution 
+    //and gradient sign is always changing.
+    if ( m > 1) {
+        laser1and4(Arr2, cArr2, lcd);        
+    }
+    else if (m > 0){
+        laser2(Arr2, cArr2, lcd);
+    }
+    else if ( m > -1 ){
+        laser3(Arr2, cArr2, lcd);
+    } 
+    else if (m < -1){
+        laser1and4(Arr2, cArr2, lcd);
+    }   
+    lineBreak = 0;
+}       
+void Weapon::laser1and4(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    for (int y = 46; y > 0; y--) {
+        //draw straight line 
+        x = -(y - c)/m; 
+        lcd.setPixel(x,y);
+        if( cArr2[x-1][y-1] == 'r' || cArr2[x+1][y-1] == 'l' ) {
+            laser_detectSpawnC(x, y, Arr2, cArr2, lcd);
+        } else {   
+            laser_detectSpawn(x, y, Arr2, lcd);
+        }
+        if (lineBreak == 1) {
+            break;
+        }
+    }
+    
+    //printf("Part 1 is drawing line \n");
+}
+void Weapon::laser2(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    for (int x = 43; x < 83; x++) {
+        //draw straight line 
+        y = -m * x + c;
+        lcd.setPixel(x,y);
+        if( cArr2[x-1][y-1] == 'r' || cArr2[x+1][y-1] == 'l' ) {
+            laser_detectSpawnC(x, y, Arr2, cArr2, lcd);
+        } else {   
+            laser_detectSpawn(x, y, Arr2, lcd);
+        }
+        if (lineBreak == 1) {
+            break;
+        }
+    }
+    //printf("Part 2 is drawing line \n"); 
+}
+void Weapon::laser3(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    for (int x = 43; x > 0; x--) {
+        //draw a straight line for the laser
+        y = -m * x + c;
+        lcd.setPixel(x,y);
+        if( cArr2[x-1][y-1] == 'r' || cArr2[x+1][y-1] == 'l') {
+            laser_detectSpawnC(x, y, Arr2, cArr2, lcd);
+        } else {   
+            laser_detectSpawn(x, y, Arr2, lcd);
+        }
+        if (lineBreak == 1) {
+            break;
+        }
+    }    
+    //printf("part 3 is drawing line \n");  
+}
+//this piece of code to stop drawing the line when a spawn is detected.
+//hit box of the laser is only 5 pixel.
+void Weapon::laser_detectSpawn(int i, int j, int Arr2[][Rows], N5110 & lcd) {
+    //printf("drawing at x= %d, y= %d \n",x,y);
+    if ( Arr2[i][j-1] > 0) {
+        //printf("spawn detected at x = %d, y= %d \n",i,j-1);
+        lineBreak = 1;
+        Arr2[i][j-1] = Arr2[i][j-1] - _laserDamage;
+    } else if (Arr2[i-1][j-1] > 0){
+        //printf("spawn detected at x = %d, y= %d \n",i-1,j-1);
+        lineBreak = 1;
+        Arr2[i-1][j-1] = Arr2[i-1][j-1] - _laserDamage;
+    } else if (Arr2[i+1][j-1] > 0) {
+        //printf("spawn detected at x = %d, y= %d \n",i+1,j-1);
+        lineBreak = 1;
+        Arr2[i+1][j-1] = Arr2[i+1][j-1] - _laserDamage;
+    } else if (Arr2[i+1][j] > 0) {
+        lineBreak = 1;
+        Arr2[i+1][j] = Arr2[i+1][j] - _laserDamage;
+    } else if (Arr2[i-1][j] > 0) {
+        lineBreak = 1;
+        Arr2[i-1][j] = Arr2[i-1][j] - _laserDamage;
+    }
+}    
+void Weapon::laser_detectSpawnC(int i, int j, int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    //printf("either L or R is  detected \n");
+    if (cArr2[i+1][j-1] == 'l'){
+        //printf("cArr2[%d][%d] = %c \n",i+1,j-1,cArr2[i+1][j-1]);
+        lineBreak = 1;
+        Arr2[i+2][j] = Arr2[i+2][j] - _laserDamage; 
+        //printf("L found \n");
+    } else if (cArr2[i-1][j-1] == 'r') {
+        //printf("cArr2[%d][%d] = %c \n",i-1,j-1,cArr2[i-1][j-1]);
+        lineBreak = 1;
+        Arr2[i-2][j] = Arr2[i-2][j] - _laserDamage;
+        //printf("R found \n");
+    } 
+}
+void Weapon::bomb_main(int Arr2[][Rows], Gamepad &pad, N5110 &lcd) {
+    if (_bomb < _bombCooldown) {
+        //printf("bomb not ready yet \n");
+        _bomb += 1;
+        int cd = 3 + ((30* _bomb) / _bombCooldown); 
+        for (int x = 3; x < cd; x++) { //draw a line 
+            lcd.setPixel(x,47);
+        }    
+    } else { //allow bomb when cooldown is done.
+        //printf("bomb is ready to detonate \n");
+        for (int x = 3; x < 34; x++) { //draw a line 
+            lcd.setPixel(x,47);
+        }
+        checkBombTarget(pad);
+        if (bombTarget_flag == 1) {
+            drawBombTarget(pad, lcd);
+            if (pad.check_event(Gamepad::X_PRESSED)) {
+                spawnDamageByBomb(Arr2, lcd);
+            }
+        }
+    }
+}
+void Weapon::checkBombTarget(Gamepad &pad) {
+    if (pad.check_event(Gamepad::L_PRESSED)) { //press L button to toggle flag
+        if (bombTarget_flag == 1) {
+            //printf("button L pressed and flag toggled \n");
+            bombTarget_flag = 0;
+        } else if(bombTarget_flag == 0) {
+            bombTarget_flag = 1;
+        }
+    }
+}
+Target Weapon::targetCoord(Gamepad &pad) {
+    Vector2D coord = pad.get_coord();
+    //coord is used instead of mappedcoord because the bomb has to be able to go to the screen corner
+    int yy = 24 - coord.y * 24;
+    int xx = 42 + coord.x * 42;
+    
+    Target _coord = {xx,yy};
+    return _coord;
+}
+void Weapon::drawBombTarget(Gamepad &pad, N5110 &lcd) {
+    Target _coord = targetCoord(pad); //get the coordinate on the screen.
+    _y = _coord.yy;
+    _x = _coord.xx;
+    //draw a "+" on the screen using the coordinate for the target
+    lcd.setPixel(_x,_y);
+    lcd.setPixel(_x+1,_y);
+    lcd.setPixel(_x-1,_y);
+    lcd.setPixel(_x,_y+1);
+    lcd.setPixel(_x,_y-1);    
+}
+void Weapon::spawnDamageByBomb(int Arr2[][Rows], N5110 &lcd){ //draw the bombed area and deal damage to the area when X is pressed.
+    _bomb = 0; 
+    bombTarget_flag = 0; //clear flag
+    //printf("why u not working now?? omg \n");
+    //printf("x = %d, y = %d, bombRange = %d \n",a,b,r);
+    printf("bombRange = %d \n",_bombRange);
+    _bombRange = 10 + bomb.range ;
+    int a = _x; //a and b is the origin of the circle, 
+    int b = _y;
+    int r = _bombRange; //r is radius of circle
+    int c2 = r * r; 
+    int x2 = a + r +1;
+    int y2 = b + r +1;
+    
+    drawCircle(a, b, r, c2, x2, y2, Arr2, lcd);
+    //printf("bomb detonated \n");
+}
+void Weapon::drawCircle(int a, int b, int r, int c2, int x2, int y2, int Arr2[][Rows], N5110 &lcd) { 
+    //had to use this instead of lcd.drawcircle because it has to be able to manipulate the array.
+    //find all the coordinate in a square depending on the radius of circle.
+    for (int x1 = a - r; x1 < x2; x1 ++){
+        for (int y1 = b - r; y1 < y2; y1 ++) {
+            //this code because when y1 get negative. The game crash.
+            int x3 = x1; int y3 = y1;
+            if (y3 < 0) {
+                y3 = 40;
+            } if (x3 < 0) {
+                x3 = 40;
+            }
+            int a2 = (x3 - a) * (x3 - a);
+            int b2 = (y3 - b) * (y3 - b);
+            if (a2 + b2 <= c2 +1) { //if the coordinate is within the circle ( c2 = a2 + b2 )
+                //draw circle and deal damage to it .
+                lcd.setPixel(x3,y3);
+                Arr2[x3][y3] = Arr2[x3][y3] - _bombDamage;
+            }
+        }
+    }        
+}
+void Weapon::shield_main(int Arr2[][Rows], char cArr2[][Rows], Gamepad &pad, N5110 &lcd) {
+    if (pad.buttonhold_B == 1) { //if B pressed, generate shield. Shield doesnt have to be fully charged to be activated
+        if (_shield > 0) { //shield will only activate if the shield has not depleted.
+            shield_Rule(Arr2, cArr2, lcd);
+        } else { //or else, deactivate the shield and recharge the shield.
+            pad.buttonhold_B = 0;
+        }    
+    } 
+    if (pad.buttonhold_B == 0) { // recharge shield 
+        if (_shield < _shieldCapacity ) {
+            _shield = _shield + _shieldRegenRate;
+            //printf("current shield = %d \n",weap._shield); 
+            //printf("shield regen rate = %d \n",weap._shieldRegenRate);
+        } else { //when the shield is fully charged. It will automatically activate the shield.
+                pad.buttonhold_B = 1;
+        }
+    }
+    shieldMeter(lcd);
+}
+void Weapon::shield_Rule(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    drawEnergyShield(lcd);
+    for (int x = 0; x < Cols; x++) { //from x = 0 to x = 83
+        if (cArr2[x][45] == 'b') { //scan for spawn B
+            Arr2[x][45] = 0;
+            cArr2[x][45] = '\0';
+            _shield -= 20;
+        } else if ( cArr2[x][45] == 'd' || cArr2[x][45] == 'e' ) { //scan for spawn D&E
+            Arr2[x][45] = 0;
+            cArr2[x][45] = '\0';
+            _shield -= 30;
+        }
+    }  
+}
+//draw a simple barrier at y = 45
+void Weapon::drawEnergyShield(N5110 &lcd) {
+    for (int x = 0; x < Cols; x++) {
+        lcd.setPixel(x,45);    
+    }
+    for (int x = 0; x < Cols; x += 3) {
+        lcd.setPixel(x,44);
+    }    
+}
+void Weapon::shieldMeter(N5110 &lcd) {
+    int cd = 50 + ((30 * _shield) / _shieldCapacity); 
+    lcd.drawLine(50,47,cd,47,1);    
+}
+void Weapon::drone_main(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    lcd.setPixel(d_x,d_y);
+    //prioritize spawn D&E
+    droneScanForDE(Arr2, cArr2, lcd);
+    if (d_foundDE == 0) {
+        droneScanForAB(Arr2, cArr2, lcd);    
+    }
+    d_foundDE = 0;
+}
+void Weapon::droneScanForAB(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    for (int y = d_y; y > d_y - _droneRange; y--) { //scan through the given drone range from left to right
+        for (int x = d_side; x < d_scan; x++) {
+            if (cArr2[x][y] == 'a' || cArr2[x][y] == 'c') { //if detect something
+                //printf("drone detected spawn A/C at x = %d, y = %d \n",x ,y);
+                droneLaser(x, y, Arr2, cArr2, lcd);
+                Arr2[x][y] = Arr2[x][y] - _droneDamage;
+                breakout = 1;
+                break; //break out of the first for loop.  
+            } 
+        }
+        if (breakout == 1){
+            breakout = 0;
+            break; //break out of the second for loop.
+        }
+    }
+}
+void Weapon::droneScanForDE(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) { //drone prioritize in killing spawnDE
+    for (int y = d_y; y > d_y - _droneRange; y--) { //scan through the given drone range from left to right
+        for (int x = d_side; x < d_scan; x++) {
+            if (cArr2[x][y] == 'd' || cArr2[x][y] == 'e') { //if detect something
+                //printf("drone detected spawn D&E at x = %d, y = %d \n",x ,y);
+                droneLaser(x, y, Arr2, cArr2, lcd);
+                Arr2[x][y] = Arr2[x][y] - _droneDamage;
+                breakout = 1;
+                d_foundDE = 1;
+                break; //break out of the first for loop.  
+            } 
+        }
+        if (breakout == 1){
+            breakout = 0;
+            break; //break out of the second for loop.
+        }
+    }
+}
+void Weapon::droneLaser(int x, int y, int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) { //this is used to draw line (laser) for the drone
+    float m;
+    if ( x != d_x) { //to prevent m (gradient) from going to infinity.
+        m = (((float)y) - d_y) / (((float)x) - d_x); //to get the gradient of the line. y = mx + c
+    } else {
+        m = 50; //50 is more than enough since screen height is only 48 pixel.
+    }
+    int c = d_y - m * d_x; // y-intercept of the line
+    //printf("y intercept = %d and gradient = %f \n",c,m);
+    /*int lala = x - d_x;
+    if ( lala == 0 ) { 
+        printf("m = %d at x = %d \n",m,x);
+    }*/
+    for (int j = d_y ; j > y ; j--) { 
+        int i = (j - c) / m;
+        lcd.setPixel(i,j);
+    }          
+}
+void Weapon::cannon_main(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) { //dividing the screen into 4 parts like the laser 
+    //printf("cannonFiring_flag = %d, cannon_y = %d, cannon_x = %d \n",cannonFiring_flag,cannon_y,cannon_x);
+    if ( cannonFiring_flag == 0) { //save the current gradient and also the y-intercept
+        cannonDirection = m;
+        cannon_c = c;
+        cannon_y = 46; //initial pos of cannon
+        cannon_x = 43;
+        cannonFiring_flag = 1;
+        cannon_Damage =  _cannonDamage;
+        _cannon = _cannon - 320; //each cannon clip costs 320.
+        //printf("firing a new cannon \n");
+    }
+    //dividing the screen into 4 parts like the laser
+    if ( cannonFiring_flag == 1) { //cannon fired   
+        if ( cannonDirection > 1) {  
+            cannon1and4(Arr2, cArr2, lcd); 
+        }
+        else if ( cannonDirection > 0){
+            cannon2(Arr2, cArr2, lcd); 
+        }
+        else if ( cannonDirection > -1 ){
+            cannon3(Arr2, cArr2, lcd);
+        } 
+        else if ( cannonDirection < -1){
+            cannon1and4(Arr2, cArr2, lcd); 
+        }   
+    }
+}
+void Weapon::cannon1and4(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    if ( cannon_y > 0 ) {
+        cannon_y --;
+        //printf("printing cannonball at (%d,%d) \n",x,cannon_y);
+        int x = -(cannon_y - cannon_c) / cannonDirection;
+        draw_CannonBall(x, cannon_y, lcd);
+        //search for spawn A, B and C
+        cannon_HitBox(x, cannon_y, Arr2, cArr2);    
+    } else {
+        cannonFiring_flag = 0;
+        //printf("cannon1and4 is done \n");    
+    }
+}
+void Weapon::cannon2(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    if ( cannon_x < 83 ) {
+        cannon_x ++;
+        int y = - cannonDirection * cannon_x + cannon_c;
+        //printf("printing cannonball at (%d,%d) \n",cannon_x,y);
+        draw_CannonBall(cannon_x, y, lcd);
+        //search for spawn A, B and C.
+        cannon_HitBox(cannon_x, y, Arr2, cArr2);  
+    } else {
+         cannonFiring_flag = 0;
+        //printf("cannon2 is done \n");    
+    }
+}
+void Weapon::cannon3(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd) {
+    if ( cannon_x > 0 ) {
+        cannon_x --;
+        int y = - cannonDirection * cannon_x + cannon_c;  
+        //printf("printing cannonball at (%d,%d) \n",cannon_x,y);
+        draw_CannonBall(cannon_x, y, lcd); 
+        //search for spawn A, B and C.
+        cannon_HitBox(cannon_x, y, Arr2, cArr2);    
+    } else {
+        cannonFiring_flag = 0;
+        //printf("cannon3 is done \n");    
+    }
+}
+void Weapon::cannon_HitBox(int i, int j, int Arr2[][Rows], char cArr2[][Rows]) {
+    for (int x = i - 4; x < i + 5; x ++) {
+        for (int y = j - 4; y < j + 5; y ++) {
+            if (cannon_Damage > 0 ) { //if cannon can still deal damage, continue search for spawn
+                if (cArr2[x][y] == 'a') {
+                    cannon_Damage = cannon_Damage - 2; 
+                    Arr2[x][y] = 0;
+                    cArr2[x][y] = '\0';   
+                }
+                if (cArr2[x][y] == 'b') {
+                    cannon_Damage = cannon_Damage - 5;
+                    Arr2[x][y] = 0;
+                    cArr2[x][y] = '\0';
+                }
+                if (cArr2[x][y] == 'c') {
+                    cannon_Damage = cannon_Damage - 5;
+                    Arr2[x][y] = 0;
+                    cArr2[x][y] = '\0';
+                }
+            } else { //if the cannon cant deal any more damage, terminate search and clear flag
+                cannonFiring_flag = 0; 
+                break;   
+            }
+        }
+    }
+}
+void Weapon::cannon_recharge() {
+    if ( _cannon < _cannonCapacity ) {
+        _cannon = _cannon + _cannonRegenRate;
+    }    
+    //printf("_cannon = %d \n",_cannon);
+} 
+void Weapon::cannon_Meter(N5110 &lcd) {
+    float zz = 83 * ( ((float)_cannon) / _cannonCapacity) ; 
+    //printf(" zz = %f \n",zz);
+    for ( int x = 0 ; x < zz; x ++) {
+        lcd.setPixel(x,0);
+    }
+}
+void Weapon::draw_CannonBall(int x, int y, N5110 &lcd) {
+    //draw a diamond shape 
+    lcd.setPixel(x-1,y-1); lcd.setPixel(x,y-1); lcd.setPixel(x+1,y+1);
+    lcd.setPixel(x-1,y);   lcd.setPixel(x,y);   lcd.setPixel(x+1,y);
+    lcd.setPixel(x-1,y+1); lcd.setPixel(x,y+1); lcd.setPixel(x+1,y-1);
+    lcd.setPixel(x-2,y);   lcd.setPixel(x+2,y); 
+    lcd.setPixel(x,y+2);   lcd.setPixel(x,y-2);
+}
+void Weapon::setVar(int up, int up1) {
+    //printf("HI, ME FROM WEAP. up = %d, up1 = %d \n",up,up1); 
+    if (up == 0){  //if laser picked 
+        laser.damage ++;
+    } else if (up == 1) { //if bomb picked
+        if (up1 == 0) {
+            bomb.damage ++;
+        } else if (up1 == 1) {
+            bomb.range ++;
+        } else {
+            bomb.cooldown++;
+        }
+    } else if (up == 2) { //if drone picked
+        if (up1 == 0) {
+            drone.damage++;
+        } else {
+            drone.range++;
+        }
+    } else if (up == 3) { //if shield picked 
+        if (up1 == 0) {
+            shield.capacity ++;
+        } else {
+            shield.regenRate ++;
+        }
+    } else if (up == 4) { //if cannon picked
+        if (up1 == 0) {
+            cannon.damage ++;
+        } else if (up1 == 1) {
+            cannon.capacity ++;
+        } else if (up1 == 2) {
+            cannon.regenRate ++;
+        }
+    }
+} 
+void Weapon::reset_WeaponVariables() { 
+    laser.damage = 0;
+    bomb.damage = 0;
+    bomb.range = 0;
+    bomb.cooldown = 0;
+    drone.damage = 0;
+    drone.range = 0;
+    shield.capacity = 0;
+    shield.regenRate = 0;
+    bomb.damage = 0;
+    bomb.capacity = 0;
+    bomb.regenRate = 0;
+    _cannon = 0;
+    _shield = 0;
+    _bomb = 0;
+}
\ No newline at end of file