A simplified version of Galaga that can be run on an mbed

Dependencies:   4DGL-uLCD-SE DebounceIn mbed

Fork of AsteroidDefender by Ryan Quinn

main.cpp

Committer:
ndaniel7
Date:
2015-10-28
Revision:
4:6fc77e25bbcf
Parent:
3:0b2c776da95d

File content as of revision 4:6fc77e25bbcf:

#include "mbed.h"
#include "game.h"
#include "uLCD_4DGL.h"
#include <list>
#include <stdlib.h>

uLCD_4DGL lcd(p28,p27,p29);

DigitalOut myled(LED1);
AnalogIn sliderv(p17);
AnalogIn sliderh(p19);
PwmOut red(p24);
PwmOut green(p25);
DigitalIn pb1(p21);
//if the pushbutton is down
bool down = false;
//lives remaining
int lives = 3;


std::list<Enemy> enemies;
std::list<Bullet> bullets;
Ship ship;

//If the enemies have moved, cover their old spot with a black rectangle and redraw them
void render_enemies() {
    for(std::list<Enemy>::iterator j = enemies.begin(); j != enemies.end(); j++){
        if(j->moved) {
            lcd.filled_rectangle(j->old_coord.x-3, j->old_coord.y-3, j->old_coord.x + j->size.x+3, j->old_coord.y + j->size.y+3, 0x000000);
        }
        lcd.filled_rectangle(j->coord.x, j->coord.y, j->coord.x + j->size.x, j->coord.y + j->size.y, 0x00FFFF);
        if (!j->moved) {
            j->move();
        }
    }
}
//Set the led color
void loseLife(){
    lives--;
    if (lives==2){
        red=.5;
        green=.25;
    }
    else if (lives==1){
        red=.5;
        green=0;
    }
    else{
        red=0;
    }
}

//If the ship has moved, cover their old spot with a black rectangle and redraw them
void render_ship() {
    if(ship.moved) {
        lcd.filled_rectangle(ship.old_coord.x-5, ship.old_coord.y-5, ship.old_coord.x + ship.size.x + 5, ship.old_coord.y + ship.size.y + 5, 0x000000);
        ship.moved = false;
    }
    lcd.filled_rectangle(ship.coord.x, ship.coord.y, ship.coord.x + ship.size.x, ship.coord.y + ship.size.y, 0x00FF00);
}

//If the bullets have moved, cover their old spot with a black rectangle and redraw them
void render_bullets() {
    for(std::list<Bullet>::iterator j = bullets.begin(); j != bullets.end(); j++){
        if(j->moved) {
            lcd.filled_rectangle(j->old_coord.x, j->old_coord.y, j->old_coord.x + j->size.x, j->old_coord.y + j->size.y, 0x000000);
        }
        lcd.filled_rectangle(j->coord.x, j->coord.y, j->coord.x + j->size.x, j->coord.y + j->size.y, 0xFFFF00);
        if(j->coord.y < -4) {
            j = bullets.erase(j);
        }
        else {
            j->move();
        }
    }
}

//Collision checking based on coordinates
void check_collisions() {
    for(std::list<Enemy>::iterator k = enemies.begin(); k != enemies.end(); k++){
        for(std::list<Bullet>::iterator j = bullets.begin(); j != bullets.end(); j++){
            if((j->old_coord.x >= k->old_coord.x && j->old_coord.x <= (k->old_coord.x + k->size.x))||((j->coord.x + j->size.x) >= k->old_coord.x && (j->old_coord.x + j->size.x) <= (k->old_coord.x + k->size.x))){
                
                if( (j->old_coord.y >= k->old_coord.y && j->old_coord.y <= (k->old_coord.y + k->size.y))||((j->old_coord.y + j->size.y) >= k->old_coord.y && (j->old_coord.y + j->size.y) <= (k->old_coord.y + k->size.y)) ){
                
                    lcd.filled_rectangle(j->coord.x-4, j->coord.y-4, j->coord.x + j->size.x+4, j->coord.y + j->size.y+6, 0x000000);
                    lcd.filled_rectangle(k->coord.x-3, k->coord.y-3, k->coord.x + k->size.x+3, k->coord.y + k->size.y+3, 0x000000);
                    k = enemies.erase(k);
                    j = bullets.erase(j);
                }
            }
        }
        //if an enemy collides with the ship, it blows up and takes away a life
            if((ship.coord.x >= k->coord.x && ship.coord.x <= (k->coord.x + k->size.x))||((ship.coord.x + ship.size.x) >= k->coord.x && (ship.coord.x + ship.size.x) <= (k->coord.x + k->size.x))){
                
                if( (ship.coord.y >= k->coord.y && ship.coord.y <= (k->coord.y + k->size.y))||((ship.coord.y + ship.size.y) >= k->coord.y && (ship.coord.y + ship.size.y) <= (k->coord.y + k->size.y))){
                    lcd.filled_rectangle(k->coord.x, k->coord.y, k->coord.x + k->size.x, k->coord.y + k->size.y, 0x000000);
                    k = enemies.erase(k);
                    loseLife();
                }
            }
    }
}


//If button is pressed, shoot only once
void check_button() {
    if(pb1 == 0 && !down) {
        down = true;
        if(bullets.size() < 3) {
            Bullet bullet(ship.coord);
            bullets.push_back(bullet);   
        }
    }
    else if(pb1 == 1) {
        down = false;
    }
}

//Calls render methods for all different objects
void render() {
    render_enemies();
    render_ship();
    check_button();
    render_bullets();
    check_collisions(); 
}

//Analog movement for the ship based on the joystick
void ship_move() {
    if(sliderh < 0.1) {
        ship.old_coord.x = ship.coord.x;
        ship.coord.x += 5;
        ship.moved = true;
    }
    else if (sliderh < .2){
        ship.old_coord.x = ship.coord.x;
        ship.coord.x += 4;
        ship.moved = true;
    }
    else if (sliderh < .3){
        ship.old_coord.x = ship.coord.x;
        ship.coord.x += 3;
        ship.moved = true;
    }
    else if (sliderh < .4){
        ship.old_coord.x = ship.coord.x;
        ship.coord.x += 2;
        ship.moved = true;
    }
    if(sliderh > 0.9) {
        ship.old_coord.x = ship.coord.x; 
        ship.coord.x -= 5;
        ship.moved = true;
    }
    else if(sliderh > 0.8) {
        ship.old_coord.x = ship.coord.x;
        ship.coord.x -= 4;
        ship.moved = true;
    }
    else if(sliderh > 0.7) {
        ship.old_coord.x = ship.coord.x;
        ship.coord.x -= 3;
        ship.moved = true;
    }
    else if(sliderh > 0.6) {
        ship.old_coord.x = ship.coord.x;
        ship.coord.x -= 2;
        ship.moved = true;
    }
    if (ship.coord.x < 0){
        ship.coord.x = 0;
    }
    else if (ship.coord.x > 128-ship.size.x){
        ship.coord.x = 128-ship.size.x;
    }        
    if(sliderv < 0.1) {
        ship.old_coord.y = ship.coord.y;
        ship.coord.y += 5;
        ship.moved = true;
    }
    else if (sliderv < .2){
        ship.old_coord.y = ship.coord.y;
        ship.coord.y += 4;
        ship.moved = true;
    }
    else if (sliderv < .3){
        ship.old_coord.y = ship.coord.y;
        ship.coord.y += 3;
        ship.moved = true;
    }
    else if (sliderv < .4){
        ship.old_coord.y = ship.coord.y;
        ship.coord.y += 2;
        ship.moved = true;
    }
    else if(sliderv> 0.9) {
        ship.old_coord.y = ship.coord.y; 
        ship.coord.y -= 5;
        ship.moved = true;
    }
    else if(sliderv> 0.8) {
        ship.old_coord.y = ship.coord.y;
        ship.coord.y-= 4;
        ship.moved = true;
    }
    else if(sliderv> 0.7) {
        ship.old_coord.y = ship.coord.y;
        ship.coord.y-= 3;
        ship.moved = true;
    }
    else if(sliderv> 0.6) {
        ship.old_coord.y = ship.coord.y;
        ship.coord.y-= 2;
        ship.moved = true;
    }
    if (ship.coord.y  < 0){
        ship.coord.y = 0;
    }
    else if (ship.coord.y > 128-ship.size.y){
        ship.coord.y= 128-ship.size.y;
    }
}

void create_enemies(int number) {
    for(int i = 0; i<number; i++) {
        Pair spawn,speed;
        srand(1*i);
        spawn.x = rand() % 124 + 0;
        spawn.y = 0;
        srand(2*i);
        speed.x = rand() % (number) + 1;
        srand(3*i);
        if (rand()%3==0){
            speed.x=-speed.x;
        }
        srand(4*i);
        speed.y = rand() % (number) + 1;
        Enemy enemy(spawn, speed);
        enemies.push_back(enemy);
    }
}

int main() {
    pb1.mode(PullUp);
    pc.baud(9600);
    lcd.baudrate(3000000);
    lcd.cls();
    int numEnemies = 1;
    lcd.set_font_size(5,5);
    lcd.locate(5,4);
    lcd.printf("Welcome");
    lcd.locate(5,6);
    lcd.printf("   to");
    lcd.locate(5,8);
    lcd.printf("Galager");
    red=0;
    green=.5;
    wait(3);
    lcd.cls();
    while(1) {  
        //Game over
        if(lives==0) {
            break;
        }
        Create enemies based on round number
        create_enemies(numEnemies);
        pc.printf("%d",enemies.size());
        for (int x = 0; x<100000000; x++) {           
            ship_move();
            for(std::list<Enemy>::iterator j = enemies.begin(); j != enemies.end(); j++){
                j->move();
                //If enemies get passed the bottom, delete them
                if (j->coord.y>140){
                    j = enemies.erase(j);
                }
            }
            
            render();
            //If no enemies, round is over
            if(enemies.size() == 0) {
                numEnemies+=1;
                break;
            }
            //If lose all lives, game over
            if(lives==0) {
                break;
            }
            wait(.05);
            
        }
        //Delete all the stray bullets after a round
        for(std::list<Bullet>::iterator j = bullets.begin(); j != bullets.end(); j++){
             lcd.filled_rectangle(j->coord.x-4, j->coord.y-4, j->coord.x + j->size.x+4, j->coord.y + j->size.y+4, 0x000000);
             j = bullets.erase(j);
        }
        lcd.cls();
        //Time inbetween rounds
        if (lives>0){
            for (int i=0;i<(1.5/.05);i++){
              ship_move();
              render_ship();
              wait(.05);
            }
        }
    }
    //Game is over
    lcd.cls();
    lcd.color(0xFF0000);
    lcd.set_font_size(5,5);
    lcd.locate(5,4);
    lcd.printf("Game Over");
    lcd.locate(2,7);
    lcd.printf("You made it to");
    lcd.locate(5,9);
    lcd.printf(" Round %d!",numEnemies-1);
}