Initial publish

Dependencies:   mbed

Fork of el17dg by Dmitrijs Griskovs

game/game.cpp

Committer:
Noximilien
Date:
2019-03-18
Revision:
14:e8de27c4d0d4
Parent:
13:5c3dc6e827c2
Child:
15:0145c5f0bea1

File content as of revision 14:e8de27c4d0d4:



#include "mbed.h"
#include "N5110.h"
#include "Gamepad.h"

#include "models.h"
#include "main.h"
#include "game.h"

int x_ship_pos = 0;
int y_ship_pos = 24;
int small_star_delay = 0;

const int ship_speed = 2;
const int small_star_delay_max = 3;


struct GameObject {
    int x;
    int y;
    bool active;
};

struct Enemy : public GameObject {
    bool dead;
    int dead_counter;
};

#define MAX_BLASTS (5)
GameObject blasts[MAX_BLASTS];
const float blast_collision_radius = 1;
const float blast_collision_offset_x = 1;
const float blast_collision_offset_y = 0;

#define MAX_SMALL_STARS (5)
GameObject small_stars[MAX_SMALL_STARS];

#define MAX_MEDIUM_STARS (10)
GameObject medium_stars[MAX_MEDIUM_STARS];

#define MAX_ENEMIES (1)
Enemy enemies[MAX_ENEMIES];
const float enemy_collision_radius = 8;
const float enemy_collision_offset_x = 5;
const float enemy_collision_offset_y = 3;

int game_score = 0;


GameObject player;

void spawnNewEnemy() {
    int found = -1;
    for (int i = 0; i < MAX_ENEMIES; ++i) {
        if (!enemies[i].active) {
            found = i;
            break;
        }
    }
    
    if (found != -1) {
        enemies[found].dead = false;
        enemies[found].active = true;
        enemies[found].x = screen_width;
        enemies[found].y = rand() % (screen_height - enemy2_height);

    }
}

void updateAndDrawEnemies() {
    const int enemy_speed = 2;
    for (int i = 0; i < MAX_ENEMIES; ++i) {
        if (enemies[i].active){
            enemies[i].x -= enemy_speed;
            if (!enemies[i].dead) {
                lcd.drawSprite(enemies[i].x, enemies[i].y, 7, 11, (int*)enemyShip2);
            } 
            if (enemies[i].x < 0){
                enemies[i].active = false;
            }
            else {
                if (enemies[i].dead_counter > 0) {
                    enemies[i].dead_counter--;
                    if (enemies[i].dead_counter == 2){    
                        lcd.drawSprite(enemies[i].x, enemies[i].y, 7, 11, (int*)enemyHalfExploded);
                    }
                    else if (enemies[i].dead_counter == 1){
                        lcd.drawSprite(enemies[i].x, enemies[i].y, 7, 11, (int*)enemyExploded);
                        game_score += 30;
                    }
                else {
                    enemies[i].active = false;
                }
            }
            }
        }
    }
}

void updateAndDrawBlasts() {
    const int blast_speed = 5;
    for (int i = 0; i < MAX_BLASTS; ++i) {
        if (blasts[i].active) {
            blasts[i].x += blast_speed;
            if (blasts[i].x >= screen_width){
                blasts[i].active = false;
            }
            lcd.setPixel(blasts[i].x, blasts[i].y, 1);
            lcd.setPixel(blasts[i].x+1, blasts[i].y, 1);
            lcd.setPixel(blasts[i].x+2, blasts[i].y, 1);
        }
    }
}

void fireNewBlast() {
    // Search the array of blasts if inactive we can use it.
    int found = -1;
    for (int i = 0; i < MAX_BLASTS; ++i) {
        if (!blasts[i].active) {
            found = i;
            break;
        }
    }
    
    if (found != -1) {
        blasts[found].active = true;
        blasts[found].x = x_ship_pos + spaceship1_width;
        blasts[found].y = y_ship_pos + (spaceship1_height/2);
    }
}

inline bool circleCollideTwoObjects(
    int x1, int y1, float r1, float offset_x1, float offset_y1,
    int x2, int y2, float r2, float offset_x2, float offset_y2
) {
    int distance = pow((x1 + offset_x1) - (x2 + offset_x2), 2) + pow((y1 + offset_y1) - (y2 + offset_y2), 2);
    return distance <= pow(r1 + r2, 2);
}

void collideEnemiesAndBlasts() {
    for (int i = 0; i < MAX_ENEMIES; ++i) {
        for (int j = 0; j < MAX_BLASTS; ++j) {
            if (enemies[i].active && !enemies[i].dead && blasts[j].active) {
                bool collision = circleCollideTwoObjects(
                    enemies[i].x, enemies[i].y, enemy_collision_radius, enemy_collision_offset_x, enemy_collision_offset_y,
                    blasts[j].x, blasts[j].y, blast_collision_radius, blast_collision_offset_x, blast_collision_offset_y
                );
                if (collision) {
                    enemies[i].dead = true;
                    enemies[i].dead_counter = 3;
                    blasts[j].active = false;
                }
            }
        }
    }
}

void newSmallStarFlies() {
    // Search the array of stars if inactive we can use it. - the same as with blasts
    int found = -1;
    for (int i = 0; i < MAX_SMALL_STARS; ++i) {
        if (!small_stars[i].active) {
            found = i;
            break;
        }
    }
    
    if (found != -1) {
        small_stars[found].active = true;
        small_stars[found].x = screen_width;
        small_stars[found].y = rand() % screen_height;
    }
}

void updateAndDrawSmallStars(){
    const int small_star_speed = 5;
    for (int i = 0; i < MAX_SMALL_STARS; ++i) {
        if (small_stars[i].active) {
            small_stars[i].x -= small_star_speed;
            if (small_stars[i].x <= 0){
                small_stars[i].active = false;   
            }
            lcd.drawSprite(small_stars[i].x, small_stars[i].y, 3, 3, (int*)starSmall);
        }
    }
}

void newMediumStarFlies() {
    // Search the array of stars if inactive we can use it. - the same as with blasts
    int found = -1;
    for (int i = 0; i < MAX_MEDIUM_STARS; ++i) {
        if (!medium_stars[i].active) {
            found = i;
            break;
        }
    }
    
    if (found != -1) {
        medium_stars[found].active = true;
        medium_stars[found].x = screen_width;
        medium_stars[found].y =rand() % screen_height;
    }
}

void updateAndDrawMediumStars(){
    const int medium_star_speed = 5;
    for (int i = 0; i < MAX_MEDIUM_STARS; ++i) {
        if (medium_stars[i].active) {
            medium_stars[i].x -= medium_star_speed;
            if (medium_stars[i].x <= -2){
                medium_stars[i].active = false;   
            }
            lcd.drawSprite(medium_stars[i].x, medium_stars[i].y, 5, 5, (int*)starMedium);
        }
    }
}

void shipMovment(){           // The position of the ship
        
    if(x_ship_pos <= 48 && x_ship_pos >= 0){
        if(x_dir.read() > 0.6f){
           x_ship_pos -= ship_speed;
        }
        else if(x_dir.read() < 0.4f){
           x_ship_pos += ship_speed;
        }
    } 
    
    else if (x_ship_pos <= 48){ x_ship_pos = 0;}     //Limits for x direction border IMPROVE IF POSSIBLE.
    else { x_ship_pos = 48;}
    
    
    if (y_ship_pos <= (47 - spaceship1_height) && y_ship_pos >= 0){
        if(y_dir.read() > 0.6f){
           y_ship_pos -= ship_speed; 
        }
        else if(y_dir.read() < 0.4f){
           y_ship_pos += ship_speed; 
        }
    }
    else if (y_ship_pos >= (47 - spaceship1_height)){   //Limits for y direction border IMPROVE IF POSSIBLE.
        y_ship_pos = 47 - spaceship1_height;
    } 
    else if (y_ship_pos < 0){ 
        y_ship_pos = 0;
    }      
}

void highScore(){
    char buffer[4];
    sprintf(buffer," Score: %i",game_score);
    //printf(buffer);
    lcd.printString(buffer,0,0);    
}

bool Game::updateAndDraw() {

    shipMovment();
    
    if (gamepad.check_event(gamepad.B_PRESSED)){
        fireNewBlast();
    }
    if  (small_star_delay == small_star_delay_max){ 
        //This is dealy between small stars generation.
        newSmallStarFlies();
        newMediumStarFlies();
        spawnNewEnemy();
        
        small_star_delay = 0;
    }
    else {
        small_star_delay += 1;
    }
    
    updateAndDrawBlasts();
    updateAndDrawSmallStars();
    updateAndDrawMediumStars();
    updateAndDrawEnemies();
    collideEnemiesAndBlasts();
    highScore();
    
    lcd.drawSpriteOnTop(x_ship_pos, y_ship_pos, spaceship1_width, spaceship1_height, (int *)spaceShip1);
    /*char buffer[4];
    sprintf(buffer,"%i\n",(int)(x_dir.read()*84));
    printf(buffer);*/
    
    bool want_to_pause = false;
    if (gamepad.check_event(gamepad.START_PRESSED)){
        
        want_to_pause = true;
    }
    return want_to_pause;
}