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

Revision:
0:61128d697217
Child:
1:fe4ac8f10309
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri May 06 17:03:41 2016 +0000
@@ -0,0 +1,378 @@
+#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;
+}
\ No newline at end of file