ECE 4180 Lab 4 Racing Game

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

Revision:
0:a3096c3dccff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Mar 16 01:27:09 2017 +0000
@@ -0,0 +1,157 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "SDFileSystem.h"
+#include "wave_player.h"
+#include "uLCD_4DGL.h"
+
+#define PI 3.14159
+
+//Serial Debug
+Serial pc(USBTX, USBRX);
+
+//Joystick
+AnalogIn jsy(p16);
+AnalogIn jsx(p15);
+
+//SD Card
+SDFileSystem sd(p5, p6, p7, p8, "sd");
+
+//LCD Display
+uLCD_4DGL uLCD(p13, p14, p30); // serial tx, serial rx, reset pin
+
+//Analog Out Jack
+AnalogOut DACout(p18);
+//On Board Speaker
+PwmOut PWMout(p26);
+
+//Audio Player
+wave_player player(&DACout, &PWMout);
+
+//Threads
+Thread audioThread, thread2, thread3, gameDisplayThread;
+ 
+//Game Data
+float inputLR, inputSpeed;
+int carScrPosX = 63, carScrPosY = 120;
+int carVel = 0, odo = 0;
+bool redraw = true;
+int wallY1 = 6, wallY2 = 36, wallY3 = 68, wallThickness = 8;
+int wallsStart[3], wallsEnd[3], wallsY[3] = {wallY1, wallY2, wallY3};
+
+void generateWall(int wall) {
+    float wallSeed1 = (float) rand() / RAND_MAX * 63;
+    float wallSeed2 = (float) rand() / RAND_MAX * 63;
+    int wallStart = (int) (wallSeed1 + 0.5);
+    int wallEnd = (int) (wallSeed2 + 0.5);    
+    wallsStart[wall] = wallStart;
+    wallsEnd[wall] = wallEnd + wallStart;
+    if ((wallsEnd[wall] - wallsStart[wall]) > 110) {
+        generateWall(wall);    
+    } 
+}
+
+bool updatePosition() {
+    if (jsy > 0.7 && carVel < 8) {
+        carVel += 1;
+    } else if (jsy < 0.3 && carVel > 0) {
+        carVel -= 1;
+    }
+    if (jsx > 0.55 && (carScrPosX - 4) >= 0) {
+        int delta = (int) (jsx / 0.95 * 8 +  0.5);
+        if (((carScrPosX - 4) - delta) >= 0) {
+            carScrPosX -= delta;
+        }
+    } else if (jsx < 0.45 && (carScrPosX + 4) <= 127) {
+        int delta = (int) ((1 - jsx) / 0.95 * 8 +  0.5);
+        if (((carScrPosX + 4) + delta) <= 127) {
+            carScrPosX += delta;
+        }
+    }
+    odo += carVel;
+    wallsY[0] += carVel;
+    wallsY[1] += carVel;
+    wallsY[2] += carVel;
+    //Check collision
+    for (int i = 0; i < 3; i++) {
+        if (wallsY[i] > 127) {
+            wallsY[i] = 0;
+            generateWall(i);
+            uLCD.cls();
+            redraw = true;
+        }
+        if ((carScrPosX - 4) > wallsEnd[i] || (carScrPosX + 4) < wallsStart[i] 
+            || (carScrPosY - 5) > (wallsY[i] + wallThickness) 
+            || (carScrPosY + 5) < wallsY[i]) {
+            //pc.printf("No Collision\n");    
+            Thread::wait(33);
+        } else {
+            //pc.printf("Crash\n");    
+            return false;
+        }
+    }
+    return true;      
+} 
+ 
+void playSound() {
+    //setup PWM hardware for a Class D style audio output
+    PWMout.period(1.0/400000.0);
+    while (true) {
+        FILE *fp = fopen("/sd/Skrillex_Diplo.wav", "r");
+        if(fp == NULL) {
+            error("Could not open file for read\n");
+        }
+        player.play(fp);
+        fclose(fp);
+        Thread::wait(500);
+    }
+    
+}
+
+int main() {
+    audioThread.start(playSound);
+    uLCD.baudrate(3000000); //jack up baud rate to max for fast display    
+    uLCD.media_init();
+    uLCD.set_sector_address(0x003B, 0x5600);
+    uLCD.display_image(0,0);
+    uLCD.printf("Welcome to Random\nHorizons 3\nThrottle Up!\n(Push Forward)");
+    generateWall(0);
+    generateWall(1);
+    generateWall(2);
+    int oldCarPosX = carScrPosX;
+    int oldWallsY[3] = {wallY1, wallY2, wallY3};
+    while (jsy < 0.95) Thread::wait(33);
+    uLCD.cls();
+    uLCD.printf("Controls:\nUp (Accel.)\nDown (Brake)\nLeft (Left)\n");
+    uLCD.printf("Right (Right)\nDodge the Walls!!\n");
+    Thread::wait(5000);
+    uLCD.cls();
+    do {
+        if (oldCarPosX != carScrPosX || redraw) {
+            uLCD.filled_rectangle(oldCarPosX - 4, carScrPosY - 5, 
+                oldCarPosX + 4, carScrPosY + 5, BLACK);
+            uLCD.filled_rectangle(carScrPosX - 4, carScrPosY - 5, 
+                carScrPosX + 4, carScrPosY + 5, BLUE);
+            uLCD.filled_rectangle(carScrPosX - 1, carScrPosY - 3, 
+                carScrPosX + 2, carScrPosY + 3, WHITE);
+            redraw = false;
+        }
+        for (int i = 0; i < 3; i++) {
+            if (oldWallsY[i] != wallsY[i]) {
+                uLCD.filled_rectangle(wallsStart[i], oldWallsY[i], 
+                    wallsEnd[i], oldWallsY[i] + wallThickness, BLACK);
+                uLCD.filled_rectangle(wallsStart[i], wallsY[i], 
+                    wallsEnd[i], wallsY[i] + wallThickness, RED);
+                oldWallsY[i] = wallsY[i];
+            }
+        }
+        oldCarPosX = carScrPosX;
+    } while (updatePosition() && odo <= 1280);
+    
+    if (odo >= 1280) {
+        uLCD.text_string("YOU WON!", 0, 0, FONT_7X8, WHITE);
+    } else {
+        uLCD.set_sector_address(0x003B, 0x5641);
+        uLCD.display_image(0,0);
+        uLCD.text_string("Crashed:\nGAME OVER", 0, 0, FONT_7X8, WHITE);
+    }
+}
\ No newline at end of file