Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of el17dg by
game/game.cpp
- Committer:
 - Noximilien
 - Date:
 - 2019-03-17
 - Revision:
 - 12:bfe3a3deaac3
 - Parent:
 - 11:cf2ba52e8b7e
 - Child:
 - 13:5c3dc6e827c2
 
File content as of revision 12:bfe3a3deaac3:
#include "mbed.h"
#include "N5110.h"
#include "Gamepad.h"
#include "models.h"
#include "main.h"
#include "game.h"
#include "stars.h"
//#include "planets.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)
Stars small_stars[MAX_SMALL_STARS];
#define MAX_MEDIUM_STARS (10)
Stars 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;
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 - enemy_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);
            } else {
                if (enemies[i].dead_counter > 0) {
                    enemies[i].dead_counter--;
                    lcd.drawSprite(enemies[i].x, enemies[i].y, 7, 11, (int*)enemyExploded);
                } else {
                    enemies[i].active = false;
                }
            }
            if (enemies[i].x < -5){
                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;
                }
            }
        }
    }
}
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();
    
    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;
}
void Game::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)){ y_ship_pos = 47 - spaceship1_height;}     //Limits for y direction border IMPROVE IF POSSIBLE.
    else if (y_ship_pos < 0){ y_ship_pos = 0;}
       
}
void Game::newSmallStarFlies() {
    // Search the array of stars if inactive we can use it. - the same as with blasts
    int found_inactive_small_star = -1;
    for (int i = 0; i < MAX_SMALL_STARS; ++i) {
        if (!small_stars[i].isSmallStarActive()) {
            found_inactive_small_star = i;
            break;
        }
    }
    
    if (found_inactive_small_star != -1) {
        small_stars[found_inactive_small_star].smallStarActivate(screen_width, rand() % screen_height);
    }
}
void Game::updateAndDrawSmallStars(){
    for (int i = 0; i < MAX_SMALL_STARS; ++i) {
        if (small_stars[i].isSmallStarActive()) {
            small_stars[i].updateAndDrawSmallStar();
        }
    }
}
void Game::newMediumStarFlies() {
    // Search the array of stars if inactive we can use it. - the same as with blasts
    int found_inactive_medium_star = -1;
    for (int i = 0; i < MAX_MEDIUM_STARS; ++i) {
        if (!medium_stars[i].isMediumStarActive()) {
            found_inactive_medium_star = i;
            break;
        }
    }
    
    if (found_inactive_medium_star != -1) {
        medium_stars[found_inactive_medium_star].mediumStarActivate(screen_width, rand() % screen_height); /////////////////////////////////////////// CHANGE
    }
}
void Game::updateAndDrawMediumStars(){
    for (int i = 0; i < MAX_MEDIUM_STARS; ++i) {
        if (medium_stars[i].isMediumStarActive()) {
            medium_stars[i].updateAndDrawMediumStar();
        }
    }
}
            
    