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

main.cpp

Committer:
jlind6
Date:
2014-06-17
Revision:
0:356124c0bafc
Child:
2:6163865f5ce3

File content as of revision 0:356124c0bafc:

#include "mbed.h"
#include "PinDetect.h"
#include "uLCD_4DGL.h"
#include "Speaker.h"

// Pushbuttons
PinDetect pbUp(p15); 
PinDetect pbDown(p16);
// uLCD
uLCD_4DGL uLCD(p28, p27, p29);
//Speaker
Speaker mySpeaker(p21);
 
// Global variables needed for the push button interrupts
int cornerX = 118, cornerY = 1;
int oldCornerY = 1;
int paddleMove = 8;
int length = 40;
int width = 3;
 
// State machine definitions
enum gameStateType {START, WAIT, GAME_SETUP, GAME, LOSE};
/* State Definitions:
 * START -- Creates the start screen
 * WAIT -- After the start screen, goes into wait where mbed spins and does nothing
 * GAME_SETUP -- Sets up one time things (like boarders, initializes beginning velocity
 * GAME -- When the user actually gets to play
 * LOSE -- clears the screen, prints you lose, waits, then goes back to start
 */
 
// Global state machine variable (So that the pushbuttons can modify it)
gameStateType gameState = START;

// Pushbutton callbacks
// WARNING: Do not call to draw anything to the uLCD in these
// as this will cause the uLCD to crash sometimes. Update positions
// and draw elsewhere (like it's done here).
// Only modify the logic inside the callback functions.
void pbUp_hit_callback (void)
{
    switch (gameState)
    {
    case WAIT:
        gameState = GAME_SETUP;
        break;
    case GAME:  
        if(cornerY > paddleMove) {
            cornerY -= paddleMove;
        }
        break;
    }
}
 
void pbDown_hit_callback (void)
{
    switch (gameState)
    {
    case WAIT:
        gameState = GAME_SETUP;
        break;
    case GAME:
        if(cornerY < 127 - paddleMove - length){
            cornerY += paddleMove;
        }
        break;
    }
}
 
int main() 
{   
    // This is setting up the pushbuttons
    // Don't modify this code.
    pbUp.mode(PullUp);
    pbDown.mode(PullUp);
    wait(0.1);
    pbUp.attach_deasserted(&pbUp_hit_callback);
    pbDown.attach_deasserted(&pbDown_hit_callback);
    pbUp.setSampleFrequency();
    pbDown.setSampleFrequency();
    // Don't modify this code.
    
    uLCD.display_control(PORTRAIT);
    uLCD.cls();
    uLCD.baudrate(BAUD_3000000);
    uLCD.background_color(BLACK);

    // Initialize all your variables outside the while/switch statement
    // to avoid compiler warning/errors
    int vxSign = 1, vySign = 1;
    float fx=50.0,fy=21.0,vx=1.6,vy=1.2;
    int x=50, y=21, radius=5;
    int score = 0;
    int i = 0;
    int random;
 
    while (1) 
    {   
        switch (gameState)
        {
        case START:
            uLCD.cls();
            uLCD.locate(0,0);
            uLCD.printf("Pong!!!\n\n");
            uLCD.printf("Press Key to Start");
            gameState = WAIT;
            break;
        case GAME_SETUP:
            uLCD.cls();
            uLCD.line(0, 0, 127, 0, 0xCFB53B);
            uLCD.line(127, 0, 127, 127, 0xCFB53B);
            uLCD.line(127, 127, 0, 127, 0xCFB53B);
            uLCD.line(0, 127, 0, 0, 0xCFB53B);
            vx = 1.6;
            vy = 1.2;
            srand(i);
            random = (rand() % (118 - 2*radius)) + radius; 
            fx = random;
            random = (rand() % (127 - 2*radius)) + radius;
            fy = random;
            x=(int)fx; y=(int)fy;
            random = rand() % 1;
            vxSign=-1; vySign=((float)random - 0.5)*2;
            uLCD.filled_rectangle(cornerX, cornerY, cornerX+width, cornerY+length, BLUE);
            gameState = GAME;
            break;
        case GAME:
            if ((fx+vxSign*vx<=radius+1)) 
            {
                vxSign = -vxSign;
            }
            if ((fy+vySign*vy<=radius+1) || (fy+vySign*vy>=126-radius)) 
            {
                vySign = -vySign;
            }
            if (((fx+vxSign*vx >= cornerX) && (fx+vxSign*vy <= cornerX+3)) && 
                ((fy+vySign*vy>=cornerY) && (fy+vySign*vy<=cornerY+length))) 
            {
                vySign = -vySign;
            }
            if ((fx+vxSign*vx>=126-radius)) 
            {
                vx = 0;
                vy = 0;
                gameState = LOSE;
            }
            if ((fx+vxSign*vx>=cornerX-radius) && (fy+vySign*vy<=cornerY+length) && (fy+vySign*vy>=cornerY)) 
            {
                vxSign = -vxSign;
                score++;
                uLCD.locate(1,1);
                uLCD.printf("%d", score);
            }
            uLCD.circle(x, y, radius, BLACK);
            fx=fx+(vxSign*vx);
            fy=fy+(vySign*vy);
            x=(int)fx;
            y=(int)fy;
            uLCD.circle(x, y, radius, WHITE);
            // We can assume that these for loops are quick enough that the paddle will move only one interval.
            // These movements of the paddle have been optimized. Feel free to draw it out to see how it's been done.
            if(oldCornerY > cornerY) {
                uLCD.filled_rectangle(cornerX, oldCornerY-paddleMove+1, cornerX+width, oldCornerY, BLUE);
                uLCD.filled_rectangle(cornerX, oldCornerY+length-paddleMove+1, cornerX+width, oldCornerY+length, BLACK);
                oldCornerY = cornerY;
            }
            else if(oldCornerY < cornerY) {
                uLCD.filled_rectangle(cornerX, oldCornerY, cornerX+width, oldCornerY+paddleMove, BLACK);
                uLCD.filled_rectangle(cornerX, oldCornerY+length, cornerX+width, oldCornerY+length+paddleMove, BLUE);
                oldCornerY = cornerY;
            }
            break;
        case LOSE:
            uLCD.cls();
            uLCD.printf("YOU LOSE D:");
            score = 0;
            wait(5.0);
            gameState = START;
            break;
        case WAIT:
            // Used to seed the rand() function so we don't get the same starting position every time.
            i++; 
            break;
        }
    } 
}