JianWei Lee
/
project_game
Meteor defense project
Revision 50:082feedcdd22, committed 2017-05-04
- Comitter:
- jasper0712
- Date:
- Thu May 04 16:55:26 2017 +0000
- Parent:
- 49:bf802df54786
- Commit message:
- converted library to folder
Changed in this revision
--- a/GUI.lib Thu May 04 11:55:00 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://developer.mbed.org/users/jasper0712/code/GUI/#9b1c738ef191
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GUI/GUI.cpp Thu May 04 16:55:26 2017 +0000 @@ -0,0 +1,220 @@ +#include "GUI.h" + + +GUI::GUI() +{ + +} + +GUI::~GUI() +{ + +} +void GUI::startingMenu(N5110 &lcd) { + lcd.printString("Meteor defense",0,0); + lcd.printString("Press start",10,2); + lcd.printString("to play",10,3); + lcd.printString("by Lee.",48,5); +} +void GUI::upgrades(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, Gamepad &pad, N5110 &lcd) { + printf("test struct passing %d %d %d %d %d %d %d %d \n",a,b,c,d,e,f,g,h); + Cursors _cursor = cursor(pad); + if (pointsGiven == 0){ //if upgrade points are not yet given + pointsUpgrade += 2; //give the points + pointsGiven = 1; + } + if (upgrading1_flag == 0) { //main upgrades page + main_UpgradesPage(lcd); + cursor_y = _cursor.number_y; + drawCursor(cursor_y, lcd); + printf("cursor_y = %d \n",cursor_y); + } else { //weapon picked + cursor_y1 = _cursor.number_y; + drawCursor(cursor_y1, lcd); + //picking weapon's variables + if (cursor_y == 0){ + //printf("laser selected \n"); + laser_UpgradesPage(a, lcd); + } else if (cursor_y == 1){ + //printf("bomb selected \n"); + bomb_UpgradesPage(b, c, d, lcd); + cursor_y = 1; + } else if (cursor_y == 2){ + //printf("drone selected \n"); + drone_UpgradesPage(e, f, lcd); + } else if (cursor_y == 3){ + //printf("shield selected \n"); + shield_UpgradesPage(g, h, lcd); + } else if (cursor_y == 4) { + cannon_UpgradesPage(i, j, k, lcd); + cursor_y = 4; + } + if (pad.check_event(Gamepad::BACK_PRESSED)) { //if back button is pressed + upgrading1_flag = 0; //back to the main_upgrades. + cc = 0; // reset the cursor + } + upgradesData(pad); + } + pad_events(pad); +} +void GUI::pad_events(Gamepad &pad) { + if (pad.check_event(Gamepad::A_PRESSED)) { //if A button is pressed + upgrading1_flag = 1; //go into the weapons picked. + cc = 0; //reset the cursor + pad.tone(750.0,0.1); + preventDoubleClick(pad); + } + if (pointsUpgrade == 0) { // when no more points available + if (pad.check_event(Gamepad::START_PRESSED)) { //pressing start will complete the upgrades + pointsGiven = 0; + saveTheData_flag = 1; + preventDoubleClick(pad); + } + } +} +void GUI::upgradesData(Gamepad &pad) { + //printf("p = %d \n",pointsUpgrade); + if (pointsUpgrade == 2) { //if there are 2 points remaining + if (pad.check_event(Gamepad::A_PRESSED)) { //if A button is pressed inside the weapons picked. + pointsUpgrade -= 1; // minus an upgrade point + upgradePicked = cursor_y; //saving upgrades data + upgradePicked1 = cursor_y1; + pad.tone(750.0,0.1); + preventDoubleClick(pad); + //printf("p = %d, upgradePicked = %d, upgradePicked1 = %d \n",pointsUpgrade,upgradePicked,upgradePicked1); + } + } else if (pointsUpgrade == 1) { + if (pad.check_event(Gamepad::A_PRESSED)) { //if A button is pressed inside the weapons picked. + pointsUpgrade -= 1; // minus an upgrade point + upgrade1Picked = cursor_y; //saving upgrades data + upgrade1Picked1 = cursor_y1; + pad.tone(750.0,0.1); + preventDoubleClick(pad); + //printf("p = %d, upgrade1Picked = %d, upgrade1Picked1 = %d \n",pointsUpgrade,upgrade1Picked,upgrade1Picked1); + } + } else if (pointsUpgrade == 0) {//if no more points left, bring the player back to main upgrade page + upgrading1_flag = 0; + } +} +void GUI::main_UpgradesPage(N5110 &lcd) { + options = 4; // 0, 1, 2, 3 + sprintf(pointsRemaining, "Points : %d",pointsUpgrade); + lcd.printString(pointsRemaining,1,0); + lcd.printString("Laser",10,1); //option 0 + lcd.printString("Bomb",10,2); //option 1 + lcd.printString("Drone",10,3); //option 2 + lcd.printString("Shield",10,4); //option 3 + lcd.printString("Cannon",10,5); //option 4 + if (pointsUpgrade == 0) { //if no more points left. + lcd.printString("Done",57,5); + } +} +void GUI::laser_UpgradesPage(int laserDamage, N5110 &lcd) { + options = 0; + sprintf(upgrade1, "Damage %d", laserDamage); + lcd.printString("Laser",1,0); + lcd.printString(upgrade1,10,1); +} +void GUI::bomb_UpgradesPage(int bombDamage, int bombR, int bombCooldown, N5110 &lcd) { + options = 2; + sprintf(upgrade1, "Damage %d", bombDamage); + sprintf(upgrade2, "Radius %d", bombR); + sprintf(upgrade3, "Cooldown %d", bombCooldown); + lcd.printString("Bomb",1,0); + lcd.printString(upgrade1,10,1); + lcd.printString(upgrade2,10,2); + lcd.printString(upgrade3,10,3); +} +void GUI::drone_UpgradesPage(int droneDamage, int droneRange, N5110 &lcd) { + options = 1; + sprintf(upgrade1, "Damage %d", droneDamage); + sprintf(upgrade2, "Atk Range %d", droneRange); + lcd.printString("Drone",1,0); + lcd.printString(upgrade1,10,1); + lcd.printString(upgrade2,10,2); +} +void GUI::shield_UpgradesPage(int shieldCapacity, int shieldRegenRate, N5110 &lcd) { + options = 1; + sprintf(upgrade1, "Cpcty %d", shieldCapacity); + sprintf(upgrade2, "RegenRate %d", shieldRegenRate); + lcd.printString("Shield",1,0); + lcd.printString(upgrade1,10,1); + lcd.printString(upgrade2,10,2); +} +void GUI::cannon_UpgradesPage(int cannonDamage, int cannonCapacity, int cannonRegenRate, N5110 &lcd) { + options = 2; + sprintf(upgrade1, "Damage %d", cannonDamage); + sprintf(upgrade2, "Cpcty %d", cannonCapacity); + sprintf(upgrade3, "RegenRate %d", cannonRegenRate); + lcd.printString("Cannon",1,0); + lcd.printString(upgrade1,10,1); + lcd.printString(upgrade2,10,2); + lcd.printString(upgrade3,10,3); +} +Data GUI::get_data() { + Data sd = {upgradePicked, + upgradePicked1, + upgrade1Picked, + upgrade1Picked1, + }; + return sd; +} +Cursors GUI::cursor(Gamepad &pad) { + Vector2D coordinate = pad.get_coord(); + float y = coordinate.y; + //printf(" y = %f \n",y); + if (y < -0.8f) { + printf("going down \n"); + if (cc < options) { + cc += 1; + //printf("cc = %d \n",cc); + while (1) { + //printf("release joystick pls."); + //printf("cc = %d \n",cc); + wait(0.1); + Vector2D coordinate = pad.get_coord(); + float y = coordinate.y; + if (y > -0.1f) { + break; // when joystick released. break out of this while loop. + } + } + } + } + if (y > 0.8f) { + printf("going up \n"); + if (cc > 0) { + cc -= 1; + //("cc = %d /n",cc); + while (1) { + //printf("release joystick pls. "); + //printf("cc = %d /n",cc); + wait(0.1); + Vector2D coordinate = pad.get_coord(); + float y = coordinate.y; + if (y < 0.1f) { + break; //when joystick released. break out of this while loop. + } + } + } + } + Cursors _cursor = {cc}; + return _cursor; +} +void GUI::drawCursor(int Cy, N5110 &lcd){ //simple square cursor + lcd.setPixel(4,11 + Cy * 8); + lcd.setPixel(5,11 + Cy * 8); + lcd.setPixel(4,12 + Cy * 8); + lcd.setPixel(5,12 + Cy * 8); +} +void GUI::preventDoubleClick(Gamepad &pad) { //use this to prevent unintended double clicking that always happens with the gamepad + wait(0.1); //yes, the gamepad is that bad. + if (pad.check_event(Gamepad::A_PRESSED)) { + printf("A double click prevented!!! \n"); + } + if (pad.check_event(Gamepad::START_PRESSED)) { + printf("START double click prevented!!! \n"); + } + if (pad.check_event(Gamepad::BACK_PRESSED)) { + printf("BACK double click prevented!!! \n"); + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GUI/GUI.h Thu May 04 16:55:26 2017 +0000 @@ -0,0 +1,125 @@ +#ifndef GUI_H +#define GUI_H + +#include "mbed.h" +#include "N5110.h" +#include "Gamepad.h" +#include "Weapon.h" +#include "Spawn.h" + +//position of cursor +struct Cursors { + int number_y; + int number_x; +}; + +//struct to store the ugprade data +struct Data { + int up; + int up1; + int u1p; + int u1p1; +}; + +/** GUI Class +@brief User interface class for the game +@author JianWei Lee +@date April 2017 +*/ +class GUI +{ + + +public: + GUI(); + ~GUI(); + + /**Starting Menu Strings + * + *Few strings to be printed on the lcd before starting the game + */ + void startingMenu(N5110 &lcd); + + + /**Weapon Upgrades + * + *@brief 2 points will be given for upgrades\n + *@brief Start button to enter the upgrade page\n + *@brief Press button A to select\n + *@brief After spending 2 points, press Start button again to continue game\n + *@param a - laser damage + *@param b - bomb damage + *@param c - bomb radius + *@param d - bomb cooldown + *@param e - drone damage + *@param f - drone range + *@param g - shield capacity + *@param h - sheild regenerative rate + *@param i - cannon damage + *@param j - cannon capacity + *@param k - cannon regenerative rate + */ + void upgrades(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, Gamepad &pad, N5110 &lcd); + + /**Prevent pad double click + * + *@brief Double clicking always happens on the pad and it breaks the game \n + *@brief Clear off the event flag for unintended clicks + */ + void preventDoubleClick(Gamepad &pad); + + /**Get Upgrades Data + * + *@brief The weapon that is upgraded will be saved in the struct Data using numbers \n + *@brief Return weapon's number and variable's number. + */ + Data get_data(); + + int upgrading_flag; + int upgrading1_flag; + int saveTheData_flag; + + +private: + + int cc; + int options; + char pointsRemaining[10]; + char upgrade1[12]; + char upgrade2[12]; + char upgrade3[12]; + + + + int pointsUpgrade; + int pointsGiven; + int upgradePicked; + int upgradePicked1; + int upgrade1Picked; + int upgrade1Picked1; + + //function to move the cursor up and down + Cursors cursor(Gamepad &pad); + int cursor_y; + int cursor_y1; + //simply draw a square cursor depends on the cursor Y position + void drawCursor(int Cy, N5110 &lcd); + + //contains printstring in all the page + void main_UpgradesPage(N5110 &lcd); + void laser_UpgradesPage(int laserDamage, N5110 &lcd); + void bomb_UpgradesPage(int bombDamage, int bombR, int bombCooldown, N5110 &lcd); + void drone_UpgradesPage(int droneDamage, int droneRange, N5110 &lcd); + void shield_UpgradesPage(int shieldCapacity, int shieldRegenRate, N5110 &lcd); + void cannon_UpgradesPage(int cannonDamage, int cannonCapacity, int cannonRegenRate, N5110 &lcd); + + //save the upgrade data for later use in Weapon library + //and manage the upgrade points + void upgradesData(Gamepad &pad); + + //this to check the buttons pressed when upgrading weapon and play tone to notify player + void pad_events(Gamepad &pad); + +}; + +#endif \ No newline at end of file
--- a/Weapon.lib Thu May 04 11:55:00 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -https://developer.mbed.org/teams/ELEC2645-201617/code/Weapon/#d507e93458ce
--- /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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Weapon/Weapon.h Thu May 04 16:55:26 2017 +0000 @@ -0,0 +1,255 @@ +#ifndef WEAPON_H +#define WEAPON_H + +#include "mbed.h" +#include "N5110.h" +#include "Gamepad.h" +#include "Spawn.h" +#include "GUI.h" + +#define Rows 48 +#define Cols 84 + +//position of the bomb target +struct Target { + int xx; + int yy; +}; + +//to store the weapon level +struct Variables { + int damage; + int range; + int cooldown; + int capacity; + int regenRate; + +}; + +/** Weapon Class +@brief Library that contains the weapons for the game +@author JianWei Lee +@date April 2017 +*/ +class Weapon +{ +public: + Weapon(); + ~Weapon(); + + void init(); + + /**Draw player + * + *@brief Draw player on the screen at (43,46) \n + *@brief Draw the position of the weapon depending on the joystick direction + */ + void drawPlayer(Gamepad &pad,N5110 &lcd); + + /**Math calculation + * + *@brief It gets the gradient from gamepad and calculate y-intercept of the line using the player's position \n + *@brief The math is required for laser and cannon. + */ + void weaponMath(Gamepad &pad); + + /**Laser + * + *@brief The main code for laser \n + *@brief Button A to activate laser \n + *@brief The screen is divided into 4 parts for better line resolution and gradient changes in these different region \n + *@brief Laser can only deal damage to spawn A, C and DE. \n + *@brief Laser path will be blocked by spawn B. + *@param Arr2[][Rows] - deal damage to the spawn + *@param cArr2[][Rows] - to differentiate the spawns. + */ + void laser_Main(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + + /*Bomb + * + *@brief The main code for bomb \n + *@brief Button L to bring up the bomb target, button X to detonate bomb \n + *@brief Bomb deals damage to an area - area size depends on the bomb radius \n + *@brief A circle will be drawn on the area bombed. \n + *@brief Bomb can only deal damage to spawn A, C and DE. + *@param Arr2[][Rows] - deal damage to the array + */ + void bomb_main(int Arr2[][Rows], Gamepad &pad, N5110 &lcd); + + + + /**Shield + * + *@brief The main code for shield \n + *@brief Button B to activate/deactivate shield. \n + *@brief Shield covers the player from fast moving spawn (spawn B and D&E) at y = 45 \n + *@brief The shield will be deactivated when depleted and will only recharge when the shield is deactivated + *@param Arr2[][Rows] - deal damage to the spawn + *@param cArr2[][Rows] - to differentiate the spawns. + */ + void shield_main(int Arr2[][Rows], char cArr2[][Rows], Gamepad &pad, N5110 &lcd); + + + /**Initialise drone + * + *@brief Drone on left side pixel 0 to 42 \n + *@brief Drone on right side pixel 42 to 83 + *@param x - position x of drone + *@param y - position y of drone + *@param a - left border of the drone range + *@param b - right border of the drone range + *@param damage - damage of the drone + *@param range - range of the drone + */ + void droneInit(int x, int y, int a, int b, int damage, int range); + + /*Drone + * + *@brief The drone will automatically deal damage to spawn A, C and D&E with a given range \n + *@brief Drone will prioritize at attacking spawn D&E when it enters the drone range + */ + void drone_main(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + + + /**Cannon + * + *@brief Cannon only can be fired when laser is switched on (button Y) \n + *@brief Cannon can delete spawn A, B and C instantly on contact \n + *@brief It's damage indicate how many spawns it can collide with \n + *@brief The cannon has a fixed radius and travel at the same speed at spawn B \n + *@brief Cannon ammo is not unlimited and will recharge whenever the ammo is not full + */ + void cannon_main(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + + /**Cannon meter + * + *@brief An indicator for the remaining cannon ammo \n + *@brief Cannon ammo size can be upgraded + */ + void cannon_Meter(N5110 &lcd); + + /**Cannon recharge + * + *@brief Recharge cannon ammo whenever the cannon ammo is not full \n + *@brief Cannon recharge rate can be upgraded + */ + void cannon_recharge(); + + /**Set Variables + * + *@brief This code will be executed after weapon upgrades \n + *@brief Set the variables using numbers from GUI's struct + *@param up - weapon's number + *@param up1 - variable's number + */ + void setVar(int up, int up1); + + /**Clear weapon variables + * + *@brief To be used only when the player give up on the game. \n + *@brief All weapon variables are set to 0 + */ + void reset_WeaponVariables(); + + //these variable can be upgraded as the game progress + int _bombRange; + int _laserDamage; + int _bombDamage; + int _bombCooldown; + int _shieldCapacity; + int _shieldRegenRate; + int _droneDamage; + int _droneRange; + int _cannonDamage; + int _cannonCapacity; + int _cannonRegenRate; + + //these are used in game engine + int cannonFiring_flag; + int _cannon; + +private: + //structs + Variables laser; + Variables bomb; + Variables drone; + Variables shield; + Variables cannon; + + //Laser + int c; + int y; + int x; + float m; + int _x; + int _y; + int lineBreak; + //screen divided into 4 parts + void laser1and4(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + void laser2(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + void laser3(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + //look for spawn A, B, C and D&E + void laser_detectSpawn(int i, int j, int Arr2[][Rows], N5110 &lcd); + //to give C a larger hitbox + void laser_detectSpawnC(int i, int j, int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + + //drone + int breakout; + int d_x; + int d_y; + int d_side; //which side the drone is at. 0 for left side. 42 for right side. + int d_scan; + int d_foundDE; + //draw a line for laser + void droneLaser(int x, int y, int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + //drone scan for spawn A, B and D&E + void droneScanForAB(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + void droneScanForDE(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + + //cannon + float cannonDirection; + int cannon_y; + int cannon_x; + int cannon_c; + int cannon_Damage; + //screen divided into 4 parts + void cannon1and4(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + void cannon2(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + void cannon3(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + //draw cannon ball + void draw_CannonBall(int x, int y, N5110 &lcd); + //large cannon hit box + void cannon_HitBox(int i, int j, int Arr2[][Rows], char cArr2[][Rows]); + + + + + //bomb + int _bomb; + int bombTarget_flag; + //initialise bomb + void bombInit(); + //draw bomb target on screen + void drawBombTarget(Gamepad &pad, N5110 &lcd); + //the function to toggle bomb target flag + void checkBombTarget(Gamepad &pad); + //http://stackoverflow.com/questions/17163636/filled-circle-in-matrix2d-array + //draw a circle on screen using pythagoras theorem + //and deal damage to the area + void drawCircle(int a, int b, int r, int c2, int x2, int y2, int Arr2[][Rows], N5110 &lcd); + void spawnDamageByBomb(int Arr2[][Rows], N5110 &lcd); + //struct to store bomb target's coordinate + Target targetCoord(Gamepad &pad); + + //shield + int _shield; + //Scan for spawn B and D&E and deletes them at y = 45. + void shield_Rule(int Arr2[][Rows], char cArr2[][Rows], N5110 &lcd); + //draw shield + void drawEnergyShield(N5110 &lcd); + void shieldMeter(N5110 &lcd); + +}; + +#endif + \ No newline at end of file