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-08
- Revision:
- 1:fe4ac8f10309
- Parent:
- 0:61128d697217
- Child:
- 2:c1b442f26087
File content as of revision 1:fe4ac8f10309:
#include "mbed.h" #include "N5110.h" #include "game.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); // interrupting the sleep mode. PwmOut buzzer(PTA2); // buzzer connection to PwmOut. // connections for joystick DigitalIn button(PTB10); AnalogIn xPot(PTB2); AnalogIn yPot(PTB3); // 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(); void drawCircle(int x0,int y0,int radius,int fill); // 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 m = 42; int main() { wait(1.0); // short delay for power settling lcd.init(); // initialising the display // creating introduction screen 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(1.5); buzzer.pulsewidth_ms(1.9); getPaddle(); wait(3.0); init_ball(); // setup ticker game_timer.attach(&game_timer_isr,g_dt); redraw_screen(); // draw initial screen while (1) { Squash_Court(); // draw squash court // setting the joystick control. if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { joystick.direction = CENTRE; int m = 42; lcd.drawLine(m-6,45,m+6,45,1); lcd.refresh(); wait(0.05); lcd.clear(); } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { joystick.direction = LEFT; int m = 18; lcd.drawLine(m-6,45,m+6,45,1); lcd.refresh(); wait(0.05); lcd.clear(); } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { joystick.direction = RIGHT; int m = 66; lcd.drawLine(m-6,45,m+6,45,1); //m-=1;// moving a pixel a time. lcd.refresh(); wait(0.05); lcd.clear(); } BallMove(); } } void getPaddle() // setting paddle moving { int m = 42 ; // set paddle into origin 42 on X axis. // draw a circle x,y,radius,black fill lcd.drawCircle(42,40,2,1); // drawing the paddle. 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(); } 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 calibrateJoystick() { button.mode(PullDown); // must not move during calibration joystick.x0 = xPot; // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly) joystick.y0 = yPot; } void updateJoystick() { // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred) joystick.x = xPot - joystick.x0; joystick.y = yPot - joystick.y0; // read button state joystick.buttonjoystick = button; // calculate direction depending on x,y values // tolerance allows a little lee-way in case joystick not exactly in the stated direction if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { joystick.direction = CENTRE; } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { joystick.direction = UP; } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { joystick.direction = DOWN; } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { joystick.direction = RIGHT; } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { joystick.direction = LEFT; } else { joystick.direction = UNKNOWN; } // set flag for printing printFlag = 1; } void game_timer_isr() { g_timer_flag = 1; }