![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
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:
- 11:d707cebe6eff
- Parent:
- 10:6bb7504e0f5a
File content as of revision 11:d707cebe6eff:
#include "mbed.h" #include "rtos.h" #include "uLCD_4DGL.h" #include <math.h> #include <list> #include <time.h> #include "SongPlayer.h" using namespace std; //constants #define GAMES 144 #define ACCEL .5 #define ROTTA .3 #define MAXSP 7 #define BULSP 10 #define ASTSP 3 #define PI 3.14159265359 //devices //DigitalOut myled(LED1); uLCD_4DGL ulcd(p28,p27,p29); BusOut myled(LED1,LED2,LED3,LED4); Serial blue(p13,p14); SongPlayer myspkr(p26); Mutex stdio_mutex; //Globals int game_speed = 25; bool up = 0; bool left = 0; bool right = 0; bool stop = 0; bool four = 0; bool colsound = 0; int lives = 3; int round = 0; class Movement { public: double x_pos; // x position of object double y_pos; // y position of object double x_vel; // x velocity of object double y_vel; // y velocity of object double angle; // angle of object int hit_rad; // hit box radius of object bool wrap; // does the object 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::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 //Speaker void crash(void const *args) { while(1) { if(colsound) { float note = 1568.0; float durration = .5; myspkr.PlaySong(¬e, &durration); colsound = 0; } } } //Controls int read_getc(Serial &blue) { while(!blue.readable()) { Thread::yield(); } stdio_mutex.lock(); int temp = blue.getc(); stdio_mutex.unlock(); return temp; } 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; } } } } } } //game_over void game_over(list<Movement> &asteroids, list<Movement> &bullets) { stdio_mutex.lock(); ulcd.cls(); asteroids.clear(); bullets.clear(); round = 0; //ulcd.printf("GAME OVER"); ulcd.media_init(); ulcd.set_sector_address(0x001D, 0x4C01); ulcd.display_image(0,0); wait(3); ulcd.cls(); lives = 3; ulcd.printf("%d",lives); stdio_mutex.unlock(); } //move void move(Movement &p) { p.x_pos += p.x_vel; p.y_pos += p.y_vel; if(p.x_pos < 0 || p.x_pos > GAMES || p.y_pos < 0 || p.y_pos > GAMES) { if(p.wrap) { p.x_pos += GAMES*(1 - ceil(p.x_pos/GAMES)); p.y_pos += GAMES*(1 - ceil(p.y_pos/GAMES)); } else { } } } 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); } for (iterator = bullets.begin(); iterator != bullets.end(); ++iterator) { move(*iterator); } } //garbage void garbage(list<Movement> &bullets) { bool del = 0; list<Movement>::iterator iterator; list<Movement>::iterator itcpy; for (iterator = bullets.begin(); iterator != bullets.end(); ++iterator) { if(iterator->x_pos < 0 || iterator->x_pos > GAMES || iterator->y_pos < 0 || iterator->y_pos > GAMES) { //bullets.erase(iterator); del = 1; itcpy = iterator; } } if(del) { bullets.erase(itcpy); } } //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 new_asteroid(list<Movement> &asteroids, int x, int y, int size) { double ast_ang = rand()%1000 * 2*PI/1000; double a_x_vel = ASTSP * cos(ast_ang); double a_y_vel = ASTSP * sin(ast_ang); Movement temp(x, y, a_x_vel, a_y_vel, 0, size, 1); asteroids.push_back(temp); } void calc_collisions(Movement &player, list<Movement> &asteroids, list<Movement> &bullets) { bool crash = 0, hit = 0; list<Movement>::iterator it; list<Movement>::iterator it2; list<Movement>::iterator itacpy; list<Movement>::iterator itbcpy; for (it = asteroids.begin(); it != asteroids.end(); ++it) { if(collision(player,*it)) { //ulcd.printf("crash"); colsound = 1; crash = 1; } } for (it = asteroids.begin(); it != asteroids.end(); ++it) { for (it2 = bullets.begin(); it2 != bullets.end(); ++it2) { if(collision(*it,*it2)) { //ulcd.printf("hit"); hit = 1; itacpy = it; itbcpy = it2; } } } if(crash) { player.assign(70,70,0,0,0,10,1); lives--; if(!lives) { game_over(asteroids,bullets); } stdio_mutex.lock(); ulcd.cls(); ulcd.printf("%d",lives); stdio_mutex.unlock(); } if(hit) { if(itacpy->hit_rad == 10) { new_asteroid(asteroids, itacpy->x_pos, itacpy->y_pos, 7); new_asteroid(asteroids, itacpy->x_pos, itacpy->y_pos, 7); } if(itacpy->hit_rad == 7) { new_asteroid(asteroids, itacpy->x_pos, itacpy->y_pos, 5); new_asteroid(asteroids, itacpy->x_pos, itacpy->y_pos, 5); } asteroids.erase(itacpy); bullets.erase(itbcpy); } } //drawing void draw_triangle(Movement p, int color) { 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,color); } void draw_objs(Movement player, list<Movement> asteroids, list<Movement> bullets, int color) { //ulcd.cls(); draw_triangle(player,color); ulcd.circle(player.x_pos,player.y_pos,player.hit_rad,color); list<Movement>::const_iterator iterator; for (iterator = asteroids.begin(); iterator != asteroids.end(); ++iterator) { ulcd.circle(iterator->x_pos,iterator->y_pos,iterator->hit_rad,color); } for (iterator = bullets.begin(); iterator != bullets.end(); ++iterator) { ulcd.filled_circle(iterator->x_pos,iterator->y_pos,iterator->hit_rad,color); } } //round check void round_check(list<Movement> &asteroids) { if(asteroids.empty()) { round++; for(int i = 0; i < round && i < 4; i++) { new_asteroid(asteroids, 140*(i%2), 140*((i%2)+1),10); } } } int main() { Movement temp(0,0,0,0,0,0,0); srand(time(NULL)); lives = 3; ulcd.printf("%d",lives); ulcd.baudrate(BAUD_3000000); Thread sound(crash); Thread buttons(controls); Movement player(70,70,0,0,0,10,1); list<Movement> asteroids; list<Movement> bullets; Movement p_player(70,70,0,0,0,10,1); list<Movement> p_asteroids; list<Movement> p_bullets; 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; } if(four) { temp.x_pos = player.x_pos + player.hit_rad * cos(player.angle); temp.y_pos = player.y_pos + player.hit_rad * sin(player.angle); temp.x_vel = BULSP * cos(player.angle); temp.y_vel = BULSP * sin(player.angle); temp.angle = player.angle; temp.hit_rad = 1; temp.wrap = 0; bullets.push_back(temp); } //move round_check(asteroids); move_all(player, asteroids, bullets); garbage(bullets); calc_collisions(player, asteroids, bullets); draw_objs(p_player, p_asteroids, p_bullets,BLACK); draw_objs(player, asteroids, bullets,WHITE); p_player = player; p_asteroids = asteroids; p_bullets = bullets; Thread::wait(game_speed); } }