ECE 4180 Lab 4 Racing Game

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

Committer:
deathernater
Date:
Thu Mar 16 01:27:09 2017 +0000
Revision:
0:a3096c3dccff
Initial

Who changed what in which revision?

UserRevisionLine numberNew contents of line
deathernater 0:a3096c3dccff 1 #include "mbed.h"
deathernater 0:a3096c3dccff 2 #include "rtos.h"
deathernater 0:a3096c3dccff 3 #include "SDFileSystem.h"
deathernater 0:a3096c3dccff 4 #include "wave_player.h"
deathernater 0:a3096c3dccff 5 #include "uLCD_4DGL.h"
deathernater 0:a3096c3dccff 6
deathernater 0:a3096c3dccff 7 #define PI 3.14159
deathernater 0:a3096c3dccff 8
deathernater 0:a3096c3dccff 9 //Serial Debug
deathernater 0:a3096c3dccff 10 Serial pc(USBTX, USBRX);
deathernater 0:a3096c3dccff 11
deathernater 0:a3096c3dccff 12 //Joystick
deathernater 0:a3096c3dccff 13 AnalogIn jsy(p16);
deathernater 0:a3096c3dccff 14 AnalogIn jsx(p15);
deathernater 0:a3096c3dccff 15
deathernater 0:a3096c3dccff 16 //SD Card
deathernater 0:a3096c3dccff 17 SDFileSystem sd(p5, p6, p7, p8, "sd");
deathernater 0:a3096c3dccff 18
deathernater 0:a3096c3dccff 19 //LCD Display
deathernater 0:a3096c3dccff 20 uLCD_4DGL uLCD(p13, p14, p30); // serial tx, serial rx, reset pin
deathernater 0:a3096c3dccff 21
deathernater 0:a3096c3dccff 22 //Analog Out Jack
deathernater 0:a3096c3dccff 23 AnalogOut DACout(p18);
deathernater 0:a3096c3dccff 24 //On Board Speaker
deathernater 0:a3096c3dccff 25 PwmOut PWMout(p26);
deathernater 0:a3096c3dccff 26
deathernater 0:a3096c3dccff 27 //Audio Player
deathernater 0:a3096c3dccff 28 wave_player player(&DACout, &PWMout);
deathernater 0:a3096c3dccff 29
deathernater 0:a3096c3dccff 30 //Threads
deathernater 0:a3096c3dccff 31 Thread audioThread, thread2, thread3, gameDisplayThread;
deathernater 0:a3096c3dccff 32
deathernater 0:a3096c3dccff 33 //Game Data
deathernater 0:a3096c3dccff 34 float inputLR, inputSpeed;
deathernater 0:a3096c3dccff 35 int carScrPosX = 63, carScrPosY = 120;
deathernater 0:a3096c3dccff 36 int carVel = 0, odo = 0;
deathernater 0:a3096c3dccff 37 bool redraw = true;
deathernater 0:a3096c3dccff 38 int wallY1 = 6, wallY2 = 36, wallY3 = 68, wallThickness = 8;
deathernater 0:a3096c3dccff 39 int wallsStart[3], wallsEnd[3], wallsY[3] = {wallY1, wallY2, wallY3};
deathernater 0:a3096c3dccff 40
deathernater 0:a3096c3dccff 41 void generateWall(int wall) {
deathernater 0:a3096c3dccff 42 float wallSeed1 = (float) rand() / RAND_MAX * 63;
deathernater 0:a3096c3dccff 43 float wallSeed2 = (float) rand() / RAND_MAX * 63;
deathernater 0:a3096c3dccff 44 int wallStart = (int) (wallSeed1 + 0.5);
deathernater 0:a3096c3dccff 45 int wallEnd = (int) (wallSeed2 + 0.5);
deathernater 0:a3096c3dccff 46 wallsStart[wall] = wallStart;
deathernater 0:a3096c3dccff 47 wallsEnd[wall] = wallEnd + wallStart;
deathernater 0:a3096c3dccff 48 if ((wallsEnd[wall] - wallsStart[wall]) > 110) {
deathernater 0:a3096c3dccff 49 generateWall(wall);
deathernater 0:a3096c3dccff 50 }
deathernater 0:a3096c3dccff 51 }
deathernater 0:a3096c3dccff 52
deathernater 0:a3096c3dccff 53 bool updatePosition() {
deathernater 0:a3096c3dccff 54 if (jsy > 0.7 && carVel < 8) {
deathernater 0:a3096c3dccff 55 carVel += 1;
deathernater 0:a3096c3dccff 56 } else if (jsy < 0.3 && carVel > 0) {
deathernater 0:a3096c3dccff 57 carVel -= 1;
deathernater 0:a3096c3dccff 58 }
deathernater 0:a3096c3dccff 59 if (jsx > 0.55 && (carScrPosX - 4) >= 0) {
deathernater 0:a3096c3dccff 60 int delta = (int) (jsx / 0.95 * 8 + 0.5);
deathernater 0:a3096c3dccff 61 if (((carScrPosX - 4) - delta) >= 0) {
deathernater 0:a3096c3dccff 62 carScrPosX -= delta;
deathernater 0:a3096c3dccff 63 }
deathernater 0:a3096c3dccff 64 } else if (jsx < 0.45 && (carScrPosX + 4) <= 127) {
deathernater 0:a3096c3dccff 65 int delta = (int) ((1 - jsx) / 0.95 * 8 + 0.5);
deathernater 0:a3096c3dccff 66 if (((carScrPosX + 4) + delta) <= 127) {
deathernater 0:a3096c3dccff 67 carScrPosX += delta;
deathernater 0:a3096c3dccff 68 }
deathernater 0:a3096c3dccff 69 }
deathernater 0:a3096c3dccff 70 odo += carVel;
deathernater 0:a3096c3dccff 71 wallsY[0] += carVel;
deathernater 0:a3096c3dccff 72 wallsY[1] += carVel;
deathernater 0:a3096c3dccff 73 wallsY[2] += carVel;
deathernater 0:a3096c3dccff 74 //Check collision
deathernater 0:a3096c3dccff 75 for (int i = 0; i < 3; i++) {
deathernater 0:a3096c3dccff 76 if (wallsY[i] > 127) {
deathernater 0:a3096c3dccff 77 wallsY[i] = 0;
deathernater 0:a3096c3dccff 78 generateWall(i);
deathernater 0:a3096c3dccff 79 uLCD.cls();
deathernater 0:a3096c3dccff 80 redraw = true;
deathernater 0:a3096c3dccff 81 }
deathernater 0:a3096c3dccff 82 if ((carScrPosX - 4) > wallsEnd[i] || (carScrPosX + 4) < wallsStart[i]
deathernater 0:a3096c3dccff 83 || (carScrPosY - 5) > (wallsY[i] + wallThickness)
deathernater 0:a3096c3dccff 84 || (carScrPosY + 5) < wallsY[i]) {
deathernater 0:a3096c3dccff 85 //pc.printf("No Collision\n");
deathernater 0:a3096c3dccff 86 Thread::wait(33);
deathernater 0:a3096c3dccff 87 } else {
deathernater 0:a3096c3dccff 88 //pc.printf("Crash\n");
deathernater 0:a3096c3dccff 89 return false;
deathernater 0:a3096c3dccff 90 }
deathernater 0:a3096c3dccff 91 }
deathernater 0:a3096c3dccff 92 return true;
deathernater 0:a3096c3dccff 93 }
deathernater 0:a3096c3dccff 94
deathernater 0:a3096c3dccff 95 void playSound() {
deathernater 0:a3096c3dccff 96 //setup PWM hardware for a Class D style audio output
deathernater 0:a3096c3dccff 97 PWMout.period(1.0/400000.0);
deathernater 0:a3096c3dccff 98 while (true) {
deathernater 0:a3096c3dccff 99 FILE *fp = fopen("/sd/Skrillex_Diplo.wav", "r");
deathernater 0:a3096c3dccff 100 if(fp == NULL) {
deathernater 0:a3096c3dccff 101 error("Could not open file for read\n");
deathernater 0:a3096c3dccff 102 }
deathernater 0:a3096c3dccff 103 player.play(fp);
deathernater 0:a3096c3dccff 104 fclose(fp);
deathernater 0:a3096c3dccff 105 Thread::wait(500);
deathernater 0:a3096c3dccff 106 }
deathernater 0:a3096c3dccff 107
deathernater 0:a3096c3dccff 108 }
deathernater 0:a3096c3dccff 109
deathernater 0:a3096c3dccff 110 int main() {
deathernater 0:a3096c3dccff 111 audioThread.start(playSound);
deathernater 0:a3096c3dccff 112 uLCD.baudrate(3000000); //jack up baud rate to max for fast display
deathernater 0:a3096c3dccff 113 uLCD.media_init();
deathernater 0:a3096c3dccff 114 uLCD.set_sector_address(0x003B, 0x5600);
deathernater 0:a3096c3dccff 115 uLCD.display_image(0,0);
deathernater 0:a3096c3dccff 116 uLCD.printf("Welcome to Random\nHorizons 3\nThrottle Up!\n(Push Forward)");
deathernater 0:a3096c3dccff 117 generateWall(0);
deathernater 0:a3096c3dccff 118 generateWall(1);
deathernater 0:a3096c3dccff 119 generateWall(2);
deathernater 0:a3096c3dccff 120 int oldCarPosX = carScrPosX;
deathernater 0:a3096c3dccff 121 int oldWallsY[3] = {wallY1, wallY2, wallY3};
deathernater 0:a3096c3dccff 122 while (jsy < 0.95) Thread::wait(33);
deathernater 0:a3096c3dccff 123 uLCD.cls();
deathernater 0:a3096c3dccff 124 uLCD.printf("Controls:\nUp (Accel.)\nDown (Brake)\nLeft (Left)\n");
deathernater 0:a3096c3dccff 125 uLCD.printf("Right (Right)\nDodge the Walls!!\n");
deathernater 0:a3096c3dccff 126 Thread::wait(5000);
deathernater 0:a3096c3dccff 127 uLCD.cls();
deathernater 0:a3096c3dccff 128 do {
deathernater 0:a3096c3dccff 129 if (oldCarPosX != carScrPosX || redraw) {
deathernater 0:a3096c3dccff 130 uLCD.filled_rectangle(oldCarPosX - 4, carScrPosY - 5,
deathernater 0:a3096c3dccff 131 oldCarPosX + 4, carScrPosY + 5, BLACK);
deathernater 0:a3096c3dccff 132 uLCD.filled_rectangle(carScrPosX - 4, carScrPosY - 5,
deathernater 0:a3096c3dccff 133 carScrPosX + 4, carScrPosY + 5, BLUE);
deathernater 0:a3096c3dccff 134 uLCD.filled_rectangle(carScrPosX - 1, carScrPosY - 3,
deathernater 0:a3096c3dccff 135 carScrPosX + 2, carScrPosY + 3, WHITE);
deathernater 0:a3096c3dccff 136 redraw = false;
deathernater 0:a3096c3dccff 137 }
deathernater 0:a3096c3dccff 138 for (int i = 0; i < 3; i++) {
deathernater 0:a3096c3dccff 139 if (oldWallsY[i] != wallsY[i]) {
deathernater 0:a3096c3dccff 140 uLCD.filled_rectangle(wallsStart[i], oldWallsY[i],
deathernater 0:a3096c3dccff 141 wallsEnd[i], oldWallsY[i] + wallThickness, BLACK);
deathernater 0:a3096c3dccff 142 uLCD.filled_rectangle(wallsStart[i], wallsY[i],
deathernater 0:a3096c3dccff 143 wallsEnd[i], wallsY[i] + wallThickness, RED);
deathernater 0:a3096c3dccff 144 oldWallsY[i] = wallsY[i];
deathernater 0:a3096c3dccff 145 }
deathernater 0:a3096c3dccff 146 }
deathernater 0:a3096c3dccff 147 oldCarPosX = carScrPosX;
deathernater 0:a3096c3dccff 148 } while (updatePosition() && odo <= 1280);
deathernater 0:a3096c3dccff 149
deathernater 0:a3096c3dccff 150 if (odo >= 1280) {
deathernater 0:a3096c3dccff 151 uLCD.text_string("YOU WON!", 0, 0, FONT_7X8, WHITE);
deathernater 0:a3096c3dccff 152 } else {
deathernater 0:a3096c3dccff 153 uLCD.set_sector_address(0x003B, 0x5641);
deathernater 0:a3096c3dccff 154 uLCD.display_image(0,0);
deathernater 0:a3096c3dccff 155 uLCD.text_string("Crashed:\nGAME OVER", 0, 0, FONT_7X8, WHITE);
deathernater 0:a3096c3dccff 156 }
deathernater 0:a3096c3dccff 157 }