This code contains the game Starship designed for the STM32F429i-DISC1 board. It requires a keyboard to play.

Dependencies:   Starship LCD_DISCO_F429ZI USBHost mbed

Dependents:   Starship

main.cpp

Committer:
Oshyrath
Date:
2017-11-17
Revision:
1:527a11035e0b
Parent:
0:c9afe145b57b

File content as of revision 1:527a11035e0b:

#include "main.h"
LCD_DISCO_F429ZI lcd;
DigitalOut led1(LED1);
enum Stage stage;
char pauseOrStartPressed;
char scoreText[100];
void onKey(uint8_t key,uint8_t mod) {//MODIFY THIS FUNC

    didUserRequestFire = mod;
    pauseOrStartPressed = 0;
    switch(key)
    {
        case KEY_UP:
            X_DIR = NO_DIR;
            Y_DIR = UP_DIR;
            break;
        case KEY_DOWN:
            X_DIR = NO_DIR;
            Y_DIR = DOWN_DIR;
            break;           
        case KEY_LEFT:
            X_DIR = LEFT_DIR;
            Y_DIR = NO_DIR;
            break;
        case KEY_RIGHT:
            X_DIR = RIGHT_DIR;
            Y_DIR = NO_DIR;
            break;
        case KEY_START:
            pauseOrStartPressed = 1;
            break;
    }
}
void keyboard_task(void const *) {
    
    USBHostKeyboard keyboard;
    
    while(1) {
        while(!keyboard.connect())
            Thread::wait(500);
    
      
        keyboard.attach(onKey);
        

        while(keyboard.connected())
            Thread::wait(500);
    }
}
void drawHealthBar(int16_t xPos,int16_t yPos,float percentage)
{
        yPos += 2; 
        int16_t width = (int16_t)(ENEMY_WIDTH*percentage);
        int16_t height = HEALTH_BAR_SIZE-2;
        lcd.SetTextColor(LCD_COLOR_RED);
        lcd.FillRect(xPos, yPos, width, height);
        lcd.FillRect(xPos, yPos, width, height);  
}
void drawPowerUps()
{
    int16_t radius = POWER_UP_SIZE/2;
    int j;
    for(j = powerUpCount; j;j--)
    {
            powerUpPTR=powerUpPTR->next;
            switch(powerUpPTR->type)
            {
                case PU_RapidFire:
                    lcd.SetTextColor(LCD_COLOR_ORANGE);
                    break;
                case PU_PowerShot:
                    lcd.SetTextColor(LCD_COLOR_RED);
                    break;
                case PU_FreezeEnemies:
                    lcd.SetTextColor(LCD_COLOR_LIGHTBLUE);
                    break;
                case PU_WideShot:
                    lcd.SetTextColor(LCD_COLOR_PURPLE);
                    break;
                case PU_Explosion:
                    lcd.SetTextColor(LCD_COLOR_YELLOW);
                    break;
                case PU_BonusHealth:
                    lcd.SetTextColor(LCD_COLOR_GREEN);
                    break;
                case PU_Shield:
                    lcd.SetTextColor(LCD_COLOR_WHITE);
                    break;                
            } 
 
        int16_t xPos = powerUpPTR->x_pos+radius;
        int16_t yPos = powerUpPTR->y_pos+radius;
 
        lcd.FillCircle(xPos,yPos,radius);
        lcd.FillCircle(xPos,yPos,radius);
    }
}
void drawPlayerBullets()
{
    int j;
    for(j = playerBulletCount; j;j--)
    {
        playerBulletPTR=playerBulletPTR->next;
        int16_t xPos = playerBulletPTR->x_pos;
        int16_t yPos = playerBulletPTR->y_pos;
        int16_t width = BULLET_SIZE;
        int16_t height = BULLET_SIZE;
        if(playerBulletPTR->powerShot)
            lcd.SetTextColor(LCD_COLOR_RED);
        else
            lcd.SetTextColor(LCD_COLOR_BLUE);
        lcd.FillRect(xPos, yPos, width, height);
        lcd.FillRect(xPos, yPos, width, height);
    }
}
void drawEnemyBullets()
{
    int i;
    for(i = enemyBulletCount; i;i--)
    {
        enemyBulletPTR = enemyBulletPTR->next;
        int16_t xPos = enemyBulletPTR->x_pos;
        int16_t yPos = enemyBulletPTR->y_pos;
        int16_t width = BULLET_SIZE;
        int16_t height = BULLET_SIZE;
        lcd.SetTextColor(LCD_COLOR_GREEN);
        lcd.FillRect(xPos, yPos, width, height);
        lcd.FillRect(xPos, yPos, width, height);
    }
}
void drawPlayer()
{

        
        lcd.SetTextColor(LCD_COLOR_BLUE);
        uint16_t x1 = player.x_pos;
        uint16_t x2 = player.x_pos + PLAYER_WIDTH;
        uint16_t x3 = player.x_pos + PLAYER_WIDTH/2;
        uint16_t y1 = player.y_pos + PLAYER_HEIGHT;
        uint16_t y2 = y1;
        uint16_t y3 = player.y_pos;
        if(player.shieldTimer)
        {
            lcd.SetTextColor(LCD_COLOR_WHITE);
            int16_t radius = PLAYER_HEIGHT/2+6;
            int16_t xPos = player.x_pos + PLAYER_WIDTH/2;
            int16_t yPos = player.y_pos + PLAYER_HEIGHT/2+3;
            if(yPos<radius)
                radius = yPos;
            lcd.FillCircle(xPos,yPos,radius);
            lcd.FillCircle(xPos,yPos,radius);
        }
        lcd.SetTextColor(LCD_COLOR_BLUE);
        lcd.FillTriangle(x1,x2,x3,y1,y2,y3);
        lcd.FillTriangle(x1,x2,x3,y1,y2,y3);
        int16_t xPos = player.x_pos;
        int16_t yPos = player.y_pos;
        drawHealthBar(xPos, yPos+PLAYER_HEIGHT,player.health/((float)PLAYER_STARTING_HEALTH));
}
void drawEnemies()
{
    lcd.SetTextColor(LCD_COLOR_GREEN);
    int i;
    for(i = enemyCount; i; i--)
    {    
        enemyPTR = enemyPTR->next;
        int16_t xPos = enemyPTR->x_pos;
        int16_t yPos = enemyPTR->y_pos;
                
        uint16_t x1 = enemyPTR->x_pos;
        uint16_t x2 = enemyPTR->x_pos+ENEMY_WIDTH;
        uint16_t x3 = enemyPTR->x_pos+ENEMY_WIDTH/2;
        uint16_t y1 = enemyPTR->y_pos;
        uint16_t y2 = y1;
        uint16_t y3 = enemyPTR->y_pos+ENEMY_HEIGHT;
        if(enemyPTR->freezeTimer)
            lcd.SetTextColor(LCD_COLOR_LIGHTBLUE);
        else
            lcd.SetTextColor(LCD_COLOR_GREEN); 
        lcd.FillTriangle(x1,x2,x3,y1,y2,y3);
        lcd.FillTriangle(x1,x2,x3,y1,y2,y3);      
        drawHealthBar(xPos, yPos+ENEMY_HEIGHT,enemyPTR->health/((float)enemyPTR->maxHealth));
    } 
}
void drawBackground()
{
    lcd.clear(LCD_COLOR_BLACK);
}
void drawScore()
{
    lcd.SetTextColor(LCD_COLOR_BLACK);
    sprintf(scoreText,"KILLS: %d/%d",levelScore,level*4+6);
    lcd.DisplayStringAt(0, LINE(0), (uint8_t *) scoreText, CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(0), (uint8_t *) scoreText, CENTER_MODE);
}
void drawAll()
{ 
    drawBackground();
    drawPowerUps();
    drawEnemies();
    drawEnemyBullets();
    drawPlayer();
    drawPlayerBullets();
    drawScore();
}
void drawGameOver()
{
    drawBackground();
    lcd.SetTextColor(LCD_COLOR_BLACK);
    lcd.DisplayStringAt(0, LINE(1), (uint8_t *) "GAME OVER", CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(1), (uint8_t *) "GAME OVER", CENTER_MODE);
    
    lcd.DisplayStringAt(0, LINE(2), (uint8_t *) "TOTAL KILLS", CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(2), (uint8_t *) "TOTAL KILLS", CENTER_MODE);
    
    sprintf(scoreText,"%d",totalScore);
    lcd.DisplayStringAt(0, LINE(3), (uint8_t *) scoreText, CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(3), (uint8_t *) scoreText, CENTER_MODE);     
}
void drawLostLife()
{
    drawBackground();
    lcd.SetTextColor(LCD_COLOR_BLACK);
    lcd.DisplayStringAt(0, LINE(1), (uint8_t *) "LOST A LIFE", CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(1), (uint8_t *) "LOST A LIFE", CENTER_MODE);
    
    lcd.DisplayStringAt(0, LINE(2), (uint8_t *) "LIVES LEFT:", CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(2), (uint8_t *) "LIVES LEFT:", CENTER_MODE);
    
    sprintf(scoreText,"%d",lives);
    lcd.DisplayStringAt(0, LINE(3), (uint8_t *) scoreText, CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(3), (uint8_t *) scoreText, CENTER_MODE);      
}
void drawPause()
{
    drawBackground();
    lcd.SetTextColor(LCD_COLOR_BLACK);
    lcd.DisplayStringAt(0, LINE(1), (uint8_t *) "PAUSE", CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(1), (uint8_t *) "PAUSE", CENTER_MODE);     
}
void drawLevelUp()
{
    drawBackground();
    lcd.SetTextColor(LCD_COLOR_BLACK);
    lcd.DisplayStringAt(0, LINE(1), (uint8_t *) "LEVEL UP", CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(1), (uint8_t *) "LEVEL UP", CENTER_MODE);  
}
void drawStart()
{
    drawBackground();
    lcd.SetTextColor(LCD_COLOR_BLACK);
    lcd.DisplayStringAt(0, LINE(1), (uint8_t *) "PRESS ENTER", CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(1), (uint8_t *) "PRESS ENTER", CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(2), (uint8_t *) "TO START", CENTER_MODE);
    lcd.DisplayStringAt(0, LINE(2), (uint8_t *) "TO START", CENTER_MODE);  
}
char checkPOSP()
{
    char ans = pauseOrStartPressed;
    pauseOrStartPressed = 0;
    return ans;
}
void startGame()
{
    newGame();
    newLevel();
    stage = Start;
    pauseOrStartPressed = 0;
    while(1)
    {
        switch(stage)
        {
            case Start:
                drawStart();
                if(checkPOSP())
                {
                    stage = Play;
                    break;
                }
                wait(GAME_WAIT_TIME);
                break;
            case Play:
                loopIteration();
                drawAll();
                if(checkPOSP())
                {
                    stage = Pause;
                    break;
                }
                if(didLoseLife())
                {
                    lives--;
                    stage = LostLife;
                    newLevel();
                    break;
                }
                if(didLevelUp())
                {
                    level++;
                    newLevel();
                    stage = NextLevel;
                    break;
                }
                wait(GAME_WAIT_TIME);
                break;            
            case Pause:
                drawPause();
                if(checkPOSP())
                {
                    stage = Play;
                    break;
                }
                wait(GAME_WAIT_TIME);
                break;
            case NextLevel:
                drawLevelUp();
                if(checkPOSP())
                {
                    stage = Play;
                    break;
                }
                wait(GAME_WAIT_TIME);
                break;
            case LostLife:
                drawLostLife();
                if(isGameOver())
                {
                    stage = GameOver;
                    newGame();
                    newLevel();
                    break;               
                }
                if(checkPOSP())
                    stage = Play;
                wait(GAME_WAIT_TIME);
                break;
            case GameOver:
                drawGameOver();
                if(checkPOSP())
                    stage = Play;
                wait(GAME_WAIT_TIME);
                break;
        }

    }    
}
int main()
{      
    led1 = 1;
  
    BSP_LCD_SetFont(&Font20);
    Thread keyboardTask(keyboard_task, NULL, osPriorityNormal, 1024 * 4);
    startGame();

}