Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: 4DGL-uLCD-SE mbed wave_player
Fork of MazeRunner_Fall2017-shell by
Diff: game.cpp
- 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
