ECE 2036 Project

Dependencies:   mbed wave_player 4DGL-uLCD-SE

game.cpp

Committer:
rconnorlawson
Date:
2017-11-08
Revision:
1:c18c231cb299
Parent:
0:cf4396614a79
Child:
2:2042f29de6b7

File content as of revision 1:c18c231cb299:

#include "game.h"

#include "globals.h"
#include "physics.h"
#include "wall.h"


/** 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
}

/** 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
}

/** Reads inputs to the game, such as accelerometer and buttons */
GameInputs read_inputs()
{
    GameInputs inputs = {0};

    // TODO: Get acceleration vector from accelerometer
    // TODO: Read buttons

    return inputs;
}

int update_game(DLinkedList* arena, Physics* curr, GameInputs inputs, float delta)
{
    ///////////////////////////////
    // 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 {
        switch(elem->type) {
            case WALL:
                do_wall(&next, curr, (Wall*) elem, delta);
                break;
            case BALL:
                forward_euler(&next, delta);
                break;
            default:
                break;
        }
    } while(elem = (ArenaElement*)getNext(arena));

    // Last thing! Update state, so it will be saved for the next iteration.
    *curr = next;
    
    // Zero means we aren't done yet
    return 0;
}

int run_game(DLinkedList* arena, Physics* state)
{
    // Initialize game loop timers
    int tick, phys_tick, draw_tick;
    Timer timer;
    timer.start();
    tick = timer.read_ms();
    phys_tick = tick;
    draw_tick = tick;

    // Initialize debug counters
    int count = 0;
    int count2 = 0;

    // Initial draw of the game
    uLCD.background_color(BLACK);
    uLCD.cls();

    ///////////////////
    // Main game loop
    ///////////////////
    while(1) {
        // Read timer to determine how long the last loop took
        tick = timer.read_ms();
        
        ///////////////////
        // Physics Update
        ///////////////////
        // Rate limit: 1 ms
        int diff = tick - phys_tick;
        if (diff < 1) continue;
        phys_tick = tick;

        // Compute elapsed time in milliseconds
        float delta = diff*1e-3;

        // Read inputs
        GameInputs inputs = read_inputs();

        // Update game state
        int done = update_game(arena, state, inputs, delta);
        if (done) return done;

        // Debug: Count physics updates
        count2++;

        //////////////////
        // Render update
        //////////////////
        // Rate limit: 40ms
        if(tick - draw_tick < 40) continue;
        draw_tick = tick;

        // Erase moving stuff
        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 BALL:
                    draw_ball((Ball*) elem, state);
                    break;
                default:
                    break;
            }
        } while(elem = (ArenaElement*)getNext(arena));

        ///////////////
        // Debug info
        ///////////////
        // Displays rate info in the top corner
        //  First number is total time to update and render this frame
        //  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);
        }
        
        // Reset physics iteration counter after every render update
        count2 = 0;
    }
}