The present code implements a single player squash game, using joystick to move paddle right or left. And checks the current temperature inside the device.
Dependencies: 2645_I2C_TMP102 2645_Physics_Engine_Example Paddle mbed
main.cpp
- Committer:
- bonnyngangu
- Date:
- 2016-05-06
- Revision:
- 0:61128d697217
- Child:
- 1:fe4ac8f10309
File content as of revision 0:61128d697217:
#include "mbed.h" #include "N5110.h" #include "Joystick.h" #include "SDFileSystem.h" #define BALLRADIUS 2 // VCC, SCE, RST, D/C, MOSI, SCLK, LED N5110 lcd (PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3); // Can also power (VCC) directly from VOUT (3.3 V) - // Can give better performance due to current limitation from GPIO pin InterruptIn interrupt_button(PTB18); // interrupt in button. PwmOut buzzer(PTA2); // buzzer connection to PwmOut. // Connections to SD card holder on K64F (SPI interface) SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCK, CS void delete_file(char filename[]); // function prototypes void init_ball(); void game_timer_isr(); void BallMove(); void redraw_screen(); void update_physics_engine(); void check_collisions(); void Squash_Court(); void getPaddle(); void PaddleMove(); void updateJoystick(); //bool wall = false; // Can give better performance due to current limitation from GPIO pin Ticker game_timer; // struct used to store 2D vectors typedef struct vector_t vector_t; struct vector_t { float x; float y; }; vector_t pos; // ball position vector_t vel; // ball velocity vector_t acc; // ball acceleration float refresh_rate = 25.0; // how often to update display (Hz) float g_dt = 2.0F/refresh_rate; // global to store time step (F makes it a float, gets rid of compiler warning) volatile int g_timer_flag = 0; int scoring = 0;// setting the value of starting score. int Lhand = 0;// value of the left hand side on y axis. int Rhand = 0;// value of the right hand side on y axis. int m = 42 ; int a; int width;// left hand side width. int width2;/// right hand side width. int main() { wait(1.0); // short delay for power settling lcd.init(); // initialising the display lcd.printString(" SQUASH!",15,2); lcd.inverseMode(); // invert colours lcd.drawLine(41,0,0,23,1); lcd.drawLine(41,0,83,23,1); lcd.drawLine(0,23,41,47,1); lcd.drawLine(83,23,41,47,1); lcd.refresh(); wait(5.0); lcd.clear(); lcd.printString("Game starting",5,2); lcd.normalMode(); // normal colour mode lcd.setBrightness(0.5); // put LED backlight on 50% buzzer.period_ms(2.0); buzzer.pulsewidth_ms(1.9); getPaddle(); wait(3.0); calibrateJoystick(); // get centred values of joystick pollJoystick.attach(&updateJoystick,1.0/10.0); // read joystick 10 times per second init_ball(); // setup ticker game_timer.attach(&game_timer_isr,g_dt); redraw_screen(); // draw initial screen while (1) { Squash_Court(); BallMove(); PaddleMove(); } } void getPaddle() // setting paddle moving { int m = 42 ; // set paddle into origin 42 on X axis. // drawing the paddle. lcd.drawLine(m-6,45,m+6,45,1); lcd.refresh(); } void PaddleMove() { // setting the joystick control. if (joystick.direction == RIGHT && m > 4) { //scoring + = 1;// one pixel move for 1 score. lcd.drawLine(m-6,45,m+6,45,1); m-=1;// moving a pixel a time. lcd.refresh(); } if (joystick.direction == LEFT && m < 78) { //scoring + = 1;// one pixel move for 1 score. lcd.drawLine(m-6,45,m+6,45,1); m+=1;// moving a pixel a time. lcd.drawLine(m-6,45,m+6,45,1); lcd.refresh(); } } void Squash_Court() { lcd.drawRect(0,0,83,47,0); // transparent, just outline lcd.refresh(); // need to refresh screen after drawing rects for (int i = 0; i < 84; i++) { lcd.setPixel(i,24);// at y = 24 pixels (centre) } for (int i = 0; i < 84; i++) { lcd.setPixel(i,16);// // at y = 14 pixels } // need to refresh display after setting pixels lcd.refresh(); } int SD_card() { serial.baud(115200); // full-speed! serial.printf("#### SD Card Example #####\n"); FILE *fp; // this is our file pointer wait(1); // open file for writing ('w') - creates file if it doesn't exist and overwrites // if it does. If you wish to add a score onto a list, then you can // append instead 'a'. This will open the file if it exists and start // writing at the end. It will create the file if it doesn't exist. fp = fopen("/sd/topscore.txt", "w"); int top_score = 56; // random example if (fp == NULL) { // if it can't open the file then print error message serial.printf("Error! Unable to open file!\n"); } else { // opened file so can write serial.printf("Writing to file...."); fprintf(fp, "%d",top_score); // ensure data type matches serial.printf("Done.\n"); fclose(fp); // ensure you close the file after writing } // now open file for reading fp = fopen("/sd/topscore.txt", "r"); int stored_top_score = -1; // -1 to demonstrate it has changed after reading if (fp == NULL) { // if it can't open the file then print error message serial.printf("Error! Unable to open file!\n"); } else { // opened file so can write fscanf(fp, "%d",&stored_top_score); // ensure data type matches - note address operator (&) serial.printf("Read %d from file.\n",stored_top_score); fclose(fp); // ensure you close the file after reading } // for this example, I'll create some numbers to write to file in a big list // a data logger for example will usually append to a file - at a reading // at the end rather than creating a new file fp = fopen("/sd/test.txt", "a"); if (fp == NULL) { // if it can't open the file then print error message serial.printf("Error! Unable to open file!\n"); } else { // opened file so can write serial.printf("Writing to file...."); for(int i = 1; i <= 50; i++) { float dummy = 1000.0F/i; // dummy variable fprintf(fp, "%d,%f\n",i,dummy); // print formatted string to file (CSV) } serial.printf("Done.\n"); fclose(fp); // ensure you close the file after writing } // you can comment out the writing example to check that the writing has // worked - when you run it after commenting, it should still open the // file that exists on the SD card - assuming you didn't delete it! // now open file for reading...note the 'r' fp = fopen("/sd/test.txt", "r"); if (fp == NULL) { // if it can't open the file then print error message serial.printf("Error! Unable to open file!\n"); } else { serial.printf("Reading file....\n"); int i; // create suitable variables to store the data in the file float value; // in this example, we keep reading (using fscanf) until we reach // the 'end of file'. Note we use the address operator & to write // to the variables. Also the format of the string must match what // is in the file while (fscanf(fp, "%d,%f", &i, &value) != EOF) { serial.printf("%d,%f\n",i,value); } serial.printf("Done.\n"); fclose(fp); // ensure you close the file after reading } // the previous example just read the values into variables and printed to // serial, we'll now read files into an array. // now open file for reading...note the 'r' fp = fopen("/sd/test.txt", "r"); int n=0; // going to store the number of lines in the file int *index_array; // pointers to create dynamic arrays later float *value_array; // note memory will be in heap rather than on the stack if (fp == NULL) { // if it can't open the file then print error message serial.printf("Error! Unable to open file!\n"); } else { serial.printf("Counting lines in file....\n"); //Since we may not know the // number of lines in the files ahead of time, we'll first count them // * means scan but don't save while (fscanf(fp, "%*d,%*f") != EOF) { n++; // increment counter when read a line } serial.printf("Read %d lines\n",n); serial.printf("Creating dynamic arrays...\n"); // calloc creates an array and initilises to 0 // malloc returns unitialised array - diffrent syntax index_array = (int *)calloc(n, sizeof (int)); value_array = (float *)calloc(n, sizeof (float)); int i=0; rewind(fp); // 'scrolled' to end of file, so go back to beginning serial.printf("Reading into arrays...\n"); while (fscanf(fp, "%d,%f",&index_array[i],&value_array[i]) != EOF) { i++; // read data into array and increment index } serial.printf("Done.\n"); fclose(fp); // ensure you close the file after reading } // we should now have the data in the arrays, will print to serial to check for(int i=0; i<n ; i++) { serial.printf("[%d] %d,%f\n",i,index_array[i],value_array[i]); } serial.printf("End of SD card example\n"); return 0; } void delete_file(char filename[]) { serial.printf("Deleting file '%s'...",filename); FILE *fp = fopen(filename, "r"); // try and open file if (fp != NULL) { // if it does open... fclose(fp); // close it remove(filename); // and then delete serial.printf("Done!\n"); } // if we can't open it, it doesn't exist and so we can't delete it } void BallMove() { if ( g_timer_flag ) { // ticker interrupt g_timer_flag = 0; // clear flag update_physics_engine(); check_collisions(); redraw_screen(); } } void redraw_screen() { lcd.clear(); lcd.drawCircle(pos.x,pos.y,BALLRADIUS,1); // x,y,radius,black fill lcd.refresh(); // update display } void check_collisions() { // see if ball has hit the floor (subtract the radius since the position is the centre of the ball) if ( pos.y >= 47 - BALLRADIUS ) { pos.y = 47 - BALLRADIUS; // need to force this or else ball can end up going 'underground' vel.y = -1.0 * vel.y; // y velocity is reflected and dampened // y accleration is still gravity } else if ( pos.y >= 45 - BALLRADIUS) { pos.y = 45 - BALLRADIUS; // need to force this or else ball can end up going 'underground' vel.y = -4.0 * vel.y; // y velocity is reflected and dampened // y accleration is still gravity } // has ball gone off the right-hand side? if ( pos.x >= 83 - BALLRADIUS ) { pos.x = 83 - BALLRADIUS; // need to force this or else ball can end up going off screen vel.x = -1.5 * vel.x; // reflect and damp velocity acc.x = -acc.x; // reflect accleration } // what about the left? if ( pos.x <= BALLRADIUS ) { pos.x = BALLRADIUS; // need to force this or else ball can end up going off screen vel.x = -0.5 * vel.x; // reflect and damp velocity acc.x = -acc.x; // reflect accleration } } void update_physics_engine() { // from Newton's Laws acc.x = 0.9F*acc.x; // reduce a little due to air friction // calc new velocity (assume 'unit' time) vel.x = vel.x + acc.x; // * g_gt; vel.y = vel.y + acc.y; // * g_gt; // calc new position (assume 'unit' time) pos.x = pos.x + vel.x;// * g_gt; pos.y = pos.y + vel.y;// * g_dt; // should really multiply the above by the time-step, // but since the pixel can only be a integer value, // it makes the motion a little 'jumpy'. } void init_ball() { // initial position (top-left) pos.x = BALLRADIUS; pos.y = BALLRADIUS; // initial velocity - still vel.x = 0.0; vel.y = 0.0; // initial acceleration - gravity and a bit of push to right acc.x = 0.5; acc.y = 1.0; // +ve so ball accelerates to bottom of display (top of screen is y=0, bottom is y=47) // should be 9.8, but can play with value to get a 'nice' ball movement } void game_timer_isr() { g_timer_flag = 1; }