ECE 2036 Project
Dependencies: mbed wave_player 4DGL-uLCD-SE
Diff: game.cpp
- Revision:
- 2:2042f29de6b7
- Parent:
- 1:c18c231cb299
diff -r c18c231cb299 -r 2042f29de6b7 game.cpp --- a/game.cpp Wed Nov 08 21:01:43 2017 +0000 +++ b/game.cpp Thu Nov 21 16:10:57 2019 +0000 @@ -8,14 +8,64 @@ /** Erases the ball from the screen by drawing over it with the background color. */ void erase_ball(Ball* ball) { - // TODO: Draw background color over curriously drawn ball location + // Draw background color over previously drawn ball location + uLCD.filled_circle(ball->x, ball->y, radius, BLACK); } /** Draws the ball on the screen at the updated location (according to the state) */ void draw_ball(Ball* ball, Physics* state) { - // TODO: Save that updated ball position for later erasing - // TODO: Draw ball in its updated location + // Draw ball in its updated location + uLCD.filled_circle(state->px, state->py, radius, WHITE); + // Save that updated ball position for later erasing + ball->x = state->px; + ball->y = state->py; +} + +/** Draws a hole on the screen */ +void draw_hole(Hole* hole) +{ + if (hole->should_draw) { + // Draw hole in its location + uLCD.filled_circle(hole->x, hole->y, radius - 1, RED); + hole->should_draw = 0; + } +} + +/** Checks whether the ball has hit a hole */ +int do_hole(Hole* hole, Physics* curr) +{ + double dist = sqrt(pow(curr->px - hole->x, 2) + pow(curr->py - hole->y, 2)); + if (dist < radius * 2) { + hole->should_draw = 1; + } + if (dist < radius) { + return 2; + } + return 0; +} + +/** Draws the goal on the screen */ +void draw_goal(Goal* goal) +{ + if (goal->should_draw) { + // Draw goal in its location + uLCD.filled_circle(goal->x, goal->y, radius + 1, GREEN); + goal->should_draw = 0; + } +} + +/** Checks whether the ball has hit the goal */ +int do_goal(Goal* goal, Physics* curr) +{ + double dist = sqrt(pow(curr->px - goal->x, 2) + pow(curr->py - goal->y, 2)); + if (dist < radius * 2) { + goal->should_draw = 1; + } + if (dist < radius) { + return 1; + } + return 0; } /** Reads inputs to the game, such as accelerometer and buttons */ @@ -23,22 +73,65 @@ { GameInputs inputs = {0}; - // TODO: Get acceleration vector from accelerometer - // TODO: Read buttons + // Get acceleration vector from accelerometer + acc.readXYZGravity(&inputs.ax, &inputs.ay, &inputs.az); return inputs; } -int update_game(DLinkedList* arena, Physics* curr, GameInputs inputs, float delta) +int lrpb = left_pb || right_pb; +int lpb = 1; +int upb = up_pb; +int dpb = down_pb; + +int update_game(DLinkedList* arena, Physics* curr, GameInputs inputs, DLinkedList* checkpoints, float delta) { + + // Cheat codes! + if (left_pb == 0 && right_pb == 0 && lrpb == 1) { + lpb = 1; + uLCD.cls(); + uLCD.printf("\n\n\n\n Cheat code!"); + wait(0.5); + return 30; + } + + // Help! + if (left_pb == 1 && lpb == 0) { + lpb = 1; + return 32; + } + + // Save/restore state + if (up_pb == 0 && upb == 1) { + greenLED = 1; + Physics* saveState = (Physics*) malloc(sizeof(Physics)); + *saveState = *curr; + insertTail(checkpoints, saveState); + } + if (down_pb == 0 && dpb == 1) { + Physics* restoreState = (Physics*) getTail(checkpoints); + if (restoreState != NULL) { + *curr = *restoreState; + } + } + + // Save previous inputs + lrpb = left_pb || right_pb; + lpb = left_pb; + upb = up_pb; + dpb = down_pb; + /////////////////////////////// // 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; + // Loop over all arena elements ArenaElement* elem = (ArenaElement*)getHead(arena); do { @@ -47,8 +140,20 @@ do_wall(&next, curr, (Wall*) elem, delta); break; case BALL: + next.ax += inputs.ay * ACCELERATION; + next.ay += inputs.ax * ACCELERATION; forward_euler(&next, delta); break; + case HOLE: + if (do_hole((Hole*) elem, curr)) { + return 31; + } + break; + case GOAL: + if (do_goal((Goal*) elem, curr)) { + return 1; + } + break; default: break; } @@ -56,8 +161,12 @@ // Last thing! Update state, so it will be saved for the next iteration. *curr = next; - + // Zero means we aren't done yet + // 1 means we've hit the goal + // 31 means we've hit a pothole + // 32 means we need help! + // 30 means we used the cheat code return 0; } @@ -75,17 +184,24 @@ int count = 0; int count2 = 0; + // Initialize checkpoint list + DLinkedList* checkpoints = create_dlinkedlist(); + // Initial draw of the game uLCD.background_color(BLACK); uLCD.cls(); + // Save start time + set_time(0); + time_t startTime = time(NULL); + /////////////////// // Main game loop /////////////////// while(1) { // Read timer to determine how long the last loop took tick = timer.read_ms(); - + /////////////////// // Physics Update /////////////////// @@ -101,8 +217,9 @@ 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, inputs, checkpoints, delta); + if (done == 1) return 30 - (time(NULL) - startTime); + if (done != 0) return done; // Debug: Count physics updates count2++; @@ -121,7 +238,8 @@ case BALL: erase_ball((Ball*) elem); break; - default: break; + default: + break; } } while(elem = (ArenaElement*)getNext(arena)); @@ -135,11 +253,20 @@ case BALL: draw_ball((Ball*) elem, state); break; + case HOLE: + draw_hole((Hole*) elem); + break; + case GOAL: + draw_goal((Goal*) elem); + break; default: break; } } while(elem = (ArenaElement*)getNext(arena)); + uLCD.line(0, 0, 127, 0, 0); + uLCD.line(0, 0, (30 - (time(NULL) - startTime)) * (127/30), 0, GREEN); + /////////////// // Debug info /////////////// @@ -148,11 +275,11 @@ // Second number is how many physics iterations between drawing frames // Only displayed every 10th render update (roughly 2.5 Hz) // 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); - } - + //if ((count = (count+1)%10) == 0) { + // uLCD.locate(0, 0); + // uLCD.printf("%d %d \r\n", timer.read_ms()-tick, count2); + //} + // Reset physics iteration counter after every render update count2 = 0; }