ELEC2645 (2019/20) / Mbed 2 deprecated ELEC2645_Project_el19tb

Dependencies:   mbed

Committer:
el19tb
Date:
Thu May 14 01:07:27 2020 +0000
Revision:
17:67dbdfcdcec2
Parent:
16:8a65cccd9685
Child:
18:6be4c3c94a3d
created a moving river stream in the last 3 rows of the screen, with different sprites for design

Who changed what in which revision?

UserRevisionLine numberNew contents of line
el19tb 2:86cef2afa648 1 #include "CrossyChicken.h"
el19tb 2:86cef2afa648 2 #include "Menu.h"
el19tb 3:648c9d5001be 3 #include "GraphicEngine.h"
el19tb 3:648c9d5001be 4 #include <vector>
el19tb 3:648c9d5001be 5 #include <stdio.h>
el19tb 3:648c9d5001be 6 #include <cstddef>
el19tb 13:cd6d2f999057 7 #include "Vehicle.h"
el19tb 2:86cef2afa648 8
el19tb 5:6e3afee7eac3 9 // start from the top (height)
el19tb 2:86cef2afa648 10 Gamepad gamepad;
el19tb 2:86cef2afa648 11
el19tb 3:648c9d5001be 12 //create three class: CAR LANE, SAFETY LANE, OBSTACLE LANE(water)
el19tb 3:648c9d5001be 13 //random
el19tb 3:648c9d5001be 14 //algoritmic way of generating lanes
el19tb 3:648c9d5001be 15
el19tb 2:86cef2afa648 16 //size of each each tile in the game
el19tb 4:aae7f8d4ab78 17 int grid = 4;
el19tb 2:86cef2afa648 18
el19tb 3:648c9d5001be 19 //make one object of chicken
el19tb 3:648c9d5001be 20 //use this to move around the lcd
el19tb 6:e285eaf8bdcd 21 Chicken chicken((84/2)-grid/2, 48-grid, grid);
el19tb 3:648c9d5001be 22 Chicken *chickenptr= &chicken;
el19tb 3:648c9d5001be 23
el19tb 3:648c9d5001be 24 //there will be multiple cars
el19tb 5:6e3afee7eac3 25 Car firstLane[2];
el19tb 5:6e3afee7eac3 26 Car secondLane[2];
el19tb 5:6e3afee7eac3 27 Car thirdLane[3];
el19tb 7:1dce07fd0867 28 Car fourthLane[3];
el19tb 7:1dce07fd0867 29 Car log1Lane[2];
el19tb 7:1dce07fd0867 30 Car lo[2];
el19tb 7:1dce07fd0867 31 Car logger[2];
el19tb 9:d210eede4a1b 32 Car vop[2];
el19tb 3:648c9d5001be 33
el19tb 8:52794de935b2 34 int screenW = 84;
el19tb 8:52794de935b2 35 int screenH = 48;
el19tb 8:52794de935b2 36
el19tb 3:648c9d5001be 37 //class that whill show objects
el19tb 3:648c9d5001be 38 GraphicEngine graphics(chickenptr);
el19tb 2:86cef2afa648 39
el19tb 8:52794de935b2 40 bool frogLog = false;
el19tb 8:52794de935b2 41 bool frogDie = false; // whenever the frog is above safety lane in the middle
el19tb 8:52794de935b2 42 bool attach = false;
el19tb 8:52794de935b2 43
el19tb 11:cc5861abfca5 44 CrossyChicken::CrossyChicken(Level *level)
el19tb 11:cc5861abfca5 45 {
el19tb 11:cc5861abfca5 46 this->local_level = level;
el19tb 11:cc5861abfca5 47 }
el19tb 11:cc5861abfca5 48
el19tb 2:86cef2afa648 49 //main function that starts the game
el19tb 3:648c9d5001be 50 void CrossyChicken::start(){
el19tb 2:86cef2afa648 51 //game setup
el19tb 3:648c9d5001be 52 graphics.init();
el19tb 3:648c9d5001be 53 graphics.contrast();
el19tb 3:648c9d5001be 54 graphics.backLightOn();
el19tb 2:86cef2afa648 55 gamepad.init();
el19tb 15:b15bf9357cd9 56 row_number = 1;
el19tb 15:b15bf9357cd9 57
el19tb 4:aae7f8d4ab78 58
el19tb 5:6e3afee7eac3 59 //first lane of left racers
el19tb 5:6e3afee7eac3 60 firstLane[0].setSeperation(0);
el19tb 7:1dce07fd0867 61 firstLane[1].setSeperation(20);
el19tb 5:6e3afee7eac3 62 firstLane[0].setRow(2);
el19tb 5:6e3afee7eac3 63 firstLane[1].setRow(2);
el19tb 4:aae7f8d4ab78 64
el19tb 5:6e3afee7eac3 65 secondLane[0].setSeperation(0);
el19tb 7:1dce07fd0867 66 secondLane[1].setSeperation(20);
el19tb 5:6e3afee7eac3 67 secondLane[0].setRow(3);
el19tb 5:6e3afee7eac3 68 secondLane[1].setRow(3);
el19tb 5:6e3afee7eac3 69
el19tb 7:1dce07fd0867 70 thirdLane[0].setSeperation(0);
el19tb 7:1dce07fd0867 71 thirdLane[1].setSeperation(20);
el19tb 7:1dce07fd0867 72 thirdLane[2].setSeperation(40);
el19tb 5:6e3afee7eac3 73 thirdLane[0].setRow(4);
el19tb 5:6e3afee7eac3 74 thirdLane[1].setRow(4);
el19tb 5:6e3afee7eac3 75 thirdLane[2].setRow(4);
el19tb 7:1dce07fd0867 76
el19tb 7:1dce07fd0867 77 fourthLane[0].setSeperation(10);
el19tb 7:1dce07fd0867 78 fourthLane[1].setSeperation(30);
el19tb 7:1dce07fd0867 79 fourthLane[2].setSeperation(50);
el19tb 7:1dce07fd0867 80 fourthLane[0].setRow(5);
el19tb 7:1dce07fd0867 81 fourthLane[1].setRow(5);
el19tb 7:1dce07fd0867 82 fourthLane[2].setRow(5);
el19tb 7:1dce07fd0867 83
el19tb 7:1dce07fd0867 84 // log lane 1
el19tb 7:1dce07fd0867 85 log1Lane[0].setSeperation(0);
el19tb 7:1dce07fd0867 86 log1Lane[1].setSeperation(20);
el19tb 7:1dce07fd0867 87 log1Lane[0].setRow(7);
el19tb 7:1dce07fd0867 88 log1Lane[1].setRow(7);
el19tb 7:1dce07fd0867 89
el19tb 7:1dce07fd0867 90 // log lane 2
el19tb 7:1dce07fd0867 91 lo[0].setSeperation(10);
el19tb 7:1dce07fd0867 92 lo[1].setSeperation(30);
el19tb 7:1dce07fd0867 93 lo[0].setRow(8);
el19tb 7:1dce07fd0867 94 lo[1].setRow(8);
el19tb 7:1dce07fd0867 95
el19tb 7:1dce07fd0867 96 // log lane 3
el19tb 7:1dce07fd0867 97 logger[0].setSeperation(0);
el19tb 7:1dce07fd0867 98 logger[1].setSeperation(20);
el19tb 7:1dce07fd0867 99 logger[0].setRow(9);
el19tb 7:1dce07fd0867 100 logger[1].setRow(9);
el19tb 9:d210eede4a1b 101
el19tb 9:d210eede4a1b 102 // log lane 3
el19tb 9:d210eede4a1b 103 vop[0].setSeperation(0);
el19tb 9:d210eede4a1b 104 vop[1].setSeperation(20);
el19tb 9:d210eede4a1b 105 vop[0].setRow(10);
el19tb 9:d210eede4a1b 106 vop[1].setRow(10);
el19tb 5:6e3afee7eac3 107
el19tb 2:86cef2afa648 108 //keep reading and processing user input
el19tb 3:648c9d5001be 109 while(1) {
el19tb 3:648c9d5001be 110 graphics.clear();
el19tb 8:52794de935b2 111
el19tb 8:52794de935b2 112 for(int i = 0; i < 2; i++){
el19tb 5:6e3afee7eac3 113 moveCar(&firstLane[i], 2, (-2)); // change x position (moving)
el19tb 5:6e3afee7eac3 114 }
el19tb 5:6e3afee7eac3 115
el19tb 5:6e3afee7eac3 116 for(int x = 0; x < 2; x++){
el19tb 5:6e3afee7eac3 117 moveCar(&secondLane[x], 1, 1);
el19tb 5:6e3afee7eac3 118 }
el19tb 5:6e3afee7eac3 119
el19tb 5:6e3afee7eac3 120 for(int t = 0; t < 3; t++){
el19tb 5:6e3afee7eac3 121 moveCar(&thirdLane[t], 2, 1);
el19tb 7:1dce07fd0867 122 }
el19tb 7:1dce07fd0867 123
el19tb 7:1dce07fd0867 124 for(int c = 0; c < 3; c++){
el19tb 7:1dce07fd0867 125 moveCar(&fourthLane[c], 2, 1);
el19tb 7:1dce07fd0867 126 }
el19tb 7:1dce07fd0867 127
el19tb 7:1dce07fd0867 128 for(int v = 0; v < 2; v++){
el19tb 8:52794de935b2 129 moveCar(&log1Lane[v], 1, 1);
el19tb 7:1dce07fd0867 130 }
el19tb 7:1dce07fd0867 131
el19tb 7:1dce07fd0867 132 for(int b = 0; b < 2; b++){
el19tb 7:1dce07fd0867 133 moveCar(&lo[b], 2, 1);
el19tb 9:d210eede4a1b 134 // moveCar(&logger[b], 2, 2);
el19tb 9:d210eede4a1b 135 moveCar(&vop[b], 1, 2);
el19tb 5:6e3afee7eac3 136
el19tb 5:6e3afee7eac3 137 }
el19tb 5:6e3afee7eac3 138
el19tb 5:6e3afee7eac3 139 graphics.showCar(firstLane);
el19tb 5:6e3afee7eac3 140 graphics.showCar(secondLane);
el19tb 5:6e3afee7eac3 141 graphics.showCar(thirdLane);
el19tb 7:1dce07fd0867 142 graphics.showCar(fourthLane);
el19tb 7:1dce07fd0867 143 graphics.showCar(log1Lane);
el19tb 7:1dce07fd0867 144 graphics.showCar(lo);
el19tb 9:d210eede4a1b 145 graphics.showCar(logger);
el19tb 9:d210eede4a1b 146 graphics.showCar(vop);
el19tb 9:d210eede4a1b 147
el19tb 8:52794de935b2 148 graphics.showChicken();
el19tb 8:52794de935b2 149 process_input();
el19tb 8:52794de935b2 150
el19tb 8:52794de935b2 151 // now when the chicken is above the safety
el19tb 8:52794de935b2 152 // lane we need to ensure that it only can go on logs
el19tb 8:52794de935b2 153 if(chicken.y < screenH - grid*6){
el19tb 8:52794de935b2 154 frogDie = true; // frog can die if it is in water
el19tb 7:1dce07fd0867 155
el19tb 8:52794de935b2 156 //if it is not in a log
el19tb 8:52794de935b2 157 for(int x = 0; x < 2; x++){
el19tb 8:52794de935b2 158 setCollision(&log1Lane[x]);
el19tb 9:d210eede4a1b 159 setCollision(&lo[x]);
el19tb 9:d210eede4a1b 160 setCollision(&logger[x]);
el19tb 9:d210eede4a1b 161 setCollision(&vop[x]);
el19tb 9:d210eede4a1b 162
el19tb 8:52794de935b2 163 if(attach){
el19tb 8:52794de935b2 164 frogOnLog(&log1Lane[x]);
el19tb 9:d210eede4a1b 165 frogOnLog(&lo[x]);
el19tb 9:d210eede4a1b 166 frogOnLog(&logger[x]);
el19tb 9:d210eede4a1b 167 frogOnLog(&vop[x]);
el19tb 9:d210eede4a1b 168
el19tb 8:52794de935b2 169 }
el19tb 8:52794de935b2 170 }
el19tb 8:52794de935b2 171
el19tb 8:52794de935b2 172 if(!attach){
el19tb 8:52794de935b2 173 graphics.print();
el19tb 9:d210eede4a1b 174 }
el19tb 6:e285eaf8bdcd 175 }
el19tb 9:d210eede4a1b 176
el19tb 3:648c9d5001be 177 graphics.refresh();
el19tb 9:d210eede4a1b 178 wait_ms(70);
el19tb 2:86cef2afa648 179 }
el19tb 2:86cef2afa648 180 }
el19tb 2:86cef2afa648 181
el19tb 7:1dce07fd0867 182 // log intersects then frog.x = log[i].speed
el19tb 7:1dce07fd0867 183 // frog is attached function
el19tb 7:1dce07fd0867 184 // detach the frog when user goes up or down
el19tb 7:1dce07fd0867 185 // if the frog is back to the safe zone detatch also
el19tb 7:1dce07fd0867 186 // whenever the frog moves detach
el19tb 2:86cef2afa648 187 //A moves right
el19tb 2:86cef2afa648 188 //X moves upward
el19tb 2:86cef2afa648 189 //B moves downward
el19tb 2:86cef2afa648 190 //Y moves left
el19tb 2:86cef2afa648 191 void CrossyChicken::process_input() {
el19tb 3:648c9d5001be 192 //determine the input
el19tb 8:52794de935b2 193 /* make this a switch statement */
el19tb 3:648c9d5001be 194 if(gamepad.A_pressed()){
el19tb 3:648c9d5001be 195 moveChicken(1,0);
el19tb 8:52794de935b2 196 attach = false;
el19tb 3:648c9d5001be 197 } else if(gamepad.X_pressed()){
el19tb 3:648c9d5001be 198 moveChicken(0,-1);
el19tb 8:52794de935b2 199 attach = false;
el19tb 3:648c9d5001be 200 } else if(gamepad.B_pressed()){
el19tb 3:648c9d5001be 201 moveChicken(0,1);
el19tb 8:52794de935b2 202 attach = false;
el19tb 3:648c9d5001be 203 } else if(gamepad.Y_pressed()){
el19tb 3:648c9d5001be 204 moveChicken(-1,0);
el19tb 8:52794de935b2 205 attach = false;
el19tb 8:52794de935b2 206 }
el19tb 8:52794de935b2 207 }
el19tb 8:52794de935b2 208
el19tb 15:b15bf9357cd9 209 // every level is going to have the same
el19tb 15:b15bf9357cd9 210 void CrossyChicken::drawRoadBackground()
el19tb 15:b15bf9357cd9 211 {
el19tb 15:b15bf9357cd9 212 int grid_screen_width = 22; // number of visible widths on width screen
el19tb 15:b15bf9357cd9 213
el19tb 16:8a65cccd9685 214 // 4 lanes of roads
el19tb 15:b15bf9357cd9 215 for(int i = 0; i < 4; i++){
el19tb 15:b15bf9357cd9 216 graphics.drawRoads(row_number);
el19tb 16:8a65cccd9685 217 row_number++;
el19tb 16:8a65cccd9685 218 }
el19tb 16:8a65cccd9685 219 }
el19tb 16:8a65cccd9685 220
el19tb 16:8a65cccd9685 221 // we are going to have two safety lanes
el19tb 16:8a65cccd9685 222 void CrossyChicken::drawSafetyLanes()
el19tb 16:8a65cccd9685 223 {
el19tb 16:8a65cccd9685 224 int state = 1;
el19tb 16:8a65cccd9685 225
el19tb 16:8a65cccd9685 226 for(int x = 0; x < 22; x++){
el19tb 16:8a65cccd9685 227 // fsm for drawing safety lane background
el19tb 16:8a65cccd9685 228 switch(state)
el19tb 16:8a65cccd9685 229 {
el19tb 16:8a65cccd9685 230 case 1:
el19tb 16:8a65cccd9685 231 graphics.drawFirstSafetyBackground(x, 0); // safety lane so row 0
el19tb 16:8a65cccd9685 232 graphics.drawFirstSafetyBackground(x, 6); // middle lane so row 6
el19tb 16:8a65cccd9685 233 state++;
el19tb 16:8a65cccd9685 234 break;
el19tb 16:8a65cccd9685 235 case 2:
el19tb 16:8a65cccd9685 236 graphics.drawSecondSafetyBackground(x, 0); // safety lane so row 0
el19tb 16:8a65cccd9685 237 graphics.drawSecondSafetyBackground(x, 6); // middle lane so row 6
el19tb 16:8a65cccd9685 238 state -= 1; // back to inital state
el19tb 16:8a65cccd9685 239 break;
el19tb 16:8a65cccd9685 240 }
el19tb 16:8a65cccd9685 241 }
el19tb 16:8a65cccd9685 242 }
el19tb 15:b15bf9357cd9 243
el19tb 17:67dbdfcdcec2 244 // the water sprites are going to 'move' to make it realistic
el19tb 17:67dbdfcdcec2 245 void CrossyChicken::createWater(){
el19tb 17:67dbdfcdcec2 246 int state = 1;
el19tb 17:67dbdfcdcec2 247
el19tb 17:67dbdfcdcec2 248 for(it = 0; it != 21; it++)
el19tb 17:67dbdfcdcec2 249 {
el19tb 17:67dbdfcdcec2 250 // fsm for drawing safety lane background
el19tb 17:67dbdfcdcec2 251 switch(state)
el19tb 17:67dbdfcdcec2 252 {
el19tb 17:67dbdfcdcec2 253 case 1: // initial state
el19tb 17:67dbdfcdcec2 254 row_water_one[it].push_back('F'); // first type of water
el19tb 17:67dbdfcdcec2 255 state++; // transition to next state
el19tb 17:67dbdfcdcec2 256 break;
el19tb 17:67dbdfcdcec2 257 case 2:
el19tb 17:67dbdfcdcec2 258 row_water_one[it].push_back('S'); // second type of water
el19tb 17:67dbdfcdcec2 259 state++; // transition to state 3
el19tb 17:67dbdfcdcec2 260 break;
el19tb 17:67dbdfcdcec2 261
el19tb 17:67dbdfcdcec2 262 case 3:
el19tb 17:67dbdfcdcec2 263 row_water_one[it].push_back('T'); // third type of water
el19tb 17:67dbdfcdcec2 264 state = 1; // back to start state
el19tb 17:67dbdfcdcec2 265 break;
el19tb 17:67dbdfcdcec2 266 }
el19tb 17:67dbdfcdcec2 267 }
el19tb 17:67dbdfcdcec2 268 }
el19tb 17:67dbdfcdcec2 269
el19tb 17:67dbdfcdcec2 270 void CrossyChicken::moveWater()
el19tb 16:8a65cccd9685 271 {
el19tb 17:67dbdfcdcec2 272 for(it = 0; it != row_water_one.size(); it++){
el19tb 17:67dbdfcdcec2 273 graphics.moveWaterWithSpeed(&row_water_one[it]);
el19tb 17:67dbdfcdcec2 274 }
el19tb 17:67dbdfcdcec2 275 }
el19tb 16:8a65cccd9685 276
el19tb 17:67dbdfcdcec2 277 // if sprite goes out of bound then show again
el19tb 17:67dbdfcdcec2 278 void CrossyChicken::loopWater(Water *sprite)
el19tb 17:67dbdfcdcec2 279 {
el19tb 17:67dbdfcdcec2 280 // check if car goes out of bounds
el19tb 17:67dbdfcdcec2 281 if(sprite->x > 84+grid){
el19tb 17:67dbdfcdcec2 282 sprite->x = -4;
el19tb 17:67dbdfcdcec2 283
el19tb 17:67dbdfcdcec2 284 } else if(sprite->x < -4){
el19tb 17:67dbdfcdcec2 285 sprite->x = 84 + grid;
el19tb 17:67dbdfcdcec2 286 }
el19tb 15:b15bf9357cd9 287 }
el19tb 15:b15bf9357cd9 288
el19tb 8:52794de935b2 289 // make the frog move same speed as log
el19tb 8:52794de935b2 290 // if the frog moves then detach
el19tb 8:52794de935b2 291 void CrossyChicken::frogOnLog(Car *log) {
el19tb 9:d210eede4a1b 292 if(log->seperation != 0){
el19tb 9:d210eede4a1b 293 chicken.x += 1.0;
el19tb 9:d210eede4a1b 294 }
el19tb 2:86cef2afa648 295 }
el19tb 2:86cef2afa648 296
el19tb 3:648c9d5001be 297 //moves the chicken around the grid
el19tb 3:648c9d5001be 298 void CrossyChicken::moveChicken(int xWay, int yWay){
el19tb 3:648c9d5001be 299 //increment the left side of the chicken by a value of the grid size
el19tb 4:aae7f8d4ab78 300 chicken.x += xWay * 4;
el19tb 3:648c9d5001be 301
el19tb 3:648c9d5001be 302 //increment the top side by a value of grid sizw
el19tb 4:aae7f8d4ab78 303 chicken.y += yWay * 4;
el19tb 3:648c9d5001be 304
el19tb 6:e285eaf8bdcd 305 chicken.left_side = chicken.x;
el19tb 6:e285eaf8bdcd 306 chicken.right_side = grid + chicken.x;
el19tb 6:e285eaf8bdcd 307 chicken.up = chicken.y;
el19tb 6:e285eaf8bdcd 308 chicken.down = grid + chicken.y;
el19tb 8:52794de935b2 309
el19tb 3:648c9d5001be 310 //display the new state of the chicken
el19tb 9:d210eede4a1b 311 //graphics.showChicken();
el19tb 3:648c9d5001be 312
el19tb 8:52794de935b2 313 //wait_ms(30);
el19tb 2:86cef2afa648 314 }
el19tb 2:86cef2afa648 315
el19tb 5:6e3afee7eac3 316 void CrossyChicken::moveCar(Car *car, int dir, int x) {
el19tb 5:6e3afee7eac3 317 car->speedMedium(dir, x);
el19tb 4:aae7f8d4ab78 318
el19tb 8:52794de935b2 319 // check if car goes out of bounds
el19tb 5:6e3afee7eac3 320 if(car->vehicle.x > 84+grid){
el19tb 5:6e3afee7eac3 321 car->vehicle.x = -4;
el19tb 3:648c9d5001be 322
el19tb 5:6e3afee7eac3 323 } else if(car->vehicle.x < -4){
el19tb 5:6e3afee7eac3 324 car->vehicle.x = 84 + grid;
el19tb 5:6e3afee7eac3 325 }
el19tb 5:6e3afee7eac3 326 }
el19tb 5:6e3afee7eac3 327
el19tb 5:6e3afee7eac3 328 // debug
el19tb 8:52794de935b2 329 void CrossyChicken::setCollision(Car *car){
el19tb 4:aae7f8d4ab78 330
el19tb 5:6e3afee7eac3 331 float other_bottom = car->vehicle.height + car->vehicle.y;
el19tb 6:e285eaf8bdcd 332
el19tb 6:e285eaf8bdcd 333
el19tb 5:6e3afee7eac3 334 if(!(chicken.up >= other_bottom ||
el19tb 5:6e3afee7eac3 335 (chicken.right_side <= car->vehicle.x) ||
el19tb 5:6e3afee7eac3 336 (chicken.down <= car->vehicle.y) ||
el19tb 5:6e3afee7eac3 337 chicken.left_side >= (car->vehicle.width + car->vehicle.x))){
el19tb 5:6e3afee7eac3 338 graphics.printTest();
el19tb 8:52794de935b2 339
el19tb 8:52794de935b2 340 if(chicken.y < screenH - grid*6){
el19tb 8:52794de935b2 341 attach = true;
el19tb 8:52794de935b2 342 } else {
el19tb 8:52794de935b2 343 attach = false;
el19tb 8:52794de935b2 344 }
el19tb 8:52794de935b2 345 }
el19tb 8:52794de935b2 346 }
el19tb 8:52794de935b2 347
el19tb 8:52794de935b2 348 bool CrossyChicken::returnCollision(Car* log){
el19tb 8:52794de935b2 349
el19tb 8:52794de935b2 350 float ob= log->vehicle.height + log->vehicle.y;
el19tb 8:52794de935b2 351
el19tb 8:52794de935b2 352 if(!(chicken.up >= ob||
el19tb 8:52794de935b2 353 (chicken.right_side <= log->vehicle.x) ||
el19tb 8:52794de935b2 354 (chicken.down <= log->vehicle.y) ||
el19tb 8:52794de935b2 355 chicken.left_side >= (log->vehicle.width + log->vehicle.x))){
el19tb 8:52794de935b2 356 return true;
el19tb 5:6e3afee7eac3 357 }
el19tb 5:6e3afee7eac3 358 }