One player pong with seven segment display for score keeping

Dependencies:   4DGL-uLCD-SE PinDetect SDFileSystem mbed-rtos mbed wave_player

Fork of ECE2036Lab2StarterCode by Joseph Lind

Committer:
jlind6
Date:
Tue Jun 17 20:03:41 2014 +0000
Revision:
0:356124c0bafc
Child:
2:6163865f5ce3
Initial Commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jlind6 0:356124c0bafc 1 #include "mbed.h"
jlind6 0:356124c0bafc 2 #include "PinDetect.h"
jlind6 0:356124c0bafc 3 #include "uLCD_4DGL.h"
jlind6 0:356124c0bafc 4 #include "Speaker.h"
jlind6 0:356124c0bafc 5
jlind6 0:356124c0bafc 6 // Pushbuttons
jlind6 0:356124c0bafc 7 PinDetect pbUp(p15);
jlind6 0:356124c0bafc 8 PinDetect pbDown(p16);
jlind6 0:356124c0bafc 9 // uLCD
jlind6 0:356124c0bafc 10 uLCD_4DGL uLCD(p28, p27, p29);
jlind6 0:356124c0bafc 11 //Speaker
jlind6 0:356124c0bafc 12 Speaker mySpeaker(p21);
jlind6 0:356124c0bafc 13
jlind6 0:356124c0bafc 14 // Global variables needed for the push button interrupts
jlind6 0:356124c0bafc 15 int cornerX = 118, cornerY = 1;
jlind6 0:356124c0bafc 16 int oldCornerY = 1;
jlind6 0:356124c0bafc 17 int paddleMove = 8;
jlind6 0:356124c0bafc 18 int length = 40;
jlind6 0:356124c0bafc 19 int width = 3;
jlind6 0:356124c0bafc 20
jlind6 0:356124c0bafc 21 // State machine definitions
jlind6 0:356124c0bafc 22 enum gameStateType {START, WAIT, GAME_SETUP, GAME, LOSE};
jlind6 0:356124c0bafc 23 /* State Definitions:
jlind6 0:356124c0bafc 24 * START -- Creates the start screen
jlind6 0:356124c0bafc 25 * WAIT -- After the start screen, goes into wait where mbed spins and does nothing
jlind6 0:356124c0bafc 26 * GAME_SETUP -- Sets up one time things (like boarders, initializes beginning velocity
jlind6 0:356124c0bafc 27 * GAME -- When the user actually gets to play
jlind6 0:356124c0bafc 28 * LOSE -- clears the screen, prints you lose, waits, then goes back to start
jlind6 0:356124c0bafc 29 */
jlind6 0:356124c0bafc 30
jlind6 0:356124c0bafc 31 // Global state machine variable (So that the pushbuttons can modify it)
jlind6 0:356124c0bafc 32 gameStateType gameState = START;
jlind6 0:356124c0bafc 33
jlind6 0:356124c0bafc 34 // Pushbutton callbacks
jlind6 0:356124c0bafc 35 // WARNING: Do not call to draw anything to the uLCD in these
jlind6 0:356124c0bafc 36 // as this will cause the uLCD to crash sometimes. Update positions
jlind6 0:356124c0bafc 37 // and draw elsewhere (like it's done here).
jlind6 0:356124c0bafc 38 // Only modify the logic inside the callback functions.
jlind6 0:356124c0bafc 39 void pbUp_hit_callback (void)
jlind6 0:356124c0bafc 40 {
jlind6 0:356124c0bafc 41 switch (gameState)
jlind6 0:356124c0bafc 42 {
jlind6 0:356124c0bafc 43 case WAIT:
jlind6 0:356124c0bafc 44 gameState = GAME_SETUP;
jlind6 0:356124c0bafc 45 break;
jlind6 0:356124c0bafc 46 case GAME:
jlind6 0:356124c0bafc 47 if(cornerY > paddleMove) {
jlind6 0:356124c0bafc 48 cornerY -= paddleMove;
jlind6 0:356124c0bafc 49 }
jlind6 0:356124c0bafc 50 break;
jlind6 0:356124c0bafc 51 }
jlind6 0:356124c0bafc 52 }
jlind6 0:356124c0bafc 53
jlind6 0:356124c0bafc 54 void pbDown_hit_callback (void)
jlind6 0:356124c0bafc 55 {
jlind6 0:356124c0bafc 56 switch (gameState)
jlind6 0:356124c0bafc 57 {
jlind6 0:356124c0bafc 58 case WAIT:
jlind6 0:356124c0bafc 59 gameState = GAME_SETUP;
jlind6 0:356124c0bafc 60 break;
jlind6 0:356124c0bafc 61 case GAME:
jlind6 0:356124c0bafc 62 if(cornerY < 127 - paddleMove - length){
jlind6 0:356124c0bafc 63 cornerY += paddleMove;
jlind6 0:356124c0bafc 64 }
jlind6 0:356124c0bafc 65 break;
jlind6 0:356124c0bafc 66 }
jlind6 0:356124c0bafc 67 }
jlind6 0:356124c0bafc 68
jlind6 0:356124c0bafc 69 int main()
jlind6 0:356124c0bafc 70 {
jlind6 0:356124c0bafc 71 // This is setting up the pushbuttons
jlind6 0:356124c0bafc 72 // Don't modify this code.
jlind6 0:356124c0bafc 73 pbUp.mode(PullUp);
jlind6 0:356124c0bafc 74 pbDown.mode(PullUp);
jlind6 0:356124c0bafc 75 wait(0.1);
jlind6 0:356124c0bafc 76 pbUp.attach_deasserted(&pbUp_hit_callback);
jlind6 0:356124c0bafc 77 pbDown.attach_deasserted(&pbDown_hit_callback);
jlind6 0:356124c0bafc 78 pbUp.setSampleFrequency();
jlind6 0:356124c0bafc 79 pbDown.setSampleFrequency();
jlind6 0:356124c0bafc 80 // Don't modify this code.
jlind6 0:356124c0bafc 81
jlind6 0:356124c0bafc 82 uLCD.display_control(PORTRAIT);
jlind6 0:356124c0bafc 83 uLCD.cls();
jlind6 0:356124c0bafc 84 uLCD.baudrate(BAUD_3000000);
jlind6 0:356124c0bafc 85 uLCD.background_color(BLACK);
jlind6 0:356124c0bafc 86
jlind6 0:356124c0bafc 87 // Initialize all your variables outside the while/switch statement
jlind6 0:356124c0bafc 88 // to avoid compiler warning/errors
jlind6 0:356124c0bafc 89 int vxSign = 1, vySign = 1;
jlind6 0:356124c0bafc 90 float fx=50.0,fy=21.0,vx=1.6,vy=1.2;
jlind6 0:356124c0bafc 91 int x=50, y=21, radius=5;
jlind6 0:356124c0bafc 92 int score = 0;
jlind6 0:356124c0bafc 93 int i = 0;
jlind6 0:356124c0bafc 94 int random;
jlind6 0:356124c0bafc 95
jlind6 0:356124c0bafc 96 while (1)
jlind6 0:356124c0bafc 97 {
jlind6 0:356124c0bafc 98 switch (gameState)
jlind6 0:356124c0bafc 99 {
jlind6 0:356124c0bafc 100 case START:
jlind6 0:356124c0bafc 101 uLCD.cls();
jlind6 0:356124c0bafc 102 uLCD.locate(0,0);
jlind6 0:356124c0bafc 103 uLCD.printf("Pong!!!\n\n");
jlind6 0:356124c0bafc 104 uLCD.printf("Press Key to Start");
jlind6 0:356124c0bafc 105 gameState = WAIT;
jlind6 0:356124c0bafc 106 break;
jlind6 0:356124c0bafc 107 case GAME_SETUP:
jlind6 0:356124c0bafc 108 uLCD.cls();
jlind6 0:356124c0bafc 109 uLCD.line(0, 0, 127, 0, 0xCFB53B);
jlind6 0:356124c0bafc 110 uLCD.line(127, 0, 127, 127, 0xCFB53B);
jlind6 0:356124c0bafc 111 uLCD.line(127, 127, 0, 127, 0xCFB53B);
jlind6 0:356124c0bafc 112 uLCD.line(0, 127, 0, 0, 0xCFB53B);
jlind6 0:356124c0bafc 113 vx = 1.6;
jlind6 0:356124c0bafc 114 vy = 1.2;
jlind6 0:356124c0bafc 115 srand(i);
jlind6 0:356124c0bafc 116 random = (rand() % (118 - 2*radius)) + radius;
jlind6 0:356124c0bafc 117 fx = random;
jlind6 0:356124c0bafc 118 random = (rand() % (127 - 2*radius)) + radius;
jlind6 0:356124c0bafc 119 fy = random;
jlind6 0:356124c0bafc 120 x=(int)fx; y=(int)fy;
jlind6 0:356124c0bafc 121 random = rand() % 1;
jlind6 0:356124c0bafc 122 vxSign=-1; vySign=((float)random - 0.5)*2;
jlind6 0:356124c0bafc 123 uLCD.filled_rectangle(cornerX, cornerY, cornerX+width, cornerY+length, BLUE);
jlind6 0:356124c0bafc 124 gameState = GAME;
jlind6 0:356124c0bafc 125 break;
jlind6 0:356124c0bafc 126 case GAME:
jlind6 0:356124c0bafc 127 if ((fx+vxSign*vx<=radius+1))
jlind6 0:356124c0bafc 128 {
jlind6 0:356124c0bafc 129 vxSign = -vxSign;
jlind6 0:356124c0bafc 130 }
jlind6 0:356124c0bafc 131 if ((fy+vySign*vy<=radius+1) || (fy+vySign*vy>=126-radius))
jlind6 0:356124c0bafc 132 {
jlind6 0:356124c0bafc 133 vySign = -vySign;
jlind6 0:356124c0bafc 134 }
jlind6 0:356124c0bafc 135 if (((fx+vxSign*vx >= cornerX) && (fx+vxSign*vy <= cornerX+3)) &&
jlind6 0:356124c0bafc 136 ((fy+vySign*vy>=cornerY) && (fy+vySign*vy<=cornerY+length)))
jlind6 0:356124c0bafc 137 {
jlind6 0:356124c0bafc 138 vySign = -vySign;
jlind6 0:356124c0bafc 139 }
jlind6 0:356124c0bafc 140 if ((fx+vxSign*vx>=126-radius))
jlind6 0:356124c0bafc 141 {
jlind6 0:356124c0bafc 142 vx = 0;
jlind6 0:356124c0bafc 143 vy = 0;
jlind6 0:356124c0bafc 144 gameState = LOSE;
jlind6 0:356124c0bafc 145 }
jlind6 0:356124c0bafc 146 if ((fx+vxSign*vx>=cornerX-radius) && (fy+vySign*vy<=cornerY+length) && (fy+vySign*vy>=cornerY))
jlind6 0:356124c0bafc 147 {
jlind6 0:356124c0bafc 148 vxSign = -vxSign;
jlind6 0:356124c0bafc 149 score++;
jlind6 0:356124c0bafc 150 uLCD.locate(1,1);
jlind6 0:356124c0bafc 151 uLCD.printf("%d", score);
jlind6 0:356124c0bafc 152 }
jlind6 0:356124c0bafc 153 uLCD.circle(x, y, radius, BLACK);
jlind6 0:356124c0bafc 154 fx=fx+(vxSign*vx);
jlind6 0:356124c0bafc 155 fy=fy+(vySign*vy);
jlind6 0:356124c0bafc 156 x=(int)fx;
jlind6 0:356124c0bafc 157 y=(int)fy;
jlind6 0:356124c0bafc 158 uLCD.circle(x, y, radius, WHITE);
jlind6 0:356124c0bafc 159 // We can assume that these for loops are quick enough that the paddle will move only one interval.
jlind6 0:356124c0bafc 160 // These movements of the paddle have been optimized. Feel free to draw it out to see how it's been done.
jlind6 0:356124c0bafc 161 if(oldCornerY > cornerY) {
jlind6 0:356124c0bafc 162 uLCD.filled_rectangle(cornerX, oldCornerY-paddleMove+1, cornerX+width, oldCornerY, BLUE);
jlind6 0:356124c0bafc 163 uLCD.filled_rectangle(cornerX, oldCornerY+length-paddleMove+1, cornerX+width, oldCornerY+length, BLACK);
jlind6 0:356124c0bafc 164 oldCornerY = cornerY;
jlind6 0:356124c0bafc 165 }
jlind6 0:356124c0bafc 166 else if(oldCornerY < cornerY) {
jlind6 0:356124c0bafc 167 uLCD.filled_rectangle(cornerX, oldCornerY, cornerX+width, oldCornerY+paddleMove, BLACK);
jlind6 0:356124c0bafc 168 uLCD.filled_rectangle(cornerX, oldCornerY+length, cornerX+width, oldCornerY+length+paddleMove, BLUE);
jlind6 0:356124c0bafc 169 oldCornerY = cornerY;
jlind6 0:356124c0bafc 170 }
jlind6 0:356124c0bafc 171 break;
jlind6 0:356124c0bafc 172 case LOSE:
jlind6 0:356124c0bafc 173 uLCD.cls();
jlind6 0:356124c0bafc 174 uLCD.printf("YOU LOSE D:");
jlind6 0:356124c0bafc 175 score = 0;
jlind6 0:356124c0bafc 176 wait(5.0);
jlind6 0:356124c0bafc 177 gameState = START;
jlind6 0:356124c0bafc 178 break;
jlind6 0:356124c0bafc 179 case WAIT:
jlind6 0:356124c0bafc 180 // Used to seed the rand() function so we don't get the same starting position every time.
jlind6 0:356124c0bafc 181 i++;
jlind6 0:356124c0bafc 182 break;
jlind6 0:356124c0bafc 183 }
jlind6 0:356124c0bafc 184 }
jlind6 0:356124c0bafc 185 }