Asteroids for MBED game with Bluetooth LE UART Friend Controller, uLCD, speaker, and uSD.

Dependencies:   4DGL-uLCD-SE mbed-rtos mbed

Asteroids for MBED game with Bluetooth LE UART Friend Controller

main.cpp

Committer:
agamemaker
Date:
2016-03-12
Revision:
6:7d1d8945b2f7
Parent:
5:f41d3bfc6701
Child:
7:ff87ab834590

File content as of revision 6:7d1d8945b2f7:

#include "mbed.h"
#include "rtos.h"
#include "uLCD_4DGL.h"
#include <math.h>
#include <list>
using namespace std;

//constants
#define ACCEL .5
#define ROTTA .2
#define MAXSP 10

//devices
//DigitalOut myled(LED1);
uLCD_4DGL ulcd(p28,p27,p29);
BusOut myled(LED1,LED2,LED3,LED4);
Serial blue(p13,p14);

//Globals
int game_speed = 25;
bool up = 0;
bool left = 0;
bool right = 0;
bool stop = 0;
bool four = 0;


class Movement
{
public:
    double x_pos;   // x position of object
    double y_pos;   //
    double x_vel;   // x velocity of object
    double y_vel;   //
    double angle;   // angle of object
    int hit_rad;     // hit box radius of object
    bool wrap;
    Movement(double xp,double yp,double xv,double yv,double a,double r,double w);
    void assign(double xp,double yp,double xv,double yv,double a,double r,double w);
    //void move();
    void accelerate();
    void turn_left();
    void turn_right();

};

Movement::Movement(double xp,double yp,double xv,double yv,double a,double r,double w)
{
    x_pos = xp;
    y_pos = yp;
    x_vel = xv;
    y_vel = yv;
    angle = a;
    hit_rad = r;
    wrap = w;
}

void Movement::assign(double xp,double yp,double xv,double yv,double a,double r,double w)
{
    x_pos = xp;
    y_pos = yp;
    x_vel = xv;
    y_vel = yv;
    angle = a;
    hit_rad = r;
    wrap = w;
}

/*void Movement::move()
{
    x_pos += x_vel;
    y_pos += y_vel;
    if(x_pos < 0 || x_pos > 144 || y_pos < 0 || y_pos > 144) {
        if(wrap) {
            x_pos += 144*(1 - ceil(x_pos/144));
            y_pos += 144*(1 - ceil(y_pos/144));
        } else {
        }
    }
}*/

void Movement::accelerate()
{
    x_vel += ACCEL * cos(angle);
    y_vel += ACCEL * sin(angle);
    if(sqrt(pow(x_vel,2) + pow(y_vel,2)) > MAXSP) {
        x_vel = x_vel * MAXSP / sqrt(pow(x_vel,2) + pow(y_vel,2));
        y_vel = y_vel * MAXSP / sqrt(pow(x_vel,2) + pow(y_vel,2));
    }
}

void Movement::turn_left()
{
    angle -= ROTTA;
}

void Movement::turn_right()
{
    angle += ROTTA;
}

//Threads
//Controls
int read_getc(Serial &blue)
{
    while(!blue.readable()) {
        Thread::yield();
    }
    return blue.getc();
}

void controls(void const *args)
{
    char bnum=0;
    char bhit=0;
    while(1) {
        //Thread::wait(100);
        if (read_getc(blue)=='!') {
            if (read_getc(blue)=='B') { //button data packet
                bnum = read_getc(blue); //button number
                bhit = read_getc(blue); //1=hit, 0=release
                if (read_getc(blue)==char(~('!' + 'B' + bnum + bhit))) { //checksum OK?
                    myled = bnum - '0'; //current button number will appear on LEDs
                    switch (bnum) {
                        case '1': //number button 1
                            if (bhit=='1') {
                                game_speed = 25;
                            } else {
                                //add release code here
                            }
                            break;
                        case '2': //number button 2
                            if (bhit=='1') {
                                game_speed = 100;
                            } else {
                                //add release code here
                            }
                            break;
                        case '3': //number button 3
                            if (bhit=='1') {
                                //add hit code here
                            } else {
                                //add release code here
                            }
                            break;
                        case '4': //number button 4
                            if (bhit=='1') {
                                four = 1;
                            } else {
                                four = 0;
                            }
                            break;
                        case '5': //button 5 up arrow
                            if (bhit=='1') {
                                up = 1;
                            } else {
                                up = 0;
                            }
                            break;
                        case '6': //button 6 down arrow
                            if (bhit=='1') {
                                stop = 1;
                            } else {
                                stop = 0;
                            }
                            break;
                        case '7': //button 7 left arrow
                            if (bhit=='1') {
                                left = 1;
                            } else {
                                left = 0;
                            }
                                   break;
                        case '8': //button 8 right arrow
                            if (bhit=='1') {
                                right = 1;
                            } else {
                                right = 0;
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
        }
    }
}

void move(Movement &p)
{
    p.x_pos += p.x_vel;
    p.y_pos += p.y_vel;
    if(p.x_pos < 0 || p.x_pos > 144 || p.y_pos < 0 || p.y_pos > 144) {
        if(p.wrap) {
            p.x_pos += 144*(1 - ceil(p.x_pos/144));
            p.y_pos += 144*(1 - ceil(p.y_pos/144));
        } else {
        }
    }
}

//move
void move_all(Movement &player, list<Movement> &asteroids, list<Movement> &bullets)
{
    move(player);
    list<Movement>::iterator iterator;
    for (iterator = asteroids.begin(); iterator != asteroids.end(); ++iterator) {
        move(*iterator);
    }
}

//collisions
bool collision(Movement p1, Movement p2)
{
    int rad = p1.hit_rad + p2.hit_rad;
    double dist = sqrt(pow((p1.x_pos - p2.x_pos),2) + pow((p1.y_pos - p2.y_pos),2));
    return dist < rad;
}

void calc_collisions(Movement &player, list<Movement> &asteroids, list<Movement> &bullets)
{
    list<Movement>::iterator iterator;
    for (iterator = asteroids.begin(); iterator != asteroids.end(); ++iterator) {
        if(collision(player,*iterator)){
            ulcd.printf("crash");
        }
    }
}

//drawing
void draw_triangle(Movement p)
{
    int x1 = p.x_pos + p.hit_rad * cos(p.angle);
    int y1 = p.y_pos + p.hit_rad * sin(p.angle);
    int x2 = p.x_pos + p.hit_rad * cos(p.angle + 2.5);
    int y2 = p.y_pos + p.hit_rad * sin(p.angle + 2.5);
    int x3 = p.x_pos + p.hit_rad * cos(p.angle - 2.5);
    int y3 = p.y_pos + p.hit_rad * sin(p.angle - 2.5);
    ulcd.triangle(x1,y1,x2,y2,x3,y3,BLUE);
}

void draw_objs(Movement player, list<Movement> asteroids, list<Movement> bullets)
{
    ulcd.cls();
    draw_triangle(player);
    ulcd.circle(player.x_pos,player.y_pos,player.hit_rad,BLUE);
    list<Movement>::const_iterator iterator;
    for (iterator = asteroids.begin(); iterator != asteroids.end(); ++iterator) {
        ulcd.circle(iterator->x_pos,iterator->y_pos,iterator->hit_rad,RED);
    }
}

int main()
{
    Thread buttons(controls);
    Movement temp(100, 0, 0, 5, 0, 10, 1);
    Movement player(50, 100, 0, -5, 0, 10, 1);
    list<Movement> asteroids;
    list<Movement> bullets;
    asteroids.push_back(temp);
    temp.assign(20, 0, 0, 5, 0, 10, 1);
    asteroids.push_back(temp);
    while(1) {
        //controls
        if(up) {
            player.accelerate();
        }
        if(left) {
            player.turn_left();
        }
        if(right) {
            player.turn_right();
        }
        if(stop) {
            player.x_vel = 0;
            player.y_vel = 0;
        }
                       //move
                       //player.move();
                       
        move_all(player, asteroids, bullets);
        calc_collisions(player, asteroids, bullets);
        draw_objs(player, asteroids, bullets);
        Thread::wait(game_speed);
    }
}