Lab1

Dependencies:   mbed C12832

KF_20901830_space_invaders.cpp

Committer:
kwstasfane1
Date:
2020-11-23
Revision:
10:2fabc22afe95

File content as of revision 10:2fabc22afe95:

/*
* Konstantinos Fane 
* kf289@kent.ac.uk
* ID: 20901830
*/

#include "mbed.h"
#include "C12832.h" // LCD display
#include "graphics.h"

int numsprite;
int setup_shooter();
int draw_shooter(int, int); //Display the shooter at some point shx
int getnew_shooter(int); // get the new shooter position (X axis)
void draw_sprite(struct sprite *);
void endgame(char);
Bitmap bm ; //Create a bitmap structure

//custom implemented functions and variables
void move_sprite();
void draw_moving_bullet(int, int);
void kill_sprite(struct sprite *);
int bullet_x_pos;
int killed_sprites = 0;
Timer m_t; //to be used for the interrupts that trigger the downward movement


int main()
{

    m_t.start(); //initialise the "move_down" timer 
    
    int nsxp; // new shooter x position
    int osxp; // old shooter x position

    //Set up the bitmap parameters for the display objects
    bm.xSize = 16; // 16 pixels wide
    bm.ySize = 8; // 8 pixels high
    bm.Byte_in_Line = 2; //i.e. 16bits
    
    //Initialise the PWM period for the multi colour LED control
    r.period(0.001);
    //And turn the 2 active (R and G) colours off
    r = 1.0; g = 1.0;

    // Draw the shooter image in its initial position
    // i.e x = 1 and y = 24 the base line
    osxp = setup_shooter();
    
    move_sprite();

    while(1)
    {        
        // Get the new shooter position
        nsxp = getnew_shooter(osxp);
        
        //And draw it
        osxp = draw_shooter(nsxp,osxp);
        wait(0.02);
        
        if(m_t.read() > 2) //wait for 2 teconds to create interrupt
        {
            move_sprite();
            m_t.reset();
        }
        
        //doesnt matter which spritetab entry is cheched, as even if its killed, 
        //its position will still be incremented
        if(spritetab[0].ypos >= 18)
        {
            endgame(LOSE);
            break; //while is terminated here
        }
        
        //checks whether all sprites have been killed
        if(killed_sprites == 8)
        {
            endgame(WIN);
            break;
        }
        
        if(joyC)
        {
            //Assign the position of the bullet shooting point to be the same as the tip of the shooter
            bullet_x_pos = nsxp + 5;
            draw_moving_bullet(bullet_x_pos, BASE);
            
            //destroys the allien sprint
            if(bullet_x_pos >=1 && bullet_x_pos <=10)
            {
                //checks if the sprint has been destroyed already
                if(spritetab[0].active == 1)
                {
                    spritetab[0].active = 0;
                    kill_sprite(&spritetab[0]);
                    killed_sprites++; //counter to keep track of how many sprites are killed, to determine whether the game has been won
                }
            }
            
            if(bullet_x_pos >=16 && bullet_x_pos <=26)
            {
                if(spritetab[1].active == 1)
                {
                    spritetab[1].active = 0;
                    kill_sprite(&spritetab[1]);
                    killed_sprites++;
                }
            }
            
            if(bullet_x_pos >=32 && bullet_x_pos <=42) {
                if(spritetab[2].active == 1)
                {
                    spritetab[2].active = 0;
                    kill_sprite(&spritetab[2]);
                    killed_sprites++;
                }
            }
            
            if(bullet_x_pos >=48 && bullet_x_pos <=58) {
                if(spritetab[3].active == 1)
                {
                    spritetab[3].active = 0;
                    kill_sprite(&spritetab[3]);
                    killed_sprites++;
                }
            }
            
            if(bullet_x_pos >=64 && bullet_x_pos <=74) {
                if(spritetab[4].active == 1)
                {
                    spritetab[4].active = 0;
                    kill_sprite(&spritetab[4]);
                    killed_sprites++;
                }
            }

            if(bullet_x_pos >=80 && bullet_x_pos <=90) {
                if(spritetab[5].active == 1)
                {
                    spritetab[5].active = 0;
                    kill_sprite(&spritetab[5]);
                    killed_sprites++;
                }
            }
            
            if(bullet_x_pos >=96 && bullet_x_pos <=106) {
                if(spritetab[6].active == 1)
                {
                    spritetab[6].active = 0;
                    kill_sprite(&spritetab[6]);
                    killed_sprites++;
                }
            }
            
            if(bullet_x_pos >=112 && bullet_x_pos <=123) {
                if(spritetab[7].active == 1)
                {
                    spritetab[7].active = 0;
                    kill_sprite(&spritetab[7]);
                    killed_sprites++;
                }
            }
        }
            
    }

    return 0;
 }
 
 //function to print th travelling bullet
void draw_moving_bullet(int bxpos, int bypos)
{
    lcd.setmode(XOR);                  //similar to how draw_sprite works
    for( int j=bypos; j>=0; j--) {
        lcd.pixel(bxpos, j, 1);
        lcd.pixel(bxpos, j-1, 1);
        lcd.pixel(bxpos, j-2, 1);
        lcd.pixel(bxpos, j-3, 1);
        wait(0.02);                 //wait is introduced so that the bullet is visible in the screen
        lcd.copy_to_lcd();          //only one is used, because if a second was used it would delete the bullet drawn already due to the XOR
        lcd.pixel(bxpos, j, 1);
        lcd.pixel(bxpos, j-1, 1);
        lcd.pixel(bxpos, j-2, 1);
        lcd.pixel(bxpos, j-3, 1);
    }
}

//implementation of sprite kill, is parsed the value of the spritetab[i]
void kill_sprite(struct sprite *ps)
{
    //a second print of the same object at the same position deletes the 
    //object @ spritetab[i]
    bm.data = ps->type;                    //assigning the type of the spritetab[i] to the bitmap variable
    lcd.print_bm(bm, ps->xpos, ps->ypos);  //prints the created bitmap at the corresponding x,y positions copies the printed data to lcd
}

 
void move_sprite()
{
    for (numsprite = 0; numsprite <= 7; numsprite++) {
        
        spritetab[numsprite].oldy = spritetab[numsprite].ypos;
        spritetab[numsprite].ypos++;
 
        //in here it checks to see whether the sprite is active or not, 
        //if yes it prints it, if not it doesnt print it
        if(spritetab[numsprite].active != 0) 
        {
            draw_sprite(&spritetab[numsprite]);
        }
    }
}
 
// setup the shooter image at location 1
int setup_shooter()
{
    lcd.cls(); //Clear the screen
    return (draw_shooter(1,0));
}
 
 
// Display the shooter at location shx the Y location (BASE) is always 24
int draw_shooter(int shx, int oldx)//shx = new position , oldx = current (old) position
{
    bm.data = shooter; // use the shooter image
    lcd.setmode(XOR); // XOR mode a second write in the same place erases the image

    if (oldx != 0) {
        //first time round
        lcd.print_bm(bm, oldx, BASE); // so this erases current shooter
        lcd.copy_to_lcd();
    }

    lcd.print_bm(bm, shx, BASE); // and this draws the new shooter at location shx
    lcd.copy_to_lcd(); // update lcd
    return shx; // 'current' position returned to become 'old' position

}

/* Get the new shooter X position in response to left or right
joystick movements stops at limits x = 1 and x = 112 */
int getnew_shooter(int oldx)
{
    int tmpx = oldx;
    if (joyL) tmpx--;
    if (tmpx <= 1) tmpx = 1;
    if (joyR) tmpx++;
    if (tmpx >= 112) tmpx = 112;
    return tmpx;
}

 // Determine sprite 1 or 2 and display
 void draw_sprite(struct sprite *ps)
 {

     bm.data = ps->type; // use sprite image as defined by type
     lcd.setmode(XOR); // XOR mode a second write in the same place erases the image
     
    if (ps->oldy != 0){ // first time round
         lcd.print_bm(bm, ps->xpos, ps->oldy); // so this erases current sprite
         lcd.copy_to_lcd();
     }
     
     lcd.print_bm(bm, ps->xpos, ps->ypos); // and this draws the new sprite at location
     lcd.copy_to_lcd(); // update lcd
 }

void endgame( char result) // LED == GREEN for WIN
{
    if(result == WIN)
    {
        lcd.cls();
        lcd.locate(20,12);
        lcd.printf("*** YOU WON ***");

        r = 1.0;
        g = 0.0;
    }
    else
    {
        lcd.cls();
        lcd.locate(17,12);
        lcd.printf("*** GAME OVER ***");

        r = 0.0;
        g = 1.0;
    }
    
    wait(2);
    lcd.cls();
    lcd.locate(13,1);
    lcd.printf("This game was made by");
    lcd.locate(24,11);
    lcd.printf("Konstantinos Fane");
    lcd.locate(25,21);
    lcd.printf("kf289@kent.ac.uk");
}