Eduardo Nava / Mbed 2 deprecated MazeRunner_Fall2017-shell

Dependencies:   4DGL-uLCD-SE mbed wave_player

Fork of MazeRunner_Fall2017-shell by ECE 2035 TA

Revision:
1:2c6ae0fe9a2a
Parent:
0:cf4396614a79
--- a/game.cpp	Fri Nov 03 18:48:48 2017 +0000
+++ b/game.cpp	Fri Dec 29 15:32:31 2017 +0000
@@ -3,11 +3,24 @@
 #include "globals.h"
 #include "physics.h"
 #include "wall.h"
+#include "pothole.h"
+#include "goal.h"
+#include "windmill.h"
+#include "token.h"
+#include "sandtrap.h"
+#include "arena.h"
+#include "rewind.h"
 
+#include "saves.h"
+
+
+int tokenUse = 0;
+int score = 0;
 
 /** Erases the ball from the screen by drawing over it with the background color. */
 void erase_ball(Ball* ball)
 {
+    uLCD.filled_circle(ball->x,ball->y,radius,0x000000);
     // TODO: Draw background color over curriously drawn ball location
 }
 
@@ -15,40 +28,103 @@
 void draw_ball(Ball* ball, Physics* state)
 {
     // TODO: Save that updated ball position for later erasing
+    ball->x = state->px;
+    ball->y = state->py;
+    uLCD.filled_circle(ball->x,ball->y,radius,GREEN);
     // TODO: Draw ball in its updated location
 }
 
+//sets all should draw in the arena to should draw
+void set_all_draw(DLinkedList* arena)
+{
+    ArenaElement* elem = (ArenaElement*)getHead(arena);
+    do {
+        switch(elem->type) {
+            case WALL:
+                ((Wall*)elem)->should_draw = 1;
+                break;
+            case POTHOLE:
+                ((Pothole*)elem)->should_draw = 1;
+                break;
+            case SANDTRAP:
+                ((Sandtrap*)elem)->should_draw = 1;
+            default:
+                break;
+        }
+    } while(elem = (ArenaElement*)getNext(arena));
+}
+
+
 /** Reads inputs to the game, such as accelerometer and buttons */
 GameInputs read_inputs()
 {
-    GameInputs inputs = {0};
-
+    GameInputs inputs;
+    double x, y, z;
+    
+    //pretty sure this is making an infinite loop
+    acc.readXYZGravity(&x, &y, &z);
+    
     // TODO: Get acceleration vector from accelerometer
+    inputs.ax = -1*x*1e-3/mass;
+    inputs.ay = y*1e-3/mass;
+    inputs.az = z;
     // TODO: Read buttons
+    left_pb.read();
+    right_pb.read();
+    up_pb.read();
+    down_pb.read();
 
     return inputs;
 }
 
-int update_game(DLinkedList* arena, Physics* curr, GameInputs inputs, float delta)
-{
+int update_game(DLinkedList* arena, Physics* curr, int* tokens, GameInputs inputs, float delta)
+{   
+    int done = 0;
+    int hit = 0;
     ///////////////////////////////
     // Prepare for physics update
     ///////////////////////////////
     // Make a copy of the current state for modification
     Physics next = *curr;
     // No acceleration unless the ArenaElements apply them. (Newton's 1st law)
-    next.ax = next.ay = 0.0;
+    next.ax = (float)inputs.ax;
+    next.ay = (float)inputs.ay;
+
+
 
     // Loop over all arena elements
     ArenaElement* elem = (ArenaElement*)getHead(arena);
     do {
         switch(elem->type) {
             case WALL:
-                do_wall(&next, curr, (Wall*) elem, delta);
+                hit = do_wall(&next, curr, (Wall*) elem, delta);
+                if (hit) {// if the wall is hit, do the wall hit animation which flashes 
+                    //the screen white.
+                    uLCD.background_color(WHITE);
+                    uLCD.cls();
+                    uLCD.background_color(BLACK);
+                    uLCD.cls();
+                    set_all_draw(arena);
+                }
+                break;
+            case POTHOLE:
+                do_pothole(&next, curr, (Pothole*) elem);
+                break;
+            case WINDMILL:
+                do_windmill(&next, curr, (Windmill*) elem, delta);
+                break;
+            case TOKEN:
+                *tokens = *tokens + do_token(&next, curr, (Token*) elem);
+                break;
+            case SANDTRAP:
+                do_sandtrap(&next, curr, (Sandtrap*)elem);
+                break;
+            case GOAL:
+                if (*tokens > 4)
+                    done = do_goal(&next, curr, (Goal*) elem);
                 break;
             case BALL:
                 forward_euler(&next, delta);
-                break;
             default:
                 break;
         }
@@ -58,18 +134,22 @@
     *curr = next;
     
     // Zero means we aren't done yet
-    return 0;
+    if(*tokens < 5){
+        done = 0;
+    }
+    return done;
 }
 
-int run_game(DLinkedList* arena, Physics* state)
+int run_game(DLinkedList* arena, Physics* state, DLinkedList* saves)
 {
     // Initialize game loop timers
-    int tick, phys_tick, draw_tick;
+    int tick, phys_tick, draw_tick, rewind_tick;
     Timer timer;
     timer.start();
     tick = timer.read_ms();
     phys_tick = tick;
     draw_tick = tick;
+    rewind_tick = tick;
 
     // Initialize debug counters
     int count = 0;
@@ -79,29 +159,147 @@
     uLCD.background_color(BLACK);
     uLCD.cls();
 
+    int* tokens = (int*)malloc(sizeof(int));
+    *tokens = 0;
+
+    state->px = 20.0;        // Position in the center of the screen
+    state->py = 20.0;
+    state->vx = 0.0;         // Initially unmoving
+    state->vy = 0.0;
+
+    int rightPress;          //button reader values
+    int leftPress;
+    int upPress;
+    int downPress;
+
+    DLinkedList* oldTail1;
+
+
+    DLinkedList* rewoundLoad;
+
+    
+    DLinkedList* rewindArenas = create_dlinkedlist();
+    
+
+    
+
+    wait(1);
     ///////////////////
     // Main game loop
     ///////////////////
     while(1) {
         // Read timer to determine how long the last loop took
+        
+        ////////
+        //check push buttons
+        //////////
+
+        rightPress = !right_pb;
+        leftPress = !left_pb;
+        upPress = !up_pb;
+        downPress = !down_pb;
+        //need to check if the skip level feature, rewind, jump back, or 
+        //get all tokens has been selected.
+
+
+        if (upPress&&downPress){
+            //skip level
+            return 1;
+        } else if(rightPress) {
+            //get all tokens mode
+            if (tokenUse < 1){
+                tokenUse++;
+                *tokens = 5;
+                myled = 0;
+                ArenaElement* elem = (ArenaElement*)getHead(arena);
+                do {
+                    switch (elem->type) {
+                        case TOKEN:
+                            ((Token*)elem)->should_erase = 1;
+                            draw_token((Token*)elem);
+                            break;
+                        default:
+                            break;
+                    }
+                } while(elem = (ArenaElement*)getNext(arena));
+            }
+        } else if(leftPress){
+            //Jump back
+            //opens the saves menu
+            DLinkedList* newLoad;
+            newLoad = runLoadSaveMenu(saves);
+            if (newLoad == NULL){
+                continue;
+            }
+            DLinkedList* newArena = (DLinkedList*)getTail(newLoad);
+            free(arena);
+            arena = copy_arena(newArena);
+            Physics* newState = (Physics*)getHead(newLoad);
+            free(state);
+            state = copy_physics(newState);
+            destroyList(newLoad);
+            tick = timer.read_ms();
+            phys_tick = tick;
+        } else if (upPress){
+            //Rewind
+            rewoundLoad = runRewind(rewindArenas);
+            if (rewoundLoad == NULL) {
+                continue;
+            }
+            free(arena);
+            arena = rewoundLoad;
+            Ball* newBall = (Ball*)getTail(arena);
+            state->px = newBall->x;
+            state->py = newBall->y;
+            tick = timer.read_ms();
+            phys_tick = tick;
+        } else if (downPress){
+            //save state
+            //need to open a saves menu
+            runStoreSaveMenu(state, arena, saves);
+            tick = timer.read_ms();
+            phys_tick = tick;
+        }
+
+
+
+        
         tick = timer.read_ms();
         
+        //score keeping
+        
+        score++;
+
         ///////////////////
         // Physics Update
         ///////////////////
         // Rate limit: 1 ms
-        if (tick - phys_tick < 1) continue;
+        int diff = tick - phys_tick;
+        if (diff < 1) continue;
         phys_tick = tick;
 
         // Compute elapsed time in milliseconds
-        float delta = (tick-phys_tick)*1e-3;
+        float delta = (diff)*1e-3*(float)gameDiff;
+        
 
         // Read inputs
         GameInputs inputs = read_inputs();
 
         // Update game state
-        int done = update_game(arena, state, inputs, delta);
-        if (done) return done;
+        int done = update_game(arena, state, tokens, inputs, delta);
+        if (done) {
+            *tokens = 0;
+            int limit = getSize(rewindArenas);
+            getHead(rewindArenas);
+            DLinkedList* currArena;
+            for (int i = 0; i < limit; i++) {
+                currArena = (DLinkedList*)getCurrent(rewindArenas);
+                (rewindArenas->current)->data = NULL;
+                destroyList(currArena);
+                removeForward(rewindArenas);
+            }
+            return done;
+        }
 
         // Debug: Count physics updates
         count2++;
@@ -113,6 +311,26 @@
         if(tick - draw_tick < 40) continue;
         draw_tick = tick;
 
+
+
+        /////////////////
+        // Save States for REwind
+        //////////////////
+        if (tick - rewind_tick > 350) {
+            rewind_tick = tick;
+            if (getSize(rewindArenas) > 9) {//only store max of 10 arenas
+                //the tail will be deleted from the stack
+                getTail(rewindArenas);
+                oldTail1 = (DLinkedList*)removeForward(rewindArenas);
+                destroyList(oldTail1);
+            }
+            DLinkedList* arenaCopy = copy_arena(arena);
+            insertHead(rewindArenas,(void*)arenaCopy);
+        }
+
+            
+
+
         // Erase moving stuff
         ArenaElement* elem = (ArenaElement*)getHead(arena);
         do {
@@ -131,6 +349,21 @@
                 case WALL:
                     draw_wall((Wall*) elem);
                     break;
+                case POTHOLE:
+                    draw_pothole((Pothole*)elem);
+                    break;
+                case WINDMILL:
+                    draw_windmill((Windmill*)elem);
+                    break;
+                case TOKEN:
+                    draw_token((Token*)elem);
+                    break;
+                case SANDTRAP:
+                    draw_sandtrap((Sandtrap*)elem);
+                    break;
+                case GOAL:
+                    draw_goal((Goal*)elem);
+                    break;
                 case BALL:
                     draw_ball((Ball*) elem, state);
                     break;
@@ -140,7 +373,7 @@
         } while(elem = (ArenaElement*)getNext(arena));
 
         ///////////////
-        // Debug info
+        // Display score
         ///////////////
         // Displays rate info in the top corner
         //  First number is total time to update and render this frame
@@ -149,10 +382,55 @@
         // TODO: Take this out before you turn your code in!
         if ((count = (count+1)%10) == 0) {
             uLCD.locate(0, 0);
-            uLCD.printf("%d %d \r\n", timer.read_ms()-tick, count2);
+            uLCD.printf("%d \r\n", score);
         }
         
         // Reset physics iteration counter after every render update
         count2 = 0;
     }
+}
+
+
+
+void draw_everything(DLinkedList* arena) {
+    ArenaElement* elem = (ArenaElement*)getHead(arena);
+    do {
+        switch(elem->type) {
+            case BALL:
+                erase_ball((Ball*) elem);
+                break;
+            default: break;
+        }
+    } while(elem = (ArenaElement*)getNext(arena));
+
+    // Draw everything
+    elem = (ArenaElement*)getHead(arena);
+    do {
+        switch(elem->type) {
+            case WALL:
+                draw_wall((Wall*) elem);
+                break;
+            case POTHOLE:
+                draw_pothole((Pothole*)elem);
+                break;
+            case WINDMILL:
+                draw_windmill((Windmill*)elem);
+                break;
+            case TOKEN:
+                draw_token((Token*)elem);
+                break;
+            case SANDTRAP:
+                draw_sandtrap((Sandtrap*)elem);
+                break;
+            case GOAL:
+                draw_goal((Goal*)elem);
+                break;
+            case BALL:
+                Ball* ball = (Ball*)elem;
+                uLCD.filled_circle(ball->x,ball->y,radius,GREEN);
+                break;
+            default:
+                break;
+        }
+    } while(elem = (ArenaElement*)getNext(arena));
 }
\ No newline at end of file