JianWei Lee
/
project_game
Meteor defense project
Diff: Weapon/Weapon.cpp
- 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