test test test

Dependencies:   mbed

snake-test/ELEC2645_ProjecT/Snake/SnakeEngine.cpp

Committer:
mohamedmoawya
Date:
2020-05-25
Revision:
0:e4c5e6ec922e

File content as of revision 0:e4c5e6ec922e:

#include "SnakeEngine.h"
SnakeEngine::SnakeEngine(Gamepad &pad, N5110 &display):gamePad(pad), lcd(display){
    
}
SnakeEngine::~SnakeEngine(){

}

void SnakeEngine::drawSnake(){
    for(int i=0;i<snakeSize;i++)
        lcd.drawRect(snake[i].X,snake[i].Y,gameObjectSize,gameObjectSize,FILL_BLACK);

}

void SnakeEngine::drawFood(){
    lcd.drawRect(food.X,food.Y,gameObjectSize,gameObjectSize,FILL_BLACK);

}

void SnakeEngine::drawScore(){
    char buffer1[14];
    sprintf(buffer1,"S:%2d      H:%2d",gameScore,gameLife);
    lcd.printString(buffer1,0,0);
}

void SnakeEngine::drawGameFrame(){
    lcd.clear();
    drawScore();
    lcd.drawLine(0,10,83,10,1);
    drawSnake();
    drawFood();
    lcd.refresh();
}

void SnakeEngine::regenFood(){
    do{
        food.X = rand() % (AREA_X + 1 - 12) + 12;//random(2,AREA_X);
    } while(food.X % gameObjectSize != 0);
    do {
        food.Y = rand() % (AREA_Y + 1 - 12) + 12;//random(2,AREA_Y);
    } while(food.Y % gameObjectSize != 0);
}

void SnakeEngine::isColliding(){
    //if snake is eating food
    if((snake[0].X == food.X) && (snake[0].Y == food.Y)){
        //turn on LEDs momentarily when eating food
        gamePad.leds_on();
        wait(0.1);
        gamePad.leds_off();
        //LED effect off
        snakeSize++; // grow snake
        gameScore++; //increase score
        regenFood(); // recreate snake food
    }
    else{ // snake is eating himself
        for(int i=1; i<snakeSize;i++){
            if((snake[0].X == snake[i].X) && (snake[0].Y == snake[i].Y)){
                gamePad.tone(1000.0,0.1);
                gameLife--;
                if(gameLife == 0)
                    state = GAMEOVER;
                else
                    state = NEWLIFE;
            }
        }
    }
/*
    //snake is going to hit a wall
    if((snake[0].X < AREA_X_min) || (snake[0].Y < AREA_Y_min) || (snake[0].X>AREA_X) || (snake[0].Y > AREA_Y)){
        gamePad.tone(1000.0,1);
        gameLife--;
        if(gameLife == 0)
            state = GAMEOVER;
        else
            state = NEWLIFE;
    }
    */
    /*******************update********************/
    //start
    if (snake[0].X <= AREA_X_min)
        snake[0].X = AREA_X;
    else if (snake[0].X >= AREA_X)
        snake[0].X = AREA_X_min;

    if (snake[0].Y <= AREA_Y_min)
        snake[0].Y = AREA_Y;
    else if (snake[0].Y >= AREA_Y)
        snake[0].Y = AREA_Y_min;
    //end

    /*******************update********************/
}



void SnakeEngine::setupGame(){
    snakeSize = 3; // initial size of the snake
    dirSnake = 1; // initialize snake direction
    //initialize snake body
    for(int i=1;i<snakeSize;i++){
        snake[i].X = 0;
        snake[i].Y = 0;
    }
    snake[0].X = 12;//head_x;
    snake[0].Y = AREA_Y_min;//head_y;

    // decide where the body of the sanke goes

    for(int i=1;i<snakeSize;i++){
        int dir = 0;//rand() % 4;//random(0,3);

        if(dir == 0){ // if the snake is facing left
            snake[i].X = snake[i-1].X - gameObjectSize;
            snake[i].Y = snake[i-1].Y;
        }
        else if(dir == 1){ // if the snake is facing right
            snake[i].X = snake[i-1].X + gameObjectSize;
            snake[i].Y = snake[i-1].Y;
        }
        else if(dir == 2){ // if snake is facing up
            snake[i].X = snake[i-1].X;
            snake[i].Y = snake[i-1].Y - gameObjectSize;
        }
        else if(dir == 3){
            snake[i].X = snake[i-1].X;
            snake[i].Y = snake[i-1].Y + gameObjectSize;
        }
    }

    //regenerate snake food
    regenFood();

    state = PAUSE; //  change the game state once setup
}

void SnakeEngine::readUserInput(){
    // read left button
    bLeft = gamePad.Y_pressed();
    //read right button
    bRight = gamePad.A_pressed();
    //read up button
    bUp = gamePad.X_pressed();
    //read down button
    bDown = gamePad.B_pressed();
}

void SnakeEngine::handleUserInput() {
    
    readUserInput();

    if((bLeft != false) && (dirSnake != 1))
        dirSnake = 0;
    if((bRight != false) && (dirSnake != 0))
        dirSnake = 1;
    if((bDown != false) && (dirSnake != 3))
        dirSnake = 2;
    if((bUp != false) && (dirSnake != 2))
        dirSnake = 3;
}

void SnakeEngine::updateGame(){
    //update body of the snake
    for(int i= snakeSize-1;i>0;i--){
        snake[i].X = snake[i-1].X;
        snake[i].Y = snake[i-1].Y;
    }

    // snake is moving left
    if(dirSnake == 0)
        snake[0].X -= gameObjectSize;
    else if(dirSnake == 1) // snake is moving right
        snake[0].X += gameObjectSize;
    else if(dirSnake == 2) // snake is moving up
        snake[0].Y += gameObjectSize; 
    else if(dirSnake == 3) // snake is moving down
        snake[0].Y -= gameObjectSize;
}

void SnakeEngine::playGame(){
    isColliding();
    if(state != NEWLIFE && state != GAMEOVER){
        handleUserInput();
        updateGame();
        drawGameFrame();
    }

    //clear game
    
}

void SnakeEngine::gameIsPaused(){
    readUserInput();

    // if paused, wait for a user input
    if((bLeft != false) || (bRight != false) || (bDown != false) || (bUp != false))
        state = INGAME;

    //redraw
    drawGameFrame();
}
void SnakeEngine::gameIsLost(){
    //redraw
    lcd.clear();
    lcd.printString("Game Over",0,1);
    char buffer1[14];
    sprintf(buffer1,"Score is %2d",gameScore);
    lcd.printString(buffer1,0,4);
    lcd.refresh();
    wait(5);
    state = SETUP;
    gameLife = 3;
    gameScore = 0;
}
void SnakeEngine::init() {
    dirSnake = 1;
    gameScore = 0;
    gameLife = 3;
    gameObjectSize = 4;
    snakeSize = 3;

    state = SETUP;

    bLeft = false;
    bRight = false;
    bDown = false;
    bUp = false;

    AREA_X = 82;
    AREA_Y = 46;
    AREA_X_min = 1;
    AREA_Y_min = 12;

    gameSpeed = 1;
}
void SnakeEngine::runGameEngine(){
    switch(state){
        case SETUP : setupGame(); break;
        case PAUSE: gameIsPaused(); break;
        case INGAME: playGame(); break;
        case NEWLIFE: setupGame(); break;
        case GAMEOVER:  gameIsLost(); 
                        welcome();
                        break;
    }
}

void SnakeEngine::welcome(){
    lcd.printString(" Great Snakes ",0,1);  
    lcd.printString("  Press Start ",0,4);
    lcd.refresh();
     
    // wait flashing LEDs until start button is pressed 
    while ( gamePad.start_pressed() == false) {
        lcd.setContrast( gamePad.read_pot1());
        gamePad.leds_on();
        wait(0.1);
        gamePad.leds_off();
        wait(0.1);
    }
    lcd.clear();
    char buffer1[14];
    sprintf(buffer1,"Speed: %2d",gameSpeed);
    lcd.printString(buffer1,5,1);
    lcd.printString("  Press Start ",0,5);
    lcd.refresh();
    
    //set snake speed menu 
    while ( gamePad.start_pressed() == false) {
        
        if(gamePad.B_pressed()){
            if(gameSpeed<4)
                gameSpeed++;
            lcd.clear();
            char buffer1[14];
            sprintf(buffer1,"Speed: %2d",gameSpeed);
            lcd.printString(buffer1,5,1);
            lcd.printString("  Press Start ",0,5);
            lcd.refresh();
        }
        if(gamePad.X_pressed()){
            if(gameSpeed !=1)
                gameSpeed--;
            lcd.clear();
            char buffer1[14];
            sprintf(buffer1,"Speed: %2d",gameSpeed);
            lcd.printString(buffer1,5,1);
            lcd.printString("  Press Start ",0,5);
            lcd.refresh();
        }
        wait(0.1);
    }
}
int SnakeEngine::getGameSpeed(){
    return gameSpeed;
}