diff --git a/Accelerometer.cpp b/Accelerometer.cpp new file mode 100644 index 0000000..bae4d3a --- /dev/null +++ b/Accelerometer.cpp @@ -0,0 +1,72 @@ +/* + Draw.cpp - Library for flashing Morse code. + Created by David A. Mellis, November 2, 2007. + Released into the public domain. +*/ + +#include "Arduino.h" +#include "Accelerometer.h" + +// Use this pins for the Accelerometer axes +#define accelXpin A0 +#define accelYpin A1 +#define accelZpin A2 + +//-------------------Accelerometer variables----------------- +int posXShip,posYShip; +int xVoltage,yVoltage,zVoltage; +float xAcc,yAcc,zAcc,roll,pitch; +float scale=98; + +//Callibration values +int xZero=502; +int zZero=512; +int yZero=497; +//Sensitivity to detect direction +int sense=20; +//---------------------------------------------------------- + +void Accelerometer::readVoltage(){ + xVoltage=analogRead(accelXpin); + yVoltage=analogRead(accelYpin); + zVoltage=analogRead(accelZpin); +} + +void Accelerometer::getRollPitch(){ + xAcc=(xVoltage-xZero)/scale; + yAcc=(yVoltage-yZero)/scale; + zAcc=(zVoltage-zZero)/scale; + // apply trigonometry to get the pitch and roll: + pitch = atan(xAcc/sqrt(pow(yAcc,2) + pow(zAcc,2))); + roll = atan(yAcc/sqrt(pow(xAcc,2) + pow(zAcc,2))); + //convert radians into degrees + pitch = pitch * (180.0/PI); + roll = roll * (180.0/PI) ; +} + +int Accelerometer::isShaking(){ + readVoltage(); + getRollPitch(); + if(pitch>30||pitch<-30||roll>30||roll<-30){ + delay(500); + readVoltage(); + getRollPitch(); + if(pitch>30||pitch<-30||roll>30||roll<-30){ + return 0; + } + }else{ + return 1; + } +} + +int Accelerometer::getRoll(){ + readVoltage(); + getRollPitch(); + return roll; +} + +int Accelerometer::getPitch(){ + readVoltage(); + getRollPitch(); + return pitch; +} diff --git a/Accelerometer.h b/Accelerometer.h new file mode 100644 index 0000000..316fe90 --- /dev/null +++ b/Accelerometer.h @@ -0,0 +1,31 @@ +/* + Morse.h - Library for flashing Morse code. + Created by David A. Mellis, November 2, 2007. + Released into the public domain. +*/ +#ifndef Accelerometer_h +#define Accelerometer_h + +#include "Arduino.h" + + +class Accelerometer +{ + public: + /* + * Reads Voltage from accelerometer Pins + */ + void readVoltage(); + /* + * Does some fancy trigonometry in order to get roll/pitch from voltage readings + * We had to calibrate the accelereometer BEFORE applying maths + * Reference: http://physics.rutgers.edu/~aatish/teach/srr/workshop3.pdf + */ + void getRollPitch(); + int isShaking(); // Returns 1 if NOT shaking + int getPitch(); //Returns current pitch value + int getRoll(); //Returns current roll value + private: +}; +#endif + diff --git a/Arduino-Game-Console.ino b/Arduino-Game-Console.ino new file mode 100644 index 0000000..8223596 --- /dev/null +++ b/Arduino-Game-Console.ino @@ -0,0 +1,895 @@ +#include "Draw.h" // Implemented libraries +#include "Accelerometer.h" +#include // SD card libraries +#include + +Draw draw; // Draw object. Used to access functions in Draw.h +Accelerometer accelerometer; // Same as above, but for Accelerometer.h + +typedef enum{ // Current states of state machine + MENU, // Displays Main Menu + NEW, // Starts new game + HS, // Display High Score + CREDITS, // Display Credits + PLAY, // MAIN STATE when playing + GO, // Game Over Displays score and stats + SNEW, // Soft new game, starts new level without reseting the stats + SDS, // SD card start: reads scores from sd card file + NHS, // New high score: Starts user input for high score + INTRO, // Does intro + +}game_States; + +// SD card and file reading variables +File myFile; // Opened file +char bufferIn; // Buffer used to read from file +char namesScores[5][13];// 5 Strings for each line in the HS.txt file +char names[15]; // 5 strings for separating names from scores +int scores[5]; // Array used to separate scores from names as INT + +game_States cState; // current State +unsigned int score; // current game stats +char level, lifes; + +/* + * These two arrays are needed in order to improve the speed of the game engine: + * new_terrain: Everything is written here BEFORE it gets updated on the display + * old_terrain: Everything that WAS updated in the display is here + * + * In Order to avoid RAM consumption, it was decided to use arrays 2 by n. These ones keep X and Y coordinates in a lower space: + * invadersPos: keeps X & Y coordinates for invaders AND type/color AND destroyed status + * invadersLasersPos: keeps X & Y coordinates for invaders lasers + * humanLasersPos keeps X & Y coordinates for human lasers + * prev_time: used to move invaders down on the screen + * humanLasers_time: used to limit the human spaceship firing rate + * lasers: counts the number of lasers fired through the game + * shots: counts the human lasers that HIT invaders or invaders missiles + * flag_moving: used to stop movement of human spaceship once exploded + * huShipX: human spaceship X coordinate ( Y is NOT needed) + */ +char new_terrain[160][128], old_terrain[160][128]; +unsigned char invadersPos[50][4],invadersLasersPos[10][2],humanLasersPos[5][2]; +unsigned int prev_time,humanLasers_time; +float lasers, shots; +char flag_moving; +char huShipX; +int i,j,k; // For counters/For cycles + +/* + * Two modes: + * Hard reset: Resets stats, level, shots, score, lasers, lifes AND terrain, invaders, human lasers, invaders, lasers, ship pos, timers, flags + * Soft reset: Resets terrain, invaders, human lasers, invaders, lasers, ship pos + */ +void resetGame(boolean hardreset){ + if(hardreset){ + level=1; + lasers=shots=score=0; + lifes=6; + } + + // If leveled up, add an extra life + if(lifes<6){ + lifes++; + } + + flag_moving=prev_time=humanLasers_time=0; + + for(i=0;i<160;i++){ // Clear terrain + for(j=0;j<128;j++){ + new_terrain[i][j]=0; + old_terrain[i][j]=0; + } + } + for(i=0;i<50;i++){ // Clear invaders + for(int j=0;j<4;j++){ + invadersPos[i][j]=0; + //invadersPos[i][3]=1; + } + } + for(i=0;i<10;i++){ // Clear invaders lasers + invadersLasersPos[i][0]=invadersLasersPos[i][1]=invadersLasersPos[i][2]=0; + } + + for(i=0;i<5;i++){ // Clear human lasers + humanLasersPos[i][0]=humanLasersPos[i][1]=humanLasersPos[i][2]=0; + } + huShipX=80; // Reset human spaceship start position +} + +/* + * Reads accelerometer value and updates position of the human spaceship: + * If tilt left, huShipX=huShipX-6 + * If tilt right, huShipX=huShipX+6 + * If no tilt, huShipX=huShipX + * Writes new position to NEW map. NOTICE: new_terrain HAS NOT been rendered YET on the screen + */ +void moveSpaceship(){ + int temp; + if(accelerometer.getRoll()<-10 && (huShipX+6)<155 && flag_moving==0){ // Move Right + huShipX+=5; + new_terrain[huShipX++][119]=7; // 7: Is the identifier for the human spaceship. INFO check object() at Draw.h/Draw.cpp + }else if(accelerometer.getRoll()>=10 && (huShipX-6)>5 && flag_moving==0){ //Move Left + huShipX-=5; + new_terrain[huShipX--][119]=7; + }else{ // Same pos + new_terrain[huShipX][119]=7; + } +} +/* + * Creates 5 rows of 10 enemies each. Difficulty only affects the type of invader generated + */ +void createEnemies(int difficulty){ + char type; + + j=16; // Start position on X for first invader + if(difficulty==2){ // Invader type selection + type=random(1,3); + }else if(difficulty==3){ + type=random(1,5); + }else if(difficulty==4){ + type=random(1,7); + }else{ + type=1; + } + + for(i=0;i<10;i++){ + if(difficulty>4){ + type=random(1,7); + } + invadersPos[i][0]=j; // X Pos + invadersPos[i][1]=20; // Y Pos + invadersPos[i][2]=type; // Type and color + invadersPos[i][3]=0; // Destroyed: 0 is fine, 1 is destroyed + j+=14; //Separation on X axis + } + + if(difficulty==2){ + type=random(3,5); + }else if(difficulty==3){ + type=random(3,7); + }else if(difficulty==4){ + type=random(1,7); + }else{ + type=3; + } + + j=14; + for(i=10;i<20;i++){ + if(difficulty>4){ + type=random(1,7); + } + invadersPos[i][0]=j; + invadersPos[i][1]=30; + invadersPos[i][2]=type; + invadersPos[i][3]=0; + j+=14; + } + + if(difficulty==2){ + type=random(3,5); + }else if(difficulty==3){ + type=random(3,7); + }else if(difficulty==4){ + type=random(1,7); + }else{ + type=4; + } + + j=14; + for(i=20;i<30;i++){ + if(difficulty>4){ + type=random(1,7); + } + invadersPos[i][0]=j; + invadersPos[i][1]=40; + invadersPos[i][2]=type; + invadersPos[i][3]=0; + j+=14; + } + + if(difficulty==2){ + type=random(5,7); + }else if(difficulty==3){ + type=random(3,7); + }else if(difficulty==4){ + type=random(1,7); + }else{ + type=5; + } + + j=15; + for(i=30;i<40;i++){ + if(difficulty>4){ + type=random(1,7); + } + invadersPos[i][0]=j; + invadersPos[i][1]=50; + invadersPos[i][2]=type; + invadersPos[i][3]=0; + j+=14; + } + + if(difficulty==2){ + type=random(5,7); + }else if(difficulty==3){ + type=random(3,7); + }else if(difficulty==4){ + type=random(1,7); + }else{ + type=6; + } + + j=15; + for(i=40;i<50;i++){ + if(difficulty>4){ + type=random(1,7); + } + invadersPos[i][0]=j; + invadersPos[i][1]=60; + invadersPos[i][2]=type; + invadersPos[i][3]=0; + j+=14; + } +} + +/* + * Moves invaders down on the screen according to difficulty. Eg: increased difficulty, increased speed + */ +void moveInvaders(float difficulty){ + if(millis()-prev_time>(9000.0/(1+(difficulty/10)))){ + for(i=0;i<50;i++){ + invadersPos[i][1]+=5; // Sum 5 on y axis coordinates + } + prev_time=millis(); + } + for(i=0;i<50;i++){ // Updates the new Y coordinate on all invaders except destroyed ones + if(invadersPos[i][3]!=1){ // destroy invaders by not updating position + new_terrain[invadersPos[i][0]][invadersPos[i][1]]=invadersPos[i][2]; + } + } +} +/* + * Creates invaders lasers according to difficulty. Eg: more difficulty, more lasers are fired + * Algorithm searches for the 10 closest invaders to the bottom. Generates lasers randomly at that position + * It also lowers the firing rate accordingly to the alive invaders on map. Eg: 1 invader on map lowers firing to almost 0. + * This avoids making the level near impossible. Otherwise, last invader would fire constanlty + */ +void createInvadersLasers(float difficulty){ + char alive=0; + char ten; + char selected[10]; + char temp=0; + for(i=0;i<50;i++){ // Check and count invaders alive on map + if(invadersPos[i][3]==0){ + alive++; + } + } + + ten=(alive*10)/50; // lower firing rate + + for(i=49;i>=0 && temp!=ten;i--){ // Searches for 10 invaders closest to bottom (alive) + if(invadersPos[i][3]!=1){ + selected[temp]=i; + temp++; + }else{ + selected[temp]=60; // 60 is selected randomly to avoid firing from dead invaders + } + } + + for(i=0;i-30 && (millis()-humanLasers_time)>300){ // If accelerometer in position and time allows it, fire + i=0; + while(humanLasersPos[i][0]!=0 && humanLasersPos[i][1]!=0){ //checks for NON fired lasers + i++; + } + if(i<5){ // Generate laser at current spaceship POS X + humanLasersPos[i][0]= huShipX; + humanLasersPos[i][1]= 116; + lasers++; // Increment lasers fired counter + } + humanLasers_time=millis(); + } +} + +// Self explanatory +void createLasers(float difficulty){ + createInvadersLasers(difficulty); + createHumanLasers(); +} + +/* + * Moves invaders lasers on Y axis 5 pixels at a time. + * Deletes them once they went out the map + */ +void moveInvadersLasers(float difficulty){ + for(i=0;i<10;i++){ + if(invadersLasersPos[i][0]!=0 && invadersLasersPos[i][1]!=0){ //If lasers exist, move them + if(invadersLasersPos[i][1]+5<130){ // If laser is not out of map + invadersLasersPos[i][1]+=5; + new_terrain[invadersLasersPos[i][0]][invadersLasersPos[i][1]]=10; //draw them + }else{ + invadersLasersPos[i][0]=0; // Else delete laser + invadersLasersPos[i][1]=0; + } + } + } +} +/* + * Moves created human lasers 5 pixels at a time + * Deletes them once they are at the top of screen + */ +void moveHumanLasers(){ + for(i=0;i<5;i++){ + if(humanLasersPos[i][0]!=0 && humanLasersPos[i][1]!=0){ + if(humanLasersPos[i][1]-5>15){ + humanLasersPos[i][1]-=5; + new_terrain[humanLasersPos[i][0]][humanLasersPos[i][1]]=11; //Draw laser + }else{ + humanLasersPos[i][0]=0; //Delete lasers + humanLasersPos[i][1]=0; + } + } + } +} +// Self explanatory +void moveLasers(float difficulty){ + moveInvadersLasers(difficulty); + moveHumanLasers(); +} +/* + * Validates invaders lasers hitting human spaceship. + * Checks if laser exists, then laser's X coordinate and compares with ship. + * Checks Y coordinates and if hit, substracts 1 life + */ +void validateInvadersLasers(){ + for(i=0;i<10;i++){ + if(invadersLasersPos[i][0]!=0 && invadersLasersPos[i][1]!=0){ // if laser exists + if(invadersLasersPos[i][0]>huShipX-6 && invadersLasersPos[i][0]= 119){ // If lasers reach Spaceship Y coordinates + if(lifes>0){ + lifes--; // substract to lifes + } + // Destroy laser + invadersLasersPos[i][0]=0; + invadersLasersPos[i][1]=0; + } + } + } + } +} +/* + * Validates human lasers with invaders position and invaders lasers + * If true, destroys invader/laser and draws an explosion + */ +void validateHumanLasers(){ + for(i=0;i<5;i++){ // For each of the human lasers + for(j=49;j>=0;j--){ // Validate with all invaders + if(invadersPos[j][3]!=1){ // If invader is alive + if((invadersPos[j][0]-humanLasersPos[i][0]<=3 && invadersPos[j][0]-humanLasersPos[i][0]>=0) || (humanLasersPos[i][0]-invadersPos[j][0]<7 &&humanLasersPos[i][0]-invadersPos[j][0]>0)){ //If hit on X + if(humanLasersPos[i][1]-invadersPos[j][1]<6 &&humanLasersPos[i][1]-invadersPos[j][1]>=0){ // If hit on Y + //Destroy invader & laser + invadersPos[j][3]=1; + humanLasersPos[i][0]=0; + humanLasersPos[i][1]=0; + new_terrain[invadersPos[j][0]+1][invadersPos[j][1]+1]=9; //Create explosion at coordinates + shots++; // Increase shots counter + switch(invadersPos[j][2]){ // increases score according to invader type + case 1: + score+=3; + break; + case 2: + score+=3; + break; + case 3: + score+=2; + break; + case 4: + score+=2; + break; + case 5: + score+=1; + break; + case 6: + score+=1; + break; + } + } + } + } + } + /* + * Same logic as above. Validates collisions between lasers + */ + for(j=0;j<10;j++){ + if(invadersLasersPos[j][0]!= 0 && invadersLasersPos[j][1]!=0 ){ + if(abs(invadersLasersPos[j][0]-humanLasersPos[i][0])<5){ + if(humanLasersPos[i][1]-invadersLasersPos[j][1]<=6 && humanLasersPos[i][1]-invadersLasersPos[j][1]>=0){ + shots++; + new_terrain[invadersLasersPos[j][0]][invadersLasersPos[j][1]+2]=9; //Create explosion of lasers collision + invadersLasersPos[j][0]=0; //Delete invaders lasers + invadersLasersPos[j][1]=0; + humanLasersPos[i][0]=0; //Delete human laser + humanLasersPos[i][1]=0; + } + } + } + } + } +} + +//Self explanatory +void validateLasers(){ + validateInvadersLasers(); + validateHumanLasers(); +} +// Initializes SD card comms +void initSD(){ + Serial.print("Initializing SD card..."); + if (!SD.begin(4)) { + Serial.println("initialization failed!"); + return; + } + Serial.println("initialization done."); +} +// Reads HS.txt file and saves text +void readHS(){ + // re-open the file for reading: + myFile = SD.open("HS.txt"); + if (myFile) { + // read from the file until there's nothing else in it: + j=i=0; + while (myFile.available()) { + bufferIn=myFile.read(); + if( bufferIn=='\r' ){ + myFile.read(); + j++; + i=0; + namesScores[j][i]=myFile.read(); + }else{ + namesScores[j][i]=bufferIn; + } + i++; + } + // close the file: + myFile.close(); + // Separate names from scores + getNames(); + getScores(); + Serial.println("Successfully read file tho"); + } else { + // if the file didn't open, print an error: + Serial.println("error opening test.txt"); + } +} +/* + * Converts char to INT, and saves them in array + */ +void getScores(){ + scores[0]=getInt(namesScores[0]); + scores[1]=getInt(namesScores[1]); + scores[2]=getInt(namesScores[2]); + scores[3]=getInt(namesScores[3]); + scores[4]=getInt(namesScores[4]); +} +/* + * Stores names in a 1d array for using with draw library + */ +void getNames(){ + names[0]=namesScores[0][0]; + names[1]=namesScores[0][1]; + names[2]=namesScores[0][2]; + names[3]=namesScores[1][0]; + names[4]=namesScores[1][1]; + names[5]=namesScores[1][2]; + names[6]=namesScores[2][0]; + names[7]=namesScores[2][1]; + names[8]=namesScores[2][2]; + names[9]=namesScores[3][0]; + names[10]=namesScores[3][1]; + names[11]=namesScores[3][2]; + names[12]=namesScores[4][0]; + names[13]=namesScores[4][1]; + names[14]=namesScores[4][2]; +} + +/* + * Returns converted Int number from char + */ +int getInt(char numbs[13]){ + int result=0; + for(i=4;numbs[i]!='\0';i++){ + } + i--; + for(j=0,i;i>=4;i--,j++){ + result+=(numbs[i]-48)*pow(10,j); + } + return result; +} +// Returns the position of the current score compared to already stored +int getOrder(int score){ + readHS(); + for(i=0;i<5 && scores[i]> score;i++){ + } + return i; +} +/* + * Function gets input from the user in order to save his/her name + * Gets three upper case letters to save + */ +void getName(int posi){ + char chars[]="AAA"; + char namesOrder[5][3]; + draw.stars(); + i=0; + while(i!=3){ + if(accelerometer.getPitch()>-10 && chars[i]>65){ // Letters UP + chars[i]--; + }else if(accelerometer.getPitch()<-35 && chars[i]< 90){ // Letters DOWN + chars[i]++; + } + + if(accelerometer.getRoll()>10 && i>0){ // Select left + i--; + + }else if(accelerometer.getRoll()<-10 && i<3 && accelerometer.getRoll()>-20 & i!=2){ // Select Right + i++; + }else if(i==2 && accelerometer.getRoll()<-30 && i<3){ // Done editing + i++; + } + draw.updateNames(i,chars); //Redraws letters + delay(300); + } + + //Reconfigures scores according to new score and orders them + switch(posi){ + case 0: + namesOrder[4][0]=names[9]; + namesOrder[4][1]=names[10]; + namesOrder[4][2]=names[11]; + + namesOrder[3][0]=names[6]; + namesOrder[3][1]=names[7]; + namesOrder[3][2]=names[8]; + + namesOrder[2][0]=names[3]; + namesOrder[2][1]=names[4]; + namesOrder[2][2]=names[5]; + + namesOrder[1][0]=names[0]; + namesOrder[1][1]=names[1]; + namesOrder[1][2]=names[2]; + + namesOrder[0][0]=chars[0]; + namesOrder[0][1]=chars[1]; + namesOrder[0][2]=chars[2]; + + scores[4]=scores[3]; + scores[3]=scores[2]; + scores[2]=scores[1]; + scores[1]=scores[0]; + scores[0]=score; + + break; + case 1: + namesOrder[4][0]=names[9]; + namesOrder[4][1]=names[10]; + namesOrder[4][2]=names[11]; + + namesOrder[3][0]=names[6]; + namesOrder[3][1]=names[7]; + namesOrder[3][2]=names[8]; + + namesOrder[2][0]=names[3]; + namesOrder[2][1]=names[4]; + namesOrder[2][2]=names[5]; + + namesOrder[1][0]=chars[0]; + namesOrder[1][1]=chars[1]; + namesOrder[1][2]=chars[2]; + + namesOrder[0][0]=names[0]; + namesOrder[0][1]=names[1]; + namesOrder[0][2]=names[2]; + + scores[4]=scores[3]; + scores[3]=scores[2]; + scores[2]=scores[1]; + scores[1]=score; + + break; + case 2: + namesOrder[4][0]=names[9]; + namesOrder[4][1]=names[10]; + namesOrder[4][2]=names[11]; + + namesOrder[3][0]=names[6]; + namesOrder[3][1]=names[7]; + namesOrder[3][2]=names[8]; + + namesOrder[2][0]=chars[0]; + namesOrder[2][1]=chars[1]; + namesOrder[2][2]=chars[2]; + + namesOrder[1][0]=names[3]; + namesOrder[1][1]=names[4]; + namesOrder[1][2]=names[5]; + + namesOrder[0][0]=names[0]; + namesOrder[0][1]=names[1]; + namesOrder[0][2]=names[2]; + + scores[4]=scores[3]; + scores[3]=scores[2]; + scores[2]=score; + + break; + case 3: + namesOrder[4][0]=names[9]; + namesOrder[4][1]=names[10]; + namesOrder[4][2]=names[11]; + + namesOrder[3][0]=chars[0]; + namesOrder[3][1]=chars[1]; + namesOrder[3][2]=chars[2]; + + namesOrder[2][0]=names[6]; + namesOrder[2][1]=names[7]; + namesOrder[2][2]=names[8]; + + namesOrder[1][0]=names[3]; + namesOrder[1][1]=names[4]; + namesOrder[1][2]=names[5]; + + namesOrder[0][0]=names[0]; + namesOrder[0][1]=names[1]; + namesOrder[0][2]=names[2]; + + scores[4]=scores[3]; + scores[3]=score; + + break; + case 4: + namesOrder[4][0]=chars[0]; + namesOrder[4][1]=chars[1]; + namesOrder[4][2]=chars[2]; + + namesOrder[3][0]=names[9]; + namesOrder[3][1]=names[10]; + namesOrder[3][2]=names[11]; + + namesOrder[2][0]=names[6]; + namesOrder[2][1]=names[7]; + namesOrder[2][2]=names[8]; + + namesOrder[1][0]=names[3]; + namesOrder[1][1]=names[4]; + namesOrder[1][2]=names[5]; + + namesOrder[0][0]=names[0]; + namesOrder[0][1]=names[1]; + namesOrder[0][2]=names[2]; + + scores[4]=score; + + break; + + } + //Writes new ordered scores to txt file + SD.remove("HS.txt"); + + myFile=SD.open("HS.txt",FILE_WRITE); + if(myFile){ + myFile.print(namesOrder[0][0]); + myFile.print(namesOrder[0][1]); + myFile.print(namesOrder[0][2]); + myFile.print(","); + myFile.println(scores[0]); + + myFile.print(namesOrder[1][0]); + myFile.print(namesOrder[1][1]); + myFile.print(namesOrder[1][2]); + myFile.print(","); + myFile.println(scores[1]); + + myFile.print(namesOrder[2][0]); + myFile.print(namesOrder[2][1]); + myFile.print(namesOrder[2][2]); + myFile.print(","); + myFile.println(scores[2]); + + myFile.print(namesOrder[3][0]); + myFile.print(namesOrder[3][1]); + myFile.print(namesOrder[3][2]); + myFile.print(","); + myFile.println(scores[3]); + + myFile.print(namesOrder[4][0]); + myFile.print(namesOrder[4][1]); + myFile.print(namesOrder[4][2]); + myFile.print(","); + myFile.println(scores[4]); + + myFile.close(); + } + cState=MENU; +} +/* + * Checks game stats, updates score, substracts lifes + * If all invaders on screen are killed: next level + * If invader reaches bottom of map: game over + */ +void updateStats(){ + char alive=0; + for(i=0;i<50;i++){ + if(invadersPos[i][3]==0){ + alive++; + if(invadersPos[i][1]>111){ // If invader reaches bottom + cState=GO; + } + } + } + if(alive==0){ // If level cleared, generate new level + level++; + cState=SNEW; + } + + draw.updateScore(score); + + switch(lifes){ + case 0: + flag_moving=1; //Stop movement on spaceship + draw.object(7,huShipX,119,ST7735_BLACK,1);//Delete spaceship + draw.object(9,huShipX-4,115,ST7735_WHITE,2);//Create explosion + draw.object(12,139,1,ST7735_BLACK,1); //DElete last heart + cState=GO; + break; + case 1: + draw.object(12,146,1,ST7735_BLACK,1); + break; + case 2: + draw.object(12,153,1,ST7735_BLACK,1); + break; + case 3: + draw.object(12,139,8,ST7735_BLACK,1); + break; + case 4: + draw.object(12,146,8,ST7735_BLACK,1); + break; + case 5: + draw.object(12,153,8,ST7735_BLACK,1); + break; + } +} +/* + * In order to reduce rendering lag, it was decided to only update parts of the screen that currently have drawings on it. + * Therefore we WILL never use tft.fillScreen() on the state PLAY + * In order to optimize speed, two arrays are needed. One with all the previous positions of objects CURRENTLY on the Screen + * And another array with the future positions. + * + * Delete Logic: + * Function searches the old_terrain array until not 0. + * If not 0, replaces object with same object in color BLACK. + * Deletes the object from old_terrain by asigning a 0 + * Draw Logic: + * Same as Delete, but searches in new_terrain. And draws with COLOR. + * After Drawing, old_terrain=new_terrain + * And deletes entry on new_terrain + */ +void updateTerrain(){ + for(i=0;i<160;i++){ + for(j=0;j<128;j++){ + + if(new_terrain[i][j] != 0){ + draw.object(new_terrain[i][j],i,j,ST7735_CYAN,1); + old_terrain[i][j]=new_terrain[i][j]; + new_terrain[i][j]=0; + } + else if(old_terrain[i][j]!= 0 ){ + draw.object(old_terrain[i][j],i,j,ST7735_BLACK,1); + old_terrain[i][j]=0; + } + } + } +} + +void setup(void) { + Serial.begin(9600); // For debugging prupuses + initSD(); + + draw.setUp(); // Configures the Display, SET ROTATION HERE + draw.doIntro(); // Nifty little animation. If device shaked, next STATE=MENU + cState=MENU; +} +/* + * Game FSM machine is defined here. + */ +void loop(void) { + switch(cState){ + case MENU: + switch(draw.doMenu()){ + case 1: + cState=NEW; //Selected new game + break; + case 2: + cState=SDS; //Selected High Scores + break; + case 3: + cState=CREDITS; //Selected Credits + break; + } + break; + + case NEW: + resetGame(true); // Hard reset + draw.newGame(level,lifes,score); + createEnemies(level); + cState=PLAY; + break; + case SNEW: // Soft reset + resetGame(false); + draw.newGame(level,lifes,score); + createEnemies(level); + cState=PLAY; + break; + case PLAY: + createLasers(level); //Creates invaders lasers if not created yet + moveLasers(level); // Moves created lasers + validateLasers(); // Validates collisions of lasers with ship + moveInvaders(level); //Moves invaders + moveSpaceship(); //moves AND UPDATES spaceship on screen + updateTerrain(); //Done after EVERYthing ELSE + updateStats(); //Updates score, and lifes + break; + case SDS: + readHS(); //Read info from file + cState=HS; + break; + case HS: // Display High scores + getScores(); + getNames(); + draw.highScores(scores,names); + cState=MENU; + break; + case GO: // Game over checks if score is high score + readHS(); + getScores(); + if(getOrder(score)==5){ + draw.gameOver(score,shots,lasers); + cState=MENU; // NOT high score + }else{ + draw.gameOver(score,shots,lasers); + cState=NHS; //yes highscore + } + break; + case NHS: + getName(getOrder(score)); // Gets user input and saves score + break; + case CREDITS: //Displays credits + draw.credits(); + cState=INTRO; + break; + case INTRO: //Does intro + draw.doIntro(); + cState=MENU; + break; + default: + break; + } +} diff --git a/Draw.cpp b/Draw.cpp new file mode 100644 index 0000000..be0c923 --- /dev/null +++ b/Draw.cpp @@ -0,0 +1,1252 @@ +/*************************************************** + This is a library for the Adafruit 1.8" SPI display. + +This library works with the Adafruit 1.8" TFT Breakout w/SD card + ----> http://www.adafruit.com/products/358 +The 1.8" TFT shield + ----> https://www.adafruit.com/product/802 +The 1.44" TFT breakout + ----> https://www.adafruit.com/product/2088 +as well as Adafruit raw 1.8" TFT display + ----> http://www.adafruit.com/products/618 + + Check out the links above for our tutorials and wiring diagrams + These displays use SPI to communicate, 4 or 5 pins are required to + interface (RST is optional) + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + MIT license, all text above must be included in any redistribution + ****************************************************/ + +#include "Arduino.h" +#include "Draw.h" + + +void Draw::setUp(){ + // Use this initializer if you're using a 1.8" TFT + tft.initR(INITR_BLACKTAB); // initialize a ST7735S chip, black tab + Serial.println("init"); + tft.setTextWrap(true); // Don't allow text to run off right edge + tft.fillScreen(ST7735_BLACK); + tft.setRotation(1); //Set rotation as landscape with pins to right side + //------------------------- Do NOT modify before line ------------------ + +} + +void Draw::doIntro(){ + int posX,posY; + randomSeed(analogRead(A7)); + tft.fillScreen(ST7735_BLACK); //Clear Screen + //Draw Stars + for(_i=0;_i<50;_i++){ + for(_j=0;_j<10;_j++){ + posX=random(160); + posY=random(128); + tft.drawPixel(posX, posY, ST7735_WHITE); + delay(5); + } + } + //Draw Text + tft.setCursor(47,38); + tft.setTextColor(ST7735_YELLOW); + tft.setTextSize(3); + tft.println("GAME"); + delay(700); + + tft.setCursor(29,62); + tft.setTextColor(ST7735_RED); + tft.println("THING"); + delay(700); + + tft.setCursor(119,54); + tft.setTextColor(ST7735_BLUE); + tft.setTextSize(4); + tft.println("2"); + + delay(700); + tft.setCursor(35,84); + tft.setTextColor(ST7735_CYAN); + tft.setTextSize(1); + tft.println("BY Reuben & Luis"); + delay(700); + + //Shake to start Animation, otherwise do this thing: + _i=posX=posY=0; + int shake=1; + while(shake){ + tft.setCursor(50+posX,100+posY); + tft.setTextColor(ST7735_BLACK); + tft.setTextSize(2); + tft.println("SHAKE"); + + posX=random(5); + posY=random(5); + + tft.setCursor(50+posX,100+posY); + tft.setTextColor(ST7735_GREEN); + tft.setTextSize(2); + tft.println("SHAKE"); + delay(50); + + shake=accelerometer.isShaking(); + } + + +} + +int Draw::doMenu(){ + int posX,posY,roll; + //Fill Screen eith white + for(_i=0;_i<1000;_i++){ + for(_j=0;_j<100;_j++){ + posX=random(160); + posY=random(128); + tft.drawPixel(posX, posY, ST7735_WHITE); + } + } + tft.fillScreen(ST7735_WHITE); //FILL remaining Pixels white + + tft.setCursor(37,32); + tft.setTextColor(ST7735_BLACK); + tft.setTextSize(2); + tft.println("NEW GAME"); + + tft.setCursor(37,50); + tft.setTextColor(ST7735_BLACK); + tft.setTextSize(2); + tft.println("H SCORES"); + + tft.setCursor(37,68); + tft.setTextColor(ST7735_BLACK); + tft.setTextSize(2); + tft.println("CREDITS"); + + object(13,25,100,ST7735_RED,2); + tft.setCursor(35,104); + tft.setTextColor(ST7735_BLACK); + tft.setTextSize(1); + tft.println("Move"); + + object(14,80,102,ST7735_RED,2); + tft.setCursor(89,104); + tft.setTextColor(ST7735_BLACK); + tft.setTextSize(1); + tft.println("Select"); + + posY=31; + + + //Add 18 to posY of invader select menu + + while(roll>-30){ + //Do this trickery until selected + if(accelerometer.getPitch()>-20){ + posY= 31; + }else if(accelerometer.getPitch()>-40){ + posY=49; + }else{ + posY=67; + } + object(3,15,posY,ST7735_MAGENTA,2); + delay(20); + tft.invertDisplay(true); + delay(100); + object(3,15,posY,ST7735_WHITE,2); + roll=accelerometer.getRoll(); + + if(accelerometer.getPitch()>-20){ + posY= 31; + }else if(accelerometer.getPitch()>-40){ + posY=49; + }else{ + posY=67; + } + //delay(10); + object(3,15,posY,ST7735_MAGENTA,2); + delay(20); + tft.invertDisplay(false); + delay(100); + object(3,15,posY,ST7735_WHITE,2); + roll=accelerometer.getRoll(); + + } + + switch(posY){ + case 31: + + Serial.println("Start"); + return 1; + break; + case 49: + //showHS(); + Serial.println("HS"); + return 2; + break; + case 67: + //doCredits(); + Serial.println("Creds"); + return 3; + break; + } + + + + +} + +void Draw::newGame(char level,char lifes,unsigned int score){ + int posX, posY; + transition_lines(ST7735_BLACK); + tft.fillScreen(ST7735_BLACK); + //Draw Stars + for(_i=0;_i<25;_i++){ + for(_j=0;_j<5;_j++){ + posX=random(160); + posY=random(128); + tft.drawPixel(posX, posY, ST7735_WHITE); + delay(5); + } + } + + //Draw Level text + tft.setCursor(3,3); + tft.setTextColor(ST7735_CYAN); + tft.setTextSize(1); + tft.println("LVL:"); + tft.setCursor(28,3); + tft.print((int)level); + + //Draw level Score + tft.setCursor(63,3); + tft.setTextColor(ST7735_RED); + tft.println("SCORE"); + + tft.setCursor(76,12); + tft.setTextColor(ST7735_WHITE); + tft.print(score); + + //Draw level life + tft.setCursor(110,3); + tft.setTextColor(ST7735_YELLOW); + tft.println("LIFE:"); + switch(lifes){ + case 1: + object(12,139,1,ST7735_RED,1); + break; + case 2: + object(12,139,1,ST7735_RED,1); + object(12,146,1,ST7735_RED,1); + break; + case 3: + object(12,139,1,ST7735_RED,1); + object(12,146,1,ST7735_RED,1); + object(12,153,1,ST7735_RED,1); + break; + case 4: + object(12,139,1,ST7735_RED,1); + object(12,146,1,ST7735_RED,1); + object(12,153,1,ST7735_RED,1); + + object(12,139,8,ST7735_RED,1); + break; + case 5: + object(12,139,1,ST7735_RED,1); + object(12,146,1,ST7735_RED,1); + object(12,153,1,ST7735_RED,1); + + object(12,139,8,ST7735_RED,1); + object(12,146,8,ST7735_RED,1); + break; + case 6: + object(12,139,1,ST7735_RED,1); + object(12,146,1,ST7735_RED,1); + object(12,153,1,ST7735_RED,1); + + object(12,139,8,ST7735_RED,1); + object(12,146,8,ST7735_RED,1); + object(12,153,8,ST7735_RED,1); + break; + } + + + //Draw Human Spaceship + //object(4,80,119,ST7735_CYAN,1); +} + + + + +char updateLCD(char (*old)[160],char (*newT)[160]){ + return 'l'; +} + + +void Draw::transition_lines(uint16_t color){ + // tft.fillScreen(ST7735_BLACK); + for (int16_t x=0; x < tft.width(); x+=6) { + tft.drawLine(0, 0, x, tft.height()-1, color); + } + for (int16_t y=0; y < tft.height(); y+=6) { + tft.drawLine(0, 0, tft.width()-1, y, color); + } + + //tft.fillScreen(ST7735_BLACK); + for (int16_t x=0; x < tft.width(); x+=6) { + tft.drawLine(tft.width()-1, 0, x, tft.height()-1, color); + } + for (int16_t y=0; y < tft.height(); y+=6) { + tft.drawLine(tft.width()-1, 0, 0, y, color); + } + + //tft.fillScreen(ST7735_BLACK); + for (int16_t x=0; x < tft.width(); x+=6) { + tft.drawLine(0, tft.height()-1, x, 0, color); + } + for (int16_t y=0; y < tft.height(); y+=6) { + tft.drawLine(0, tft.height()-1, tft.width()-1, y, color); + } + + //tft.fillScreen(ST7735_BLACK); + for (int16_t x=0; x < tft.width(); x+=6) { + tft.drawLine(tft.width()-1, tft.height()-1, x, 0, color); + } + for (int16_t y=0; y < tft.height(); y+=6) { + tft.drawLine(tft.width()-1, tft.height()-1, 0, y, color); + } +} + + +void Draw::gameOver(unsigned int score,float shots, float lasers){ + transition_lines(ST7735_WHITE); + tft.fillScreen(ST7735_WHITE); + + tft.setCursor(47,18); + tft.setTextColor(ST7735_RED); + tft.setTextSize(3); + tft.println("GAME"); + delay(700); + + tft.setCursor(47,48); + tft.setTextColor(ST7735_BLACK); + tft.setTextSize(3); + tft.println("OVER"); + delay(700); + + tft.setCursor(30,78); + tft.setTextColor(ST7735_BLACK); + tft.setTextSize(1); + tft.println("Score:"); + + + tft.setCursor(70,74); + tft.setTextColor(ST7735_MAGENTA); + tft.setTextSize(2); + tft.println(score); + delay(500); + + tft.setCursor(15,99); + tft.setTextColor(ST7735_BLACK); + tft.setTextSize(1); + tft.println("Shots fired:"); + + tft.setCursor(90,99); + tft.setTextColor(ST7735_GREEN); + tft.setTextSize(1); + tft.println(lasers); + + tft.setCursor(15,112); + tft.setTextColor(ST7735_BLACK); + tft.setTextSize(1); + tft.println("Accuracy:"); + + tft.setCursor(80,112); + tft.setTextColor(ST7735_RED); + tft.setTextSize(1); + tft.println((shots/lasers)*100); + + tft.setCursor(120,108); + tft.setTextColor(ST7735_RED); + tft.setTextSize(2); + tft.println("%"); + + delay(4500); + + + + +} + +void Draw::updateScore(unsigned int score){ + tft.fillRect(75,12,20,8,ST7735_BLACK); + tft.setCursor(76,12); + tft.setTextColor(ST7735_WHITE); + tft.print(score); +} + + +void Draw::highScores(int scores[5], char names[15]){ + int posX, posY,m; + tft.fillScreen(ST7735_BLACK); + //Draw Stars + for(_i=0;_i<25;_i++){ + for(_j=0;_j<5;_j++){ + posX=random(160); + posY=random(128); + tft.drawPixel(posX, posY, ST7735_YELLOW); + delay(5); + } + } + tft.setCursor(15,2); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(2); + tft.println("High Scores"); + delay(300); + //------------------------------ 1 + tft.setCursor(20,20); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(2); + tft.println(1); + + tft.setCursor(35,20); + tft.setTextColor(ST7735_GREEN); + tft.setTextSize(2); + tft.println(names[0]); + + tft.setCursor(50,20); + tft.setTextColor(ST7735_GREEN); + tft.setTextSize(2); + tft.println(names[1]); + + tft.setCursor(65,20); + tft.setTextColor(ST7735_GREEN); + tft.setTextSize(2); + tft.println(names[2]); + + tft.setCursor(90,20); + tft.setTextColor(ST7735_YELLOW); + tft.setTextSize(2); + tft.println(scores[0]); + delay(300); + + //------------------------------ 2 + tft.setCursor(20,40); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(2); + tft.println(2); + + tft.setCursor(35,40); + tft.setTextColor(ST7735_RED); + tft.setTextSize(2); + tft.println(names[3]); + + tft.setCursor(50,40); + tft.setTextColor(ST7735_RED); + tft.setTextSize(2); + tft.println(names[4]); + + tft.setCursor(65,40); + tft.setTextColor(ST7735_RED); + tft.setTextSize(2); + tft.println(names[5]); + + tft.setCursor(90,40); + tft.setTextColor(ST7735_YELLOW); + tft.setTextSize(2); + tft.println(scores[1]); + delay(300); + + //------------------------------ 3 + tft.setCursor(20,60); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(2); + tft.println(3); + + tft.setCursor(35,60); + tft.setTextColor(ST7735_CYAN); + tft.setTextSize(2); + tft.println(names[6]); + + tft.setCursor(50,60); + tft.setTextColor(ST7735_CYAN); + tft.setTextSize(2); + tft.println(names[7]); + + tft.setCursor(65,60); + tft.setTextColor(ST7735_CYAN); + tft.setTextSize(2); + tft.println(names[8]); + + tft.setCursor(90,60); + tft.setTextColor(ST7735_YELLOW); + tft.setTextSize(2); + tft.println(scores[2]); + delay(300); + + //------------------------------ 4 + tft.setCursor(20,80); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(2); + tft.println(4); + + tft.setCursor(35,80); + tft.setTextColor(ST7735_MAGENTA); + tft.setTextSize(2); + tft.println(names[9]); + + tft.setCursor(50,80); + tft.setTextColor(ST7735_MAGENTA); + tft.setTextSize(2); + tft.println(names[10]); + + tft.setCursor(65,80); + tft.setTextColor(ST7735_MAGENTA); + tft.setTextSize(2); + tft.println(names[11]); + + tft.setCursor(90,80); + tft.setTextColor(ST7735_YELLOW); + tft.setTextSize(2); + tft.println(scores[3]); + delay(300); + + //------------------------------ 5 + tft.setCursor(20,100); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(2); + tft.println(5); + + tft.setCursor(35,100); + tft.setTextColor(ST7735_BLUE); + tft.setTextSize(2); + tft.println(names[12]); + + tft.setCursor(50,100); + tft.setTextColor(ST7735_BLUE); + tft.setTextSize(2); + tft.println(names[13]); + + tft.setCursor(65,100); + tft.setTextColor(ST7735_BLUE); + tft.setTextSize(2); + tft.println(names[14]); + + tft.setCursor(90,100); + tft.setTextColor(ST7735_YELLOW); + tft.setTextSize(2); + tft.println(scores[4]); + + + delay(5000); + +} + +void Draw::stars(){ + int posX, posY,m; + tft.fillScreen(ST7735_BLACK); + //Draw Stars + for(_i=0;_i<25;_i++){ + for(_j=0;_j<5;_j++){ + posX=random(160); + posY=random(128); + tft.drawPixel(posX, posY, ST7735_YELLOW); + delay(5); + } + } + tft.setCursor(40,2); + tft.setTextColor(ST7735_RED); + tft.setTextSize(2); + tft.println("Congrats!"); + + tft.setCursor(15,30); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(1); + tft.println("Enter"); + + tft.setCursor(17,39); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(1); + tft.println("your"); + + tft.setCursor(16,47); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(1); + tft.println("name:"); + + object(13,25,100,ST7735_RED,2); + tft.setCursor(35,104); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(1); + tft.println("Letters"); + + object(14,90,102,ST7735_RED,2); + tft.setCursor(99,104); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(1); + tft.println("Move"); + +} +void Draw::updateNames(int pos, char names[3]){ + + tft.fillRect(65,28,80,40,ST7735_BLACK); + + tft.setCursor(65,28); + tft.setTextColor(ST7735_BLUE); + tft.setTextSize(4); + tft.println(names); + switch(pos){ + case 0: + tft.fillRect(65,60,20,2,ST7735_YELLOW); + break; + case 1: + tft.fillRect(89,60,20,2,ST7735_YELLOW); + break; + case 2: + tft.fillRect(113,60,20,2,ST7735_YELLOW); + break; + case 3: + //tft.fillRect(137,60,20,2,ST7735_YELLOW); + break; + } + + delay(40); +} + +void Draw::credits(){ + tft.fillScreen(ST7735_BLACK); + int color = 100; + int i; + int t; + int k=0; + + tft.setCursor(40,60); + tft.setTextColor(ST7735_WHITE); + tft.setTextSize(1); + tft.println("Luis & Reuben:"); + while(k<10){ + for(t = 0 ; t <= 4; t+=1) { + int x = 0; + int y = 0; + int w = tft.width()-2; + int h = tft.height()-2; + for(i = 0 ; i <= 16; i+=1) { + tft.drawRoundRect(x, y, w, h, 5, color); + x+=2; + y+=3; + w-=4; + h-=6; + color+=1100; + } + color+=100; + } + k++; + } + + +} + +void Draw::object(int type, int posX, int posY, uint16_t color,int scale){ + /* + * 1: Small invader GREEN + * 2: Small invader RED + * 3: Medium invader GREEN + * 4: Medium invader CYAN + * 5: Large invader CYAN + * 6: Large invader MAGENTA + * 7: Human Spaceship CYAN + * 8: Human Spaceship YELLOW + * 9: Explosion WHITE + * 10: Enemeny laser WHITE + * 11: Huma laser YELLOW + * 12: Heart ANY + * 13: UP/Down arrows ANY + * 14: Right arrow ANY + * + */ + switch(type){ + case 1: //SMALL invader + if(color!=ST7735_BLACK){ + color=ST7735_GREEN; + } + tft.fillRect(posX,posY,scale,scale,color); + tft.fillRect(posX+(1*scale),posY,scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX,posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX,posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(4*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(5*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX,posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(6*scale),scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(7*scale),scale,scale,color); + + break; + case 2: //SMALL invader + if(color!=ST7735_BLACK){ + color=ST7735_RED; + } + tft.fillRect(posX,posY,scale,scale,color); + tft.fillRect(posX+(1*scale),posY,scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX,posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX,posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(4*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(5*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX,posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(6*scale),scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(7*scale),scale,scale,color); + + break; + case 3: //MEDIUM invader + if(color!=ST7735_BLACK && color!=ST7735_WHITE){ + color=ST7735_GREEN; + } + tft.fillRect(posX,posY,scale,scale,color); + tft.fillRect(posX+(6*scale),posY,scale,scale,color); + + tft.fillRect(posX+(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX,posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(8*scale),posY+(4*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX,posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(8*scale),posY+(5*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX,posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(8*scale),posY+(6*scale),scale,scale,color); + + tft.fillRect(posX+(1*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(7*scale),scale,scale,color); + break; + case 4: //MEDIUM invader + if(color!=ST7735_BLACK && color!=ST7735_WHITE){ + color=ST7735_CYAN; + } + tft.fillRect(posX,posY,scale,scale,color); + tft.fillRect(posX+(6*scale),posY,scale,scale,color); + + tft.fillRect(posX+(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX,posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(8*scale),posY+(4*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX,posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(8*scale),posY+(5*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX,posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(8*scale),posY+(6*scale),scale,scale,color); + + tft.fillRect(posX+(1*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(7*scale),scale,scale,color); + break; + case 5: //BIG INVADER + if(color!=ST7735_BLACK){ + color=ST7735_CYAN; + } + tft.fillRect(posX,posY,scale,scale,color); + tft.fillRect(posX+(1*scale),posY,scale,scale,color); + tft.fillRect(posX+(2*scale),posY,scale,scale,color); + tft.fillRect(posX+(3*scale),posY,scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX,posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(4*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX,posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(5*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(6*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(7*scale),scale,scale,color); + + break; + case 6: //BIG INVADER + if(color!=ST7735_BLACK){ + color=ST7735_MAGENTA; + } + tft.fillRect(posX,posY,scale,scale,color); + tft.fillRect(posX+(1*scale),posY,scale,scale,color); + tft.fillRect(posX+(2*scale),posY,scale,scale,color); + tft.fillRect(posX+(3*scale),posY,scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX,posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(4*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX,posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(5*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(6*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(7*scale),scale,scale,color); + + break; + case 7: //Human spaceship + if(color!=ST7735_BLACK){ + color=ST7735_CYAN; + } + tft.fillRect(posX,posY,scale,scale,color); + + tft.fillRect(posX,posY+(1*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(3*scale),scale,scale,color); + //tft.fillRect(posX,posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(4*scale),scale,scale,color); + //tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(4*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(5*scale),scale,scale,color); + //tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(5*scale),scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX,posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(6*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX,posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(7*scale),scale,scale,color); + + break; + case 8: //Human spaceship + if(color!=ST7735_BLACK){ + color=ST7735_YELLOW; + } + tft.fillRect(posX,posY,scale,scale,color); + + tft.fillRect(posX,posY+(1*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(3*scale),scale,scale,color); + //tft.fillRect(posX,posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(4*scale),scale,scale,color); + //tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(4*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(5*scale),scale,scale,color); + //tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(5*scale),scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX,posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(6*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX,posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(7*scale),scale,scale,color); + + break; + case 9: //explosion + if(color!=ST7735_BLACK){ + color=ST7735_WHITE; + } + tft.fillRect(posX,posY,scale,scale,color); + tft.fillRect(posX+(4*scale),posY,scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX-(4*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX-(3*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(8*scale),posY+(4*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(5*scale),posY+(5*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(6*scale),posY+(6*scale),scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(7*scale),posY+(7*scale),scale,scale,color); + + tft.fillRect(posX,posY+(8*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(8*scale),scale,scale,color); + break; + case 10: //Enemies lasers + if(color!=ST7735_BLACK){ + color=ST7735_WHITE; + } + tft.fillRect(posX,posY,scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + + tft.fillRect(posX+(1*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX,posY+(4*scale),scale,scale,color); + break; + case 11: //Human lasers + if(color!=ST7735_BLACK){ + color=ST7735_YELLOW; + } + tft.fillRect(posX,posY,scale,scale,color); + tft.fillRect(posX,posY+(1*scale),scale,scale,color); + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + break; + case 12: //Heart + tft.fillRect(posX,posY,scale,scale,color); + tft.fillRect(posX+(3*scale),posY,scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(4*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX+(3*scale),posY+(4*scale),scale,scale,color); + + tft.fillRect(posX+(1*scale),posY+(5*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(5*scale),scale,scale,color); + break; + case 13: //Up and down arrows + tft.fillRect(posX,posY,scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(1*scale),scale,scale,color); + tft.fillRect(posX,posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX,posY+(3*scale),scale,scale,color); + tft.fillRect(posX,posY+(4*scale),scale,scale,color); + tft.fillRect(posX,posY+(5*scale),scale,scale,color); + + tft.fillRect(posX-(2*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX,posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(6*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(6*scale),scale,scale,color); + + tft.fillRect(posX-(1*scale),posY+(7*scale),scale,scale,color); + tft.fillRect(posX,posY+(7*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(7*scale),scale,scale,color); + + tft.fillRect(posX,posY+(8*scale),scale,scale,color); + + + break; + case 14: //right arrow + tft.fillRect(posX,posY,scale,scale,color); + + tft.fillRect(posX,posY+(1*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(1*scale),scale,scale,color); + + tft.fillRect(posX-(3*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(2*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX-(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX,posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(2*scale),scale,scale,color); + tft.fillRect(posX+(2*scale),posY+(2*scale),scale,scale,color); + + tft.fillRect(posX,posY+(3*scale),scale,scale,color); + tft.fillRect(posX+(1*scale),posY+(3*scale),scale,scale,color); + + tft.fillRect(posX,posY+(4*scale),scale,scale,color); + break; + + + } +} + diff --git a/Draw.h b/Draw.h new file mode 100644 index 0000000..58f044a --- /dev/null +++ b/Draw.h @@ -0,0 +1,66 @@ +/*************************************************** + This is a library for the Adafruit 1.8" SPI display. + +This library works with the Adafruit 1.8" TFT Breakout w/SD card + ----> http://www.adafruit.com/products/358 +The 1.8" TFT shield + ----> https://www.adafruit.com/product/802 +The 1.44" TFT breakout + ----> https://www.adafruit.com/product/2088 +as well as Adafruit raw 1.8" TFT display + ----> http://www.adafruit.com/products/618 + + Check out the links above for our tutorials and wiring diagrams + These displays use SPI to communicate, 4 or 5 pins are required to + interface (RST is optional) + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + MIT license, all text above must be included in any redistribution + ****************************************************/ + +#ifndef Draw_h +#define Draw_h + +#include // Core graphics library +#include // Hardware-specific library +#include +#include "Arduino.h" +#include "Accelerometer.h" + +// For the breakout, you can use any 2 or 3 pins +// These pins will also work for the 1.8" TFT shield +#define TFT_CS 10 +#define TFT_RST 9 // you can also connect this to the Arduino reset + // in which case, set this #define pin to 0! +#define TFT_DC 8 + +class Draw +{ + public: + void setUp(); // Sets up the screen. ROTATION SET here + void doIntro(); // Fancy intro animation + int doMenu(); // Displays the menu. Returns selected option + void gameOver(unsigned int score,float shots, float lasers); + void updateScore(unsigned int score); + void stars(); + void credits(); + void newGame(char level,char lifes,unsigned int sccore); // Draws the new game screen + void transition_lines(uint16_t color); // Fancy transition animation from adafruit library + void highScores(int scores[5], char names[15]); + void updateNames(int pos, char names[3]); + Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); // Screen object. VERY IMPORTANT + /* + * Draws all the custom objects on screen. Needs object type, X coordinate, Y coordinate, color and scale + * CREATE NEW objects HERE + */ + void object(int type, int posX, int posY, uint16_t color,int scale); + private: + int _i; + int _j; + Accelerometer accelerometer; +}; +#endif +