mini project

Dependencies:   4DGL-uLCD-SE mbed

main.cpp

Committer:
qfruhauf
Date:
2014-10-21
Revision:
0:30c7c184a9c9

File content as of revision 0:30c7c184a9c9:

#include "mbed.h"
#include "uLCD_4DGL.h"

uLCD_4DGL uLCD(p28, p27, p29); // create a global lcd object
DigitalIn moveRight(p10);
DigitalIn moveLeft(p11);
DigitalIn pause(p12);
DigitalIn resetButton(p13);

/**Directions:

Start the game by pressing pause button (p12)
Push moveRight (p10) to move bottom rectangle right
Push moveLeft (p11) to move bottom rectangle left
Push pause to pause the game at any time
Push resetButton (p13) to reset to game

The game automatically resets when player loses or wins.
Win by destroying all the blocks at the top
Lose by letting the ball fall off bottom of screen

**/



//LCD is 127x127

#define RADIUS 5                //Ball size
#define NUMBER_OF_BLOCKS 10     //Number of blocks to break
#define X_BALL_START 20         //X starting location of ball
#define Y_BALL_START 50         //Y starting location of ball

#define X_START_RECT 53         //X starting location of rectangle
#define X_END_RECT 72           //X ending location of rectangle
#define Y_START_RECT 121        //Y starting location of rectangle 
#define Y_END_RECT 126          //Y ending location of rectangle 

//Initialize global values that control rectangle, ball and rate of ball
int x1Rec = X_START_RECT, x2Rec = X_END_RECT, xBall = X_BALL_START, yBall = Y_BALL_START, vX = -1, vY = 1;


//Value 0 or 1 ***** 1 means block at location is alive
int numOfBlocks [NUMBER_OF_BLOCKS]; 
int countBlocksDisappeared = 0;     //Keeps track of number of blocks

void play();
void pauseGame();
void reset();
void createStartingBlocks();
void checkHit(int index, int x1, int x2, int y1, int y2);
void hitDirection();

int main() {
    
    uLCD.baudrate(3000000);
    moveRight.mode(PullUp);
    moveLeft.mode(PullUp);
    pause.mode(PullUp);
    resetButton.mode(PullUp);

    //Draw outline boundaries
    uLCD.line(0, 0, 127, 0, WHITE);         //top
    uLCD.line(127, 0, 127, 127, WHITE);     //right
    uLCD.line(127, 127, 0, 127, WHITE);     //bottom
    uLCD.line(0, 127, 0, 0, WHITE);         //left

    //Draw Ball starting location
    uLCD.filled_circle(X_BALL_START, Y_BALL_START, RADIUS, RED);
        
    //Draw Rectangle starting location
    uLCD.filled_rectangle(X_START_RECT, Y_START_RECT, X_END_RECT, Y_END_RECT, WHITE);
    
    //Validate the blocks
    createStartingBlocks();
    
    while(1) {
        if(!pause){
            wait(.5);
            play();
        }
    }
}

void play()
{
    while(1){    
        
        //Move rectangle left - up to boundary
        if(!moveLeft && x1Rec > 2){
            //Erase current rectangle
            uLCD.filled_rectangle(x1Rec, Y_START_RECT, x2Rec, Y_END_RECT, BLACK);
            
            //Draw new rectangle
            x1Rec -=4;
            x2Rec -=4;
            uLCD.filled_rectangle(x1Rec, Y_START_RECT, x2Rec, Y_END_RECT, WHITE);
        }
        
        //Move rectangle right - up to boundary
        if(!moveRight && x2Rec < 125){
            //Erase current rectangle
            uLCD.filled_rectangle(x1Rec, Y_START_RECT, x2Rec, Y_END_RECT, BLACK);
            
            //Draw new rectangle
            x1Rec +=4;
            x2Rec +=4;
            uLCD.filled_rectangle(x1Rec, Y_START_RECT, x2Rec, Y_END_RECT, WHITE);
        }
    
        //Draw ball 
        uLCD.filled_circle(xBall, yBall, RADIUS, RED);  
        //Erase ball
        uLCD.filled_circle(xBall, yBall, RADIUS, BLACK);
           
        //Check if hit bottom rectangle
        if(yBall + RADIUS == 121 && (xBall - RADIUS <= x2Rec && xBall + RADIUS >= x1Rec))
        {
            //flip y direction
            vY = vY*(-1);
            hitDirection();
        }
        
        //Check if hit layer 1
        if(yBall - RADIUS >= 1 && yBall - RADIUS <= 6)
        {
            checkHit(0, 43, 52, 1, 6);
            checkHit(1, 53, 62, 1, 6);
            checkHit(2, 63, 72, 1, 6);
            checkHit(3, 73, 82, 1, 6);
        }

        //Check if hit layer 2
        if(yBall - RADIUS >= 7 && yBall - RADIUS <= 12)
        {
            checkHit(4, 48, 57, 7, 12);
            checkHit(5, 58, 67, 7, 12);
            checkHit(6, 68, 77, 7, 12);
        }
        //Check if hit layer 3
        if(yBall - RADIUS >= 13 && yBall - RADIUS <= 18)
        {
            checkHit(7, 53, 62, 13, 18);
            checkHit(8, 63, 72, 13, 18);
        }
        //Check if hit layer 4
        if(yBall - RADIUS >= 19 && yBall - RADIUS <= 24)
            checkHit(9, 58, 67, 19, 24);
        
        //Check if ball hit left or right wall
        if(xBall <= RADIUS + 1 || xBall >= 126 - RADIUS)
            vX = vX*(-1);
        
        //Check if hit top wall 
        if(yBall <= RADIUS + 1)
            vY = vY*(-1);
            
        //Check if lose
        if(yBall >= 126 - RADIUS)
        {
            //Wipe screen and print lose with large font
            wait(1);
            uLCD.cls();
            uLCD.locate(0,5);
            uLCD.text_width(2);
            uLCD.text_height(2);
            uLCD.printf("YOU LOSE!");
            wait(5);
            reset();
        }
        
        //Move ball
        xBall += vX;
        yBall += vY;
        
        //Pause game
        if(!pause)
            pauseGame();
        
        //Reset game
        if(!resetButton)
            reset();
         
        //Check for win    
        if(countBlocksDisappeared == 10)
        {
            //Wipe screen and print win with large font
            wait(1);
            uLCD.cls();
            uLCD.locate(0,5);
            uLCD.text_width(2);
            uLCD.text_height(2);
            uLCD.printf("YOU WIN!");
            wait(5);
            reset();
        }            
    }
}

void pauseGame()
{
    //Ensure user has time to stop pressing button
    wait(1);
    
    //Spin until unpause
    while(pause){}
    
    //Give a little time to adjust
    wait(.5);
}

void reset()
{
    //Wipe Screen
    uLCD.cls();
    
    //Draw outline boundaries
    uLCD.line(0, 0, 127, 0, WHITE);         //top
    uLCD.line(127, 0, 127, 127, WHITE);     //right
    uLCD.line(127, 127, 0, 127, WHITE);     //bottom
    uLCD.line(0, 127, 0, 0, WHITE);         //left
    
    //restore init conditions
    x1Rec = X_START_RECT;  
    x2Rec = X_END_RECT;  
    xBall = X_BALL_START;
    yBall = Y_BALL_START;
    vX = -1;
    vY = 1;
    
    //Draw Ball starting location
    uLCD.filled_circle(xBall, yBall, RADIUS, RED);
        
    //Draw Rectangle starting location
    uLCD.filled_rectangle(x1Rec, Y_START_RECT, x2Rec, Y_END_RECT, WHITE);
    
    createStartingBlocks();
    
    //Press pause button to restart game 
    pauseGame();
}

void createStartingBlocks()
{
    /**Draw Blocks */
    //Layer 1
    uLCD.filled_rectangle(43, 1, 52, 6, WHITE);
    uLCD.filled_rectangle(53, 1, 62, 6, WHITE);
    uLCD.filled_rectangle(63, 1, 72, 6, WHITE);
    uLCD.filled_rectangle(73, 1, 82, 6, WHITE);
    
    //Layer 2
    uLCD.filled_rectangle(48, 7, 57, 12, WHITE);
    uLCD.filled_rectangle(58, 7, 67, 12, WHITE);
    uLCD.filled_rectangle(68, 7, 77, 12, WHITE);
    
    //Layer 3
    uLCD.filled_rectangle(53, 13, 62, 18, WHITE);
    uLCD.filled_rectangle(63, 13, 72, 18, WHITE);
    
    //Layer 4
    uLCD.filled_rectangle(58, 19, 67, 24, WHITE);
    
    //Set validator
    countBlocksDisappeared = 0;
    for(int i = 0; i<NUMBER_OF_BLOCKS; i++)
        numOfBlocks[i] = 1;
}

void checkHit(int index, int x1, int x2, int y1, int y2)
{
    //Check block if active
    if(numOfBlocks[index] == 1 && xBall - RADIUS <= x2 && xBall + RADIUS >= x1)
    {
        //Inactivate block
        numOfBlocks[index] = 0;
        countBlocksDisappeared++;
        //Flip y direction of ball
        vY = vY*(-1);
        //Erase rectangle
        uLCD.filled_rectangle(x1, y1, x2, y2, BLACK);
        //Check if necessary to flip x direction of ball
        hitDirection();
    }
}

void hitDirection()
{
    //Comes from right
    if(xBall - vX > xBall)
    {
        //Check if x direction  
        if(xBall > (x1Rec+x2Rec)/2)
            vX = vX*(-1);
    }
    
    //Comes from left
    if(xBall - vX < xBall)
    {
        //Check if x direction  
        if(xBall < (x1Rec+x2Rec)/2)
            vX = vX*(-1);
    }
}