![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
Shell code for the Tanks game
Dependencies: 4DGL-uLCD-SE EthernetInterface Game_Synchronizer MMA8452 SDFileSystem mbed-rtos mbed wave_player
Diff: main.cpp
- Revision:
- 12:088a8203a9bb
- Parent:
- 11:f455e907baba
- Child:
- 14:36c306e26317
diff -r f455e907baba -r 088a8203a9bb main.cpp --- a/main.cpp Fri Oct 23 04:18:28 2015 +0000 +++ b/main.cpp Sun Oct 25 17:57:39 2015 +0000 @@ -2,7 +2,9 @@ #include "mbed.h" #include "game_synchronizer.h" +#include "MMA8452.h" // for accelerometer #include "math.h" +#include <vector> #define SKY_COLOR 0x7EC0EE #define GND_COLOR 0x66CD00 @@ -20,10 +22,12 @@ DigitalIn pb_u(p22); // up button DigitalIn pb_d(p23); // down button - +//MMA8452 acc(p28, p27, 100000); // Accelerometer uLCD_4DGL uLCD(p9,p10,p11); // LCD (serial tx, serial rx, reset pin;) Game_Synchronizer sync(PLAYER1); // (tx, rx, rst, player mode) +Timer frame_timer; + // For debug only. Don't use in production code. It will slow your game down a lot. Serial pc(USBTX, USBRX); @@ -69,6 +73,7 @@ int barrel_length; int wheel_rad; + Tank(int sx, int sy, int width, int height, int color) { x = sx; y = sy; w = width; h = height; @@ -78,15 +83,41 @@ wheel_rad = 2.0; draw(); } - int min_x(void) { return x; } + int min_x(void) { + int barrel_extent = (-barrel_length*cos(barrel_theta) > w/2.0) ? barrel_length*cos(barrel_theta) + w/2.0 : 0; + return x + barrel_extent; } int min_y(void) { return y; } - int max_x(void) { return x + w + ceil(barrel_length*cos(barrel_theta)); } - int max_y(void) { return y + h + wheel_rad + ceil(barrel_length*sin(barrel_theta)); } + int max_x(void) { + int barrel_extent = (barrel_length*cos(barrel_theta) > w/2.0) ? barrel_length*cos(barrel_theta) : w/2.0; + return x + w/2.0 + barrel_extent; } + int max_y(void) { + int barrel_extent = (sin(barrel_theta) > 0) ? barrel_length*sin(barrel_theta) : 0; + return y + h + wheel_rad + barrel_extent; } + + void barrel_end(int& bx, int& by) { + bx = x + w/2.0 + (barrel_length+1)*cos(barrel_theta); + by = y+h+wheel_rad + (barrel_length+1)*sin(barrel_theta); + } void reposition(int new_x, int new_y, float new_theta) { - sync.filled_rectangle(min_x(), min_y(), max_x(), max_y(), SKY_COLOR); - sync.line(x + w/2.0, y+h+wheel_rad, x + w/2.0 + 1 + barrel_length*cos(barrel_theta), y+h + barrel_length*sin(barrel_theta), SKY_COLOR); - x = new_x; y = new_y; barrel_theta = new_theta; + float old_theta = barrel_theta; + int old_x = x; + int old_y = y; + int minx = min_x(); + int miny = min_y(); + int maxx = max_x(); + int maxy = max_y(); + + x = new_x; y = new_y; barrel_theta = new_theta - (int)(new_theta/PI)*PI; + + if(min_x() < 0 || max_x() > 128) { + x = old_x; y = old_y; barrel_theta = old_theta; + draw(); + return; + } + + sync.filled_rectangle(minx, miny, maxx, maxy, SKY_COLOR); + sync.line(old_x + w/2.0, old_y+h+wheel_rad, old_x + w/2.0 + 1 + barrel_length*cos(old_theta), old_y+h + barrel_length*sin(old_theta), SKY_COLOR); draw(); } void draw() { @@ -94,9 +125,84 @@ sync.filled_rectangle(x, y+wheel_rad, x+w, y+h+wheel_rad, tank_color); sync.filled_circle(x+wheel_rad, y+wheel_rad, wheel_rad, BLACK); sync.filled_circle(x+w-wheel_rad, y+wheel_rad, wheel_rad, BLACK); + } +}; + +int convert24to16bpp(int col_24) { + int b = col_24 & 0xFF; + int g = (col_24 >> 8) & 0xFF; + int r = (col_24 >> 16)& 0xFF; + + r >>= 3; + g >>= 2; + b >>= 3; + + return r<<11 | g<<5 | b; +} + +class Bullet{ + public: + int x0; + int y0; + float vx0; + float vy0; + int x; + int y; + int speed; + float time; + bool in_flight; + + Tank* tank; + + Bullet(Tank* t) { + tank = t; + speed = 30; + in_flight = false; } + void shoot(void) { + if(in_flight) {return;} + time = 0; + tank->barrel_end(x0, y0); + x = x0; y = y0; + vx0 = speed*cos(tank->barrel_theta); + vy0 = speed*sin(tank->barrel_theta); + in_flight = true; + } + + void time_step(float dt) { + if(!in_flight) {return;} + time += dt; + int new_x = x0 + vx0*time; + int new_y = y0 + vy0*time + 0.5*(-9.81)*time*time; + + if(new_x == x && new_y == y) { + return; + } + + if(new_x < 0 || new_x > 128 || new_y < 0 || new_y > 128) { + in_flight = false; + return; + } + + int col = sync.read_pixel(new_x, new_y); + if(col != convert24to16bpp(SKY_COLOR)) { + if(col == convert24to16bpp(TANK_BLUE)) { + pc.printf("Player 1 wins!\n"); + } + sync.pixel(x, y, SKY_COLOR); + sync.filled_circle(new_x, new_y, 4, SKY_COLOR); + in_flight = false; + return; + } + sync.pixel(x, y, SKY_COLOR); + + x = new_x; + y = new_y; + sync.pixel(x, y, BLACK); + } }; + void game_init(void) { led1 = 0; led2 = 0; led3 = 0; led4 = 0; @@ -119,15 +225,20 @@ game_init(); - Tank t1(4, 20, 12, 8, TANK_RED); - Tank t2(111, 20, 12, 8, TANK_BLUE); + Tank t1(4, 21, 12, 8, TANK_RED); + Tank t2(111, 21, 12, 8, TANK_BLUE); + Bullet b1(&t1); + Bullet b2(&t2); + + frame_timer.start(); while(1) { - sync.line(0,0, 5,5, BLACK); // Update pukes if you try to send nothing :P - sync.update(); + + //double acc_x, acc_y, acc_z; + //acc.readXYZGravity(&acc_x,&acc_y,&acc_z); //read accelerometer + //pc.printf("ACCELERATION X:%f Y:%f Z:%f\n", acc_x, acc_y, acc_z); p2_buttons = sync.get_button_state(); - led1 = p2_buttons[0] ^ !pb_u; led2 = p2_buttons[1] ^ !pb_r; led3 = p2_buttons[2] ^ !pb_d; @@ -138,11 +249,17 @@ if(p2_buttons[3]) t2.reposition(t2.x-1, t2.y, t2.barrel_theta); if(p2_buttons[1]) t2.reposition(t2.x+1, t2.y, t2.barrel_theta); - if(!pb_d) t1.reposition(t1.x, t1.y, t1.barrel_theta+PI/30.0); - if(!pb_u) t1.reposition(t1.x, t1.y, t1.barrel_theta-PI/30.0); + //if(!pb_d) t1.reposition(t1.x, t1.y, t1.barrel_theta-PI/30.0); + if(!pb_u) t1.reposition(t1.x, t1.y, t1.barrel_theta+PI/30.0); if(p2_buttons[0]) t2.reposition(t2.x, t2.y, t2.barrel_theta+PI/30.0); if(p2_buttons[2]) t2.reposition(t2.x, t2.y, t2.barrel_theta-PI/30.0); + if(!pb_d) { b1.shoot(); } + + b1.time_step(0.01); + //b2.time_step(1); + frame_timer.reset(); + sync.update(); } } \ No newline at end of file