Revenge of the Mouse

Dependencies:   4DGL-uLCD-SE EthernetInterface Game_Synchronizer LCD_fonts MMA8452 SDFileSystem mbed-rtos mbed wave_player

Fork of 2035_Tanks_Shell by ECE2035 Spring 2015 TA

Committer:
jford38
Date:
Sun Oct 25 17:57:39 2015 +0000
Revision:
12:088a8203a9bb
Parent:
11:f455e907baba
Child:
14:36c306e26317
All kinds of stuff. Basically, things explode when you hit them now, and tanks can't drive through side of the screen.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jford38 6:3be57cf4bd33 1 // Student Side.
jford38 0:899c85cd266f 2
jford38 0:899c85cd266f 3 #include "mbed.h"
jford38 6:3be57cf4bd33 4 #include "game_synchronizer.h"
jford38 12:088a8203a9bb 5 #include "MMA8452.h" // for accelerometer
jford38 10:5da9b27e050e 6 #include "math.h"
jford38 12:088a8203a9bb 7 #include <vector>
jford38 10:5da9b27e050e 8
jford38 10:5da9b27e050e 9 #define SKY_COLOR 0x7EC0EE
jford38 10:5da9b27e050e 10 #define GND_COLOR 0x66CD00
jford38 10:5da9b27e050e 11 #define TANK_RED 0xCD0000
jford38 10:5da9b27e050e 12 #define TANK_BLUE 0x000080
jford38 10:5da9b27e050e 13 #define PI 3.1415926535797
jford38 6:3be57cf4bd33 14
jford38 6:3be57cf4bd33 15 DigitalOut led1(LED1);
jford38 6:3be57cf4bd33 16 DigitalOut led2(LED2);
jford38 6:3be57cf4bd33 17 DigitalOut led3(LED3);
jford38 6:3be57cf4bd33 18 DigitalOut led4(LED4);
jford38 0:899c85cd266f 19
jford38 6:3be57cf4bd33 20 DigitalIn pb_l(p24); // left button
jford38 6:3be57cf4bd33 21 DigitalIn pb_r(p21); // right button
jford38 6:3be57cf4bd33 22 DigitalIn pb_u(p22); // up button
jford38 6:3be57cf4bd33 23 DigitalIn pb_d(p23); // down button
jford38 6:3be57cf4bd33 24
jford38 12:088a8203a9bb 25 //MMA8452 acc(p28, p27, 100000); // Accelerometer
jford38 8:e6dd05393290 26 uLCD_4DGL uLCD(p9,p10,p11); // LCD (serial tx, serial rx, reset pin;)
jford38 8:e6dd05393290 27 Game_Synchronizer sync(PLAYER1); // (tx, rx, rst, player mode)
jford38 0:899c85cd266f 28
jford38 12:088a8203a9bb 29 Timer frame_timer;
jford38 12:088a8203a9bb 30
jford38 6:3be57cf4bd33 31 // For debug only. Don't use in production code. It will slow your game down a lot.
jford38 6:3be57cf4bd33 32 Serial pc(USBTX, USBRX);
jford38 0:899c85cd266f 33
jford38 7:9506f2d84162 34
jford38 7:9506f2d84162 35 int game_menu(void) {
jford38 7:9506f2d84162 36
jford38 7:9506f2d84162 37 // Figure out what mode the game will be run in.
jford38 9:ee330b1ba394 38
jford38 10:5da9b27e050e 39 uLCD.current_orientation = IS_LANDSCAPE;
jford38 9:ee330b1ba394 40 uLCD.locate(0,1);
jford38 9:ee330b1ba394 41 uLCD.puts("Select Mode:");
jford38 9:ee330b1ba394 42 uLCD.locate(0,3);
jford38 9:ee330b1ba394 43 uLCD.puts(" Single-Player:");
jford38 9:ee330b1ba394 44 uLCD.locate(0,4);
jford38 9:ee330b1ba394 45 uLCD.puts(" Left Button");
jford38 9:ee330b1ba394 46 uLCD.locate(0,6);
jford38 9:ee330b1ba394 47 uLCD.puts(" Multi-Player:");
jford38 9:ee330b1ba394 48 uLCD.locate(0,7);
jford38 9:ee330b1ba394 49 uLCD.puts(" Right Button");
jford38 7:9506f2d84162 50 // Right button -> Multiplayer
jford38 7:9506f2d84162 51 // Left button -> Single player
jford38 7:9506f2d84162 52 while(1) {
jford38 9:ee330b1ba394 53 if(!pb_r) { return MULTI_PLAYER; }
jford38 9:ee330b1ba394 54 if(!pb_l) { return SINGLE_PLAYER; }
jford38 7:9506f2d84162 55 }
jford38 7:9506f2d84162 56 }
jford38 7:9506f2d84162 57
jford38 10:5da9b27e050e 58 void map_init() {
jford38 10:5da9b27e050e 59 sync.background_color(SKY_COLOR);
jford38 10:5da9b27e050e 60 sync.cls();
jford38 10:5da9b27e050e 61 sync.filled_rectangle(0,0,128,20, GND_COLOR);
jford38 10:5da9b27e050e 62 sync.filled_rectangle(59, 20, 69, 60, BLACK);
jford38 10:5da9b27e050e 63 sync.update();
jford38 10:5da9b27e050e 64 }
jford38 10:5da9b27e050e 65
jford38 10:5da9b27e050e 66 class Tank {
jford38 10:5da9b27e050e 67 public:
jford38 10:5da9b27e050e 68 int x, y;
jford38 10:5da9b27e050e 69 int w;
jford38 10:5da9b27e050e 70 int h;
jford38 10:5da9b27e050e 71 int tank_color;
jford38 10:5da9b27e050e 72 float barrel_theta;
jford38 10:5da9b27e050e 73 int barrel_length;
jford38 10:5da9b27e050e 74 int wheel_rad;
jford38 10:5da9b27e050e 75
jford38 12:088a8203a9bb 76
jford38 10:5da9b27e050e 77 Tank(int sx, int sy, int width, int height, int color) {
jford38 10:5da9b27e050e 78 x = sx; y = sy;
jford38 10:5da9b27e050e 79 w = width; h = height;
jford38 10:5da9b27e050e 80 tank_color = color;
jford38 10:5da9b27e050e 81 barrel_theta = PI/4.0;
jford38 10:5da9b27e050e 82 barrel_length = w;
jford38 10:5da9b27e050e 83 wheel_rad = 2.0;
jford38 10:5da9b27e050e 84 draw();
jford38 10:5da9b27e050e 85 }
jford38 12:088a8203a9bb 86 int min_x(void) {
jford38 12:088a8203a9bb 87 int barrel_extent = (-barrel_length*cos(barrel_theta) > w/2.0) ? barrel_length*cos(barrel_theta) + w/2.0 : 0;
jford38 12:088a8203a9bb 88 return x + barrel_extent; }
jford38 10:5da9b27e050e 89 int min_y(void) { return y; }
jford38 12:088a8203a9bb 90 int max_x(void) {
jford38 12:088a8203a9bb 91 int barrel_extent = (barrel_length*cos(barrel_theta) > w/2.0) ? barrel_length*cos(barrel_theta) : w/2.0;
jford38 12:088a8203a9bb 92 return x + w/2.0 + barrel_extent; }
jford38 12:088a8203a9bb 93 int max_y(void) {
jford38 12:088a8203a9bb 94 int barrel_extent = (sin(barrel_theta) > 0) ? barrel_length*sin(barrel_theta) : 0;
jford38 12:088a8203a9bb 95 return y + h + wheel_rad + barrel_extent; }
jford38 12:088a8203a9bb 96
jford38 12:088a8203a9bb 97 void barrel_end(int& bx, int& by) {
jford38 12:088a8203a9bb 98 bx = x + w/2.0 + (barrel_length+1)*cos(barrel_theta);
jford38 12:088a8203a9bb 99 by = y+h+wheel_rad + (barrel_length+1)*sin(barrel_theta);
jford38 12:088a8203a9bb 100 }
jford38 10:5da9b27e050e 101
jford38 11:f455e907baba 102 void reposition(int new_x, int new_y, float new_theta) {
jford38 12:088a8203a9bb 103 float old_theta = barrel_theta;
jford38 12:088a8203a9bb 104 int old_x = x;
jford38 12:088a8203a9bb 105 int old_y = y;
jford38 12:088a8203a9bb 106 int minx = min_x();
jford38 12:088a8203a9bb 107 int miny = min_y();
jford38 12:088a8203a9bb 108 int maxx = max_x();
jford38 12:088a8203a9bb 109 int maxy = max_y();
jford38 12:088a8203a9bb 110
jford38 12:088a8203a9bb 111 x = new_x; y = new_y; barrel_theta = new_theta - (int)(new_theta/PI)*PI;
jford38 12:088a8203a9bb 112
jford38 12:088a8203a9bb 113 if(min_x() < 0 || max_x() > 128) {
jford38 12:088a8203a9bb 114 x = old_x; y = old_y; barrel_theta = old_theta;
jford38 12:088a8203a9bb 115 draw();
jford38 12:088a8203a9bb 116 return;
jford38 12:088a8203a9bb 117 }
jford38 12:088a8203a9bb 118
jford38 12:088a8203a9bb 119 sync.filled_rectangle(minx, miny, maxx, maxy, SKY_COLOR);
jford38 12:088a8203a9bb 120 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);
jford38 10:5da9b27e050e 121 draw();
jford38 10:5da9b27e050e 122 }
jford38 10:5da9b27e050e 123 void draw() {
jford38 10:5da9b27e050e 124 sync.line(x + w/2.0, y+h+wheel_rad, x + w/2.0 + barrel_length*cos(barrel_theta), y+h+wheel_rad + barrel_length*sin(barrel_theta), BLACK);
jford38 10:5da9b27e050e 125 sync.filled_rectangle(x, y+wheel_rad, x+w, y+h+wheel_rad, tank_color);
jford38 10:5da9b27e050e 126 sync.filled_circle(x+wheel_rad, y+wheel_rad, wheel_rad, BLACK);
jford38 10:5da9b27e050e 127 sync.filled_circle(x+w-wheel_rad, y+wheel_rad, wheel_rad, BLACK);
jford38 12:088a8203a9bb 128 }
jford38 12:088a8203a9bb 129 };
jford38 12:088a8203a9bb 130
jford38 12:088a8203a9bb 131 int convert24to16bpp(int col_24) {
jford38 12:088a8203a9bb 132 int b = col_24 & 0xFF;
jford38 12:088a8203a9bb 133 int g = (col_24 >> 8) & 0xFF;
jford38 12:088a8203a9bb 134 int r = (col_24 >> 16)& 0xFF;
jford38 12:088a8203a9bb 135
jford38 12:088a8203a9bb 136 r >>= 3;
jford38 12:088a8203a9bb 137 g >>= 2;
jford38 12:088a8203a9bb 138 b >>= 3;
jford38 12:088a8203a9bb 139
jford38 12:088a8203a9bb 140 return r<<11 | g<<5 | b;
jford38 12:088a8203a9bb 141 }
jford38 12:088a8203a9bb 142
jford38 12:088a8203a9bb 143 class Bullet{
jford38 12:088a8203a9bb 144 public:
jford38 12:088a8203a9bb 145 int x0;
jford38 12:088a8203a9bb 146 int y0;
jford38 12:088a8203a9bb 147 float vx0;
jford38 12:088a8203a9bb 148 float vy0;
jford38 12:088a8203a9bb 149 int x;
jford38 12:088a8203a9bb 150 int y;
jford38 12:088a8203a9bb 151 int speed;
jford38 12:088a8203a9bb 152 float time;
jford38 12:088a8203a9bb 153 bool in_flight;
jford38 12:088a8203a9bb 154
jford38 12:088a8203a9bb 155 Tank* tank;
jford38 12:088a8203a9bb 156
jford38 12:088a8203a9bb 157 Bullet(Tank* t) {
jford38 12:088a8203a9bb 158 tank = t;
jford38 12:088a8203a9bb 159 speed = 30;
jford38 12:088a8203a9bb 160 in_flight = false;
jford38 10:5da9b27e050e 161 }
jford38 12:088a8203a9bb 162 void shoot(void) {
jford38 12:088a8203a9bb 163 if(in_flight) {return;}
jford38 12:088a8203a9bb 164 time = 0;
jford38 12:088a8203a9bb 165 tank->barrel_end(x0, y0);
jford38 12:088a8203a9bb 166 x = x0; y = y0;
jford38 12:088a8203a9bb 167 vx0 = speed*cos(tank->barrel_theta);
jford38 12:088a8203a9bb 168 vy0 = speed*sin(tank->barrel_theta);
jford38 12:088a8203a9bb 169 in_flight = true;
jford38 12:088a8203a9bb 170 }
jford38 12:088a8203a9bb 171
jford38 12:088a8203a9bb 172 void time_step(float dt) {
jford38 12:088a8203a9bb 173 if(!in_flight) {return;}
jford38 12:088a8203a9bb 174 time += dt;
jford38 12:088a8203a9bb 175 int new_x = x0 + vx0*time;
jford38 12:088a8203a9bb 176 int new_y = y0 + vy0*time + 0.5*(-9.81)*time*time;
jford38 12:088a8203a9bb 177
jford38 12:088a8203a9bb 178 if(new_x == x && new_y == y) {
jford38 12:088a8203a9bb 179 return;
jford38 12:088a8203a9bb 180 }
jford38 12:088a8203a9bb 181
jford38 12:088a8203a9bb 182 if(new_x < 0 || new_x > 128 || new_y < 0 || new_y > 128) {
jford38 12:088a8203a9bb 183 in_flight = false;
jford38 12:088a8203a9bb 184 return;
jford38 12:088a8203a9bb 185 }
jford38 12:088a8203a9bb 186
jford38 12:088a8203a9bb 187 int col = sync.read_pixel(new_x, new_y);
jford38 12:088a8203a9bb 188 if(col != convert24to16bpp(SKY_COLOR)) {
jford38 12:088a8203a9bb 189 if(col == convert24to16bpp(TANK_BLUE)) {
jford38 12:088a8203a9bb 190 pc.printf("Player 1 wins!\n");
jford38 12:088a8203a9bb 191 }
jford38 12:088a8203a9bb 192 sync.pixel(x, y, SKY_COLOR);
jford38 12:088a8203a9bb 193 sync.filled_circle(new_x, new_y, 4, SKY_COLOR);
jford38 12:088a8203a9bb 194 in_flight = false;
jford38 12:088a8203a9bb 195 return;
jford38 12:088a8203a9bb 196 }
jford38 12:088a8203a9bb 197 sync.pixel(x, y, SKY_COLOR);
jford38 12:088a8203a9bb 198
jford38 12:088a8203a9bb 199 x = new_x;
jford38 12:088a8203a9bb 200 y = new_y;
jford38 12:088a8203a9bb 201 sync.pixel(x, y, BLACK);
jford38 12:088a8203a9bb 202 }
jford38 10:5da9b27e050e 203 };
jford38 10:5da9b27e050e 204
jford38 12:088a8203a9bb 205
jford38 6:3be57cf4bd33 206 void game_init(void) {
jford38 6:3be57cf4bd33 207
jford38 6:3be57cf4bd33 208 led1 = 0; led2 = 0; led3 = 0; led4 = 0;
jford38 6:3be57cf4bd33 209
jford38 6:3be57cf4bd33 210 pb_l.mode(PullUp);
jford38 6:3be57cf4bd33 211 pb_r.mode(PullUp);
jford38 6:3be57cf4bd33 212 pb_u.mode(PullUp);
jford38 6:3be57cf4bd33 213 pb_d.mode(PullUp);
jford38 6:3be57cf4bd33 214
jford38 6:3be57cf4bd33 215 pc.printf("\033[2J\033[0;0H"); // Clear the terminal screen.
jford38 6:3be57cf4bd33 216 pc.printf("I'm alive! Player 1\n"); // Let us know you made it this far.
jford38 7:9506f2d84162 217 int mode = game_menu();
jford38 9:ee330b1ba394 218 sync.init(&uLCD, mode); // Connect to the other player.
jford38 10:5da9b27e050e 219 map_init();
jford38 6:3be57cf4bd33 220 pc.printf("Initialized...\n"); // Let us know you finished initializing.
jford38 6:3be57cf4bd33 221 }
jford38 6:3be57cf4bd33 222
jford38 0:899c85cd266f 223 int main (void) {
jford38 8:e6dd05393290 224 int* p2_buttons;
jford38 8:e6dd05393290 225
jford38 8:e6dd05393290 226 game_init();
jford38 8:e6dd05393290 227
jford38 12:088a8203a9bb 228 Tank t1(4, 21, 12, 8, TANK_RED);
jford38 12:088a8203a9bb 229 Tank t2(111, 21, 12, 8, TANK_BLUE);
jford38 12:088a8203a9bb 230 Bullet b1(&t1);
jford38 12:088a8203a9bb 231 Bullet b2(&t2);
jford38 12:088a8203a9bb 232
jford38 5:cfec780c935b 233
jford38 12:088a8203a9bb 234 frame_timer.start();
jford38 0:899c85cd266f 235 while(1) {
jford38 12:088a8203a9bb 236
jford38 12:088a8203a9bb 237 //double acc_x, acc_y, acc_z;
jford38 12:088a8203a9bb 238 //acc.readXYZGravity(&acc_x,&acc_y,&acc_z); //read accelerometer
jford38 12:088a8203a9bb 239 //pc.printf("ACCELERATION X:%f Y:%f Z:%f\n", acc_x, acc_y, acc_z);
jford38 8:e6dd05393290 240
jford38 8:e6dd05393290 241 p2_buttons = sync.get_button_state();
jford38 8:e6dd05393290 242 led1 = p2_buttons[0] ^ !pb_u;
jford38 8:e6dd05393290 243 led2 = p2_buttons[1] ^ !pb_r;
jford38 8:e6dd05393290 244 led3 = p2_buttons[2] ^ !pb_d;
jford38 8:e6dd05393290 245 led4 = p2_buttons[3] ^ !pb_l;
jford38 11:f455e907baba 246
jford38 11:f455e907baba 247 if(!pb_l) t1.reposition(t1.x-1, t1.y, t1.barrel_theta);
jford38 11:f455e907baba 248 if(!pb_r) t1.reposition(t1.x+1, t1.y, t1.barrel_theta);
jford38 11:f455e907baba 249 if(p2_buttons[3]) t2.reposition(t2.x-1, t2.y, t2.barrel_theta);
jford38 11:f455e907baba 250 if(p2_buttons[1]) t2.reposition(t2.x+1, t2.y, t2.barrel_theta);
jford38 11:f455e907baba 251
jford38 12:088a8203a9bb 252 //if(!pb_d) t1.reposition(t1.x, t1.y, t1.barrel_theta-PI/30.0);
jford38 12:088a8203a9bb 253 if(!pb_u) t1.reposition(t1.x, t1.y, t1.barrel_theta+PI/30.0);
jford38 11:f455e907baba 254 if(p2_buttons[0]) t2.reposition(t2.x, t2.y, t2.barrel_theta+PI/30.0);
jford38 11:f455e907baba 255 if(p2_buttons[2]) t2.reposition(t2.x, t2.y, t2.barrel_theta-PI/30.0);
jford38 11:f455e907baba 256
jford38 12:088a8203a9bb 257 if(!pb_d) { b1.shoot(); }
jford38 12:088a8203a9bb 258
jford38 12:088a8203a9bb 259 b1.time_step(0.01);
jford38 12:088a8203a9bb 260 //b2.time_step(1);
jford38 12:088a8203a9bb 261 frame_timer.reset();
jford38 11:f455e907baba 262
jford38 12:088a8203a9bb 263 sync.update();
jford38 3:3ddefff03cb2 264 }
jford38 0:899c85cd266f 265 }