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

Committer:
bonnyngangu
Date:
Sun May 08 22:16:03 2016 +0000
Revision:
1:fe4ac8f10309
Parent:
0:61128d697217
Child:
2:c1b442f26087
Setting an external joystick to control squash paddle, to initiate bouncing ball movement.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bonnyngangu 0:61128d697217 1 #include "mbed.h"
bonnyngangu 0:61128d697217 2 #include "N5110.h"
bonnyngangu 1:fe4ac8f10309 3 #include "game.h"
bonnyngangu 0:61128d697217 4 #include "SDFileSystem.h"
bonnyngangu 0:61128d697217 5
bonnyngangu 0:61128d697217 6 #define BALLRADIUS 2
bonnyngangu 0:61128d697217 7
bonnyngangu 0:61128d697217 8
bonnyngangu 0:61128d697217 9 // VCC, SCE, RST, D/C, MOSI, SCLK, LED
bonnyngangu 0:61128d697217 10 N5110 lcd (PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3);
bonnyngangu 0:61128d697217 11 // Can also power (VCC) directly from VOUT (3.3 V) -
bonnyngangu 0:61128d697217 12 // Can give better performance due to current limitation from GPIO pin
bonnyngangu 0:61128d697217 13
bonnyngangu 1:fe4ac8f10309 14 InterruptIn interrupt_button(PTB18); // interrupting the sleep mode.
bonnyngangu 0:61128d697217 15 PwmOut buzzer(PTA2); // buzzer connection to PwmOut.
bonnyngangu 0:61128d697217 16
bonnyngangu 1:fe4ac8f10309 17 // connections for joystick
bonnyngangu 1:fe4ac8f10309 18 DigitalIn button(PTB10);
bonnyngangu 1:fe4ac8f10309 19 AnalogIn xPot(PTB2);
bonnyngangu 1:fe4ac8f10309 20 AnalogIn yPot(PTB3);
bonnyngangu 1:fe4ac8f10309 21
bonnyngangu 0:61128d697217 22 // Connections to SD card holder on K64F (SPI interface)
bonnyngangu 0:61128d697217 23 SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCK, CS
bonnyngangu 0:61128d697217 24
bonnyngangu 0:61128d697217 25 void delete_file(char filename[]);
bonnyngangu 0:61128d697217 26
bonnyngangu 0:61128d697217 27 // function prototypes
bonnyngangu 0:61128d697217 28 void init_ball();
bonnyngangu 0:61128d697217 29 void game_timer_isr();
bonnyngangu 0:61128d697217 30 void BallMove();
bonnyngangu 0:61128d697217 31 void redraw_screen();
bonnyngangu 0:61128d697217 32 void update_physics_engine();
bonnyngangu 0:61128d697217 33 void check_collisions();
bonnyngangu 0:61128d697217 34 void Squash_Court();
bonnyngangu 0:61128d697217 35 void getPaddle();
bonnyngangu 0:61128d697217 36 void PaddleMove();
bonnyngangu 0:61128d697217 37 void updateJoystick();
bonnyngangu 1:fe4ac8f10309 38 void drawCircle(int x0,int y0,int radius,int fill);
bonnyngangu 0:61128d697217 39
bonnyngangu 0:61128d697217 40
bonnyngangu 0:61128d697217 41 // Can give better performance due to current limitation from GPIO pin
bonnyngangu 0:61128d697217 42 Ticker game_timer;
bonnyngangu 0:61128d697217 43
bonnyngangu 0:61128d697217 44 // struct used to store 2D vectors
bonnyngangu 0:61128d697217 45 typedef struct vector_t vector_t;
bonnyngangu 0:61128d697217 46 struct vector_t {
bonnyngangu 0:61128d697217 47 float x;
bonnyngangu 0:61128d697217 48 float y;
bonnyngangu 0:61128d697217 49 };
bonnyngangu 0:61128d697217 50
bonnyngangu 0:61128d697217 51 vector_t pos; // ball position
bonnyngangu 0:61128d697217 52 vector_t vel; // ball velocity
bonnyngangu 0:61128d697217 53 vector_t acc; // ball acceleration
bonnyngangu 0:61128d697217 54
bonnyngangu 0:61128d697217 55 float refresh_rate = 25.0; // how often to update display (Hz)
bonnyngangu 0:61128d697217 56 float g_dt = 2.0F/refresh_rate; // global to store time step (F makes it a float, gets rid of compiler warning)
bonnyngangu 0:61128d697217 57 volatile int g_timer_flag = 0;
bonnyngangu 0:61128d697217 58
bonnyngangu 0:61128d697217 59 int scoring = 0;// setting the value of starting score.
bonnyngangu 1:fe4ac8f10309 60 int m = 42;
bonnyngangu 0:61128d697217 61
bonnyngangu 0:61128d697217 62 int main()
bonnyngangu 0:61128d697217 63 {
bonnyngangu 0:61128d697217 64
bonnyngangu 0:61128d697217 65 wait(1.0); // short delay for power settling
bonnyngangu 0:61128d697217 66 lcd.init(); // initialising the display
bonnyngangu 1:fe4ac8f10309 67
bonnyngangu 1:fe4ac8f10309 68 // creating introduction screen
bonnyngangu 0:61128d697217 69 lcd.printString(" SQUASH!",15,2);
bonnyngangu 0:61128d697217 70 lcd.inverseMode(); // invert colours
bonnyngangu 0:61128d697217 71 lcd.drawLine(41,0,0,23,1);
bonnyngangu 0:61128d697217 72 lcd.drawLine(41,0,83,23,1);
bonnyngangu 0:61128d697217 73 lcd.drawLine(0,23,41,47,1);
bonnyngangu 0:61128d697217 74 lcd.drawLine(83,23,41,47,1);
bonnyngangu 0:61128d697217 75 lcd.refresh();
bonnyngangu 0:61128d697217 76 wait(5.0);
bonnyngangu 0:61128d697217 77 lcd.clear();
bonnyngangu 1:fe4ac8f10309 78
bonnyngangu 0:61128d697217 79 lcd.printString("Game starting",5,2);
bonnyngangu 0:61128d697217 80 lcd.normalMode(); // normal colour mode
bonnyngangu 0:61128d697217 81 lcd.setBrightness(0.5); // put LED backlight on 50%
bonnyngangu 0:61128d697217 82
bonnyngangu 1:fe4ac8f10309 83 buzzer.period_ms(1.5);
bonnyngangu 0:61128d697217 84 buzzer.pulsewidth_ms(1.9);
bonnyngangu 0:61128d697217 85 getPaddle();
bonnyngangu 0:61128d697217 86 wait(3.0);
bonnyngangu 1:fe4ac8f10309 87
bonnyngangu 1:fe4ac8f10309 88 init_ball();
bonnyngangu 0:61128d697217 89
bonnyngangu 0:61128d697217 90 // setup ticker
bonnyngangu 0:61128d697217 91 game_timer.attach(&game_timer_isr,g_dt);
bonnyngangu 0:61128d697217 92
bonnyngangu 0:61128d697217 93 redraw_screen(); // draw initial screen
bonnyngangu 1:fe4ac8f10309 94
bonnyngangu 0:61128d697217 95 while (1) {
bonnyngangu 0:61128d697217 96
bonnyngangu 1:fe4ac8f10309 97 Squash_Court(); // draw squash court
bonnyngangu 1:fe4ac8f10309 98
bonnyngangu 1:fe4ac8f10309 99 // setting the joystick control.
bonnyngangu 1:fe4ac8f10309 100 if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
bonnyngangu 1:fe4ac8f10309 101 joystick.direction = CENTRE;
bonnyngangu 1:fe4ac8f10309 102 int m = 42;
bonnyngangu 1:fe4ac8f10309 103 lcd.drawLine(m-6,45,m+6,45,1);
bonnyngangu 1:fe4ac8f10309 104 lcd.refresh();
bonnyngangu 1:fe4ac8f10309 105 wait(0.05);
bonnyngangu 1:fe4ac8f10309 106 lcd.clear();
bonnyngangu 1:fe4ac8f10309 107 }
bonnyngangu 1:fe4ac8f10309 108
bonnyngangu 1:fe4ac8f10309 109 else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
bonnyngangu 1:fe4ac8f10309 110 joystick.direction = LEFT;
bonnyngangu 1:fe4ac8f10309 111 int m = 18;
bonnyngangu 1:fe4ac8f10309 112 lcd.drawLine(m-6,45,m+6,45,1);
bonnyngangu 1:fe4ac8f10309 113 lcd.refresh();
bonnyngangu 1:fe4ac8f10309 114 wait(0.05);
bonnyngangu 1:fe4ac8f10309 115 lcd.clear();
bonnyngangu 1:fe4ac8f10309 116 }
bonnyngangu 1:fe4ac8f10309 117
bonnyngangu 1:fe4ac8f10309 118 else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
bonnyngangu 1:fe4ac8f10309 119 joystick.direction = RIGHT;
bonnyngangu 1:fe4ac8f10309 120 int m = 66;
bonnyngangu 1:fe4ac8f10309 121 lcd.drawLine(m-6,45,m+6,45,1);
bonnyngangu 1:fe4ac8f10309 122 //m-=1;// moving a pixel a time.
bonnyngangu 1:fe4ac8f10309 123 lcd.refresh();
bonnyngangu 1:fe4ac8f10309 124 wait(0.05);
bonnyngangu 1:fe4ac8f10309 125 lcd.clear();
bonnyngangu 1:fe4ac8f10309 126 }
bonnyngangu 1:fe4ac8f10309 127
bonnyngangu 0:61128d697217 128 BallMove();
bonnyngangu 0:61128d697217 129 }
bonnyngangu 0:61128d697217 130 }
bonnyngangu 0:61128d697217 131
bonnyngangu 0:61128d697217 132 void getPaddle() // setting paddle moving
bonnyngangu 0:61128d697217 133 {
bonnyngangu 0:61128d697217 134 int m = 42 ; // set paddle into origin 42 on X axis.
bonnyngangu 0:61128d697217 135
bonnyngangu 1:fe4ac8f10309 136 // draw a circle x,y,radius,black fill
bonnyngangu 1:fe4ac8f10309 137 lcd.drawCircle(42,40,2,1);
bonnyngangu 1:fe4ac8f10309 138
bonnyngangu 0:61128d697217 139 // drawing the paddle.
bonnyngangu 0:61128d697217 140 lcd.drawLine(m-6,45,m+6,45,1);
bonnyngangu 0:61128d697217 141 lcd.refresh();
bonnyngangu 0:61128d697217 142 }
bonnyngangu 0:61128d697217 143
bonnyngangu 0:61128d697217 144 void Squash_Court()
bonnyngangu 0:61128d697217 145 {
bonnyngangu 0:61128d697217 146
bonnyngangu 0:61128d697217 147 lcd.drawRect(0,0,83,47,0); // transparent, just outline
bonnyngangu 0:61128d697217 148 lcd.refresh(); // need to refresh screen after drawing rects
bonnyngangu 0:61128d697217 149
bonnyngangu 0:61128d697217 150 for (int i = 0; i < 84; i++) {
bonnyngangu 0:61128d697217 151
bonnyngangu 0:61128d697217 152 lcd.setPixel(i,24);// at y = 24 pixels (centre)
bonnyngangu 0:61128d697217 153 }
bonnyngangu 0:61128d697217 154
bonnyngangu 0:61128d697217 155 for (int i = 0; i < 84; i++) {
bonnyngangu 0:61128d697217 156
bonnyngangu 0:61128d697217 157 lcd.setPixel(i,16);// // at y = 14 pixels
bonnyngangu 0:61128d697217 158 }
bonnyngangu 0:61128d697217 159
bonnyngangu 0:61128d697217 160 // need to refresh display after setting pixels
bonnyngangu 0:61128d697217 161 lcd.refresh();
bonnyngangu 0:61128d697217 162
bonnyngangu 0:61128d697217 163 }
bonnyngangu 0:61128d697217 164
bonnyngangu 0:61128d697217 165 void BallMove()
bonnyngangu 0:61128d697217 166 {
bonnyngangu 0:61128d697217 167 if ( g_timer_flag ) { // ticker interrupt
bonnyngangu 0:61128d697217 168 g_timer_flag = 0; // clear flag
bonnyngangu 0:61128d697217 169 update_physics_engine();
bonnyngangu 0:61128d697217 170 check_collisions();
bonnyngangu 0:61128d697217 171 redraw_screen();
bonnyngangu 0:61128d697217 172 }
bonnyngangu 0:61128d697217 173 }
bonnyngangu 0:61128d697217 174
bonnyngangu 0:61128d697217 175 void redraw_screen()
bonnyngangu 0:61128d697217 176 {
bonnyngangu 0:61128d697217 177 lcd.clear();
bonnyngangu 0:61128d697217 178 lcd.drawCircle(pos.x,pos.y,BALLRADIUS,1); // x,y,radius,black fill
bonnyngangu 0:61128d697217 179 lcd.refresh(); // update display
bonnyngangu 0:61128d697217 180 }
bonnyngangu 0:61128d697217 181
bonnyngangu 0:61128d697217 182 void check_collisions()
bonnyngangu 0:61128d697217 183 {
bonnyngangu 0:61128d697217 184 // see if ball has hit the floor (subtract the radius since the position is the centre of the ball)
bonnyngangu 0:61128d697217 185 if ( pos.y >= 47 - BALLRADIUS ) {
bonnyngangu 0:61128d697217 186 pos.y = 47 - BALLRADIUS; // need to force this or else ball can end up going 'underground'
bonnyngangu 0:61128d697217 187 vel.y = -1.0 * vel.y; // y velocity is reflected and dampened
bonnyngangu 0:61128d697217 188 // y accleration is still gravity
bonnyngangu 0:61128d697217 189 }
bonnyngangu 0:61128d697217 190
bonnyngangu 0:61128d697217 191 else if ( pos.y >= 45 - BALLRADIUS) {
bonnyngangu 0:61128d697217 192 pos.y = 45 - BALLRADIUS; // need to force this or else ball can end up going 'underground'
bonnyngangu 0:61128d697217 193 vel.y = -4.0 * vel.y; // y velocity is reflected and dampened
bonnyngangu 0:61128d697217 194 // y accleration is still gravity
bonnyngangu 0:61128d697217 195 }
bonnyngangu 0:61128d697217 196
bonnyngangu 0:61128d697217 197 // has ball gone off the right-hand side?
bonnyngangu 0:61128d697217 198 if ( pos.x >= 83 - BALLRADIUS ) {
bonnyngangu 0:61128d697217 199 pos.x = 83 - BALLRADIUS; // need to force this or else ball can end up going off screen
bonnyngangu 0:61128d697217 200 vel.x = -1.5 * vel.x; // reflect and damp velocity
bonnyngangu 0:61128d697217 201 acc.x = -acc.x; // reflect accleration
bonnyngangu 0:61128d697217 202 }
bonnyngangu 0:61128d697217 203
bonnyngangu 0:61128d697217 204 // what about the left?
bonnyngangu 0:61128d697217 205 if ( pos.x <= BALLRADIUS ) {
bonnyngangu 0:61128d697217 206 pos.x = BALLRADIUS; // need to force this or else ball can end up going off screen
bonnyngangu 0:61128d697217 207 vel.x = -0.5 * vel.x; // reflect and damp velocity
bonnyngangu 0:61128d697217 208 acc.x = -acc.x; // reflect accleration
bonnyngangu 0:61128d697217 209 }
bonnyngangu 0:61128d697217 210 }
bonnyngangu 0:61128d697217 211
bonnyngangu 0:61128d697217 212 void update_physics_engine()
bonnyngangu 0:61128d697217 213 {
bonnyngangu 0:61128d697217 214 // from Newton's Laws
bonnyngangu 0:61128d697217 215
bonnyngangu 0:61128d697217 216 acc.x = 0.9F*acc.x; // reduce a little due to air friction
bonnyngangu 0:61128d697217 217
bonnyngangu 0:61128d697217 218 // calc new velocity (assume 'unit' time)
bonnyngangu 0:61128d697217 219 vel.x = vel.x + acc.x; // * g_gt;
bonnyngangu 0:61128d697217 220 vel.y = vel.y + acc.y; // * g_gt;
bonnyngangu 0:61128d697217 221
bonnyngangu 0:61128d697217 222 // calc new position (assume 'unit' time)
bonnyngangu 0:61128d697217 223 pos.x = pos.x + vel.x;// * g_gt;
bonnyngangu 0:61128d697217 224 pos.y = pos.y + vel.y;// * g_dt;
bonnyngangu 0:61128d697217 225
bonnyngangu 0:61128d697217 226 // should really multiply the above by the time-step,
bonnyngangu 0:61128d697217 227 // but since the pixel can only be a integer value,
bonnyngangu 0:61128d697217 228 // it makes the motion a little 'jumpy'.
bonnyngangu 0:61128d697217 229 }
bonnyngangu 0:61128d697217 230
bonnyngangu 0:61128d697217 231 void init_ball()
bonnyngangu 0:61128d697217 232 {
bonnyngangu 0:61128d697217 233 // initial position (top-left)
bonnyngangu 0:61128d697217 234 pos.x = BALLRADIUS;
bonnyngangu 0:61128d697217 235 pos.y = BALLRADIUS;
bonnyngangu 0:61128d697217 236 // initial velocity - still
bonnyngangu 0:61128d697217 237 vel.x = 0.0;
bonnyngangu 0:61128d697217 238 vel.y = 0.0;
bonnyngangu 0:61128d697217 239 // initial acceleration - gravity and a bit of push to right
bonnyngangu 0:61128d697217 240 acc.x = 0.5;
bonnyngangu 0:61128d697217 241 acc.y = 1.0; // +ve so ball accelerates to bottom of display (top of screen is y=0, bottom is y=47)
bonnyngangu 0:61128d697217 242 // should be 9.8, but can play with value to get a 'nice' ball movement
bonnyngangu 0:61128d697217 243 }
bonnyngangu 0:61128d697217 244
bonnyngangu 1:fe4ac8f10309 245 void calibrateJoystick()
bonnyngangu 1:fe4ac8f10309 246 {
bonnyngangu 1:fe4ac8f10309 247 button.mode(PullDown);
bonnyngangu 1:fe4ac8f10309 248 // must not move during calibration
bonnyngangu 1:fe4ac8f10309 249 joystick.x0 = xPot; // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly)
bonnyngangu 1:fe4ac8f10309 250 joystick.y0 = yPot;
bonnyngangu 1:fe4ac8f10309 251 }
bonnyngangu 1:fe4ac8f10309 252 void updateJoystick()
bonnyngangu 1:fe4ac8f10309 253 {
bonnyngangu 1:fe4ac8f10309 254 // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
bonnyngangu 1:fe4ac8f10309 255 joystick.x = xPot - joystick.x0;
bonnyngangu 1:fe4ac8f10309 256 joystick.y = yPot - joystick.y0;
bonnyngangu 1:fe4ac8f10309 257 // read button state
bonnyngangu 1:fe4ac8f10309 258 joystick.buttonjoystick = button;
bonnyngangu 1:fe4ac8f10309 259
bonnyngangu 1:fe4ac8f10309 260 // calculate direction depending on x,y values
bonnyngangu 1:fe4ac8f10309 261 // tolerance allows a little lee-way in case joystick not exactly in the stated direction
bonnyngangu 1:fe4ac8f10309 262 if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
bonnyngangu 1:fe4ac8f10309 263 joystick.direction = CENTRE;
bonnyngangu 1:fe4ac8f10309 264 } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
bonnyngangu 1:fe4ac8f10309 265 joystick.direction = UP;
bonnyngangu 1:fe4ac8f10309 266 } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
bonnyngangu 1:fe4ac8f10309 267 joystick.direction = DOWN;
bonnyngangu 1:fe4ac8f10309 268 } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
bonnyngangu 1:fe4ac8f10309 269 joystick.direction = RIGHT;
bonnyngangu 1:fe4ac8f10309 270 } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
bonnyngangu 1:fe4ac8f10309 271 joystick.direction = LEFT;
bonnyngangu 1:fe4ac8f10309 272 } else {
bonnyngangu 1:fe4ac8f10309 273 joystick.direction = UNKNOWN;
bonnyngangu 1:fe4ac8f10309 274 }
bonnyngangu 1:fe4ac8f10309 275
bonnyngangu 1:fe4ac8f10309 276 // set flag for printing
bonnyngangu 1:fe4ac8f10309 277 printFlag = 1;
bonnyngangu 1:fe4ac8f10309 278 }
bonnyngangu 1:fe4ac8f10309 279
bonnyngangu 0:61128d697217 280 void game_timer_isr()
bonnyngangu 0:61128d697217 281 {
bonnyngangu 0:61128d697217 282 g_timer_flag = 1;
bonnyngangu 1:fe4ac8f10309 283 }