Fork of bouncing_ball by Stephen Licht

bouncing_ball.cpp

Committer:
rsean10
Date:
2017-11-15
Revision:
6:1e5cd98fc2aa
Parent:
5:dd8df17df666

File content as of revision 6:1e5cd98fc2aa:

#include "mbed.h"
#include "bouncing_ball.h"

//Constructor.  Default values are set in the library header for all member variables.
physics_ball::physics_ball()
{
    // Set all values to defaults defined above (avoids magic numbers)!
    speedx = DEFAULT_SPEEDX;
    speedy = DEFAULT_SPEEDY;
    posx = DEFAULT_POSX;
    posy = DEFAULT_POSY;
    color = DEFAULT_COLOR;
    radius = DEFAULT_RADIUS;
    _width = DEFAULT_WIDTH;
    _height = DEFAULT_HEIGHT;
    _posy_f = (float) posx;
    _posx_f = (float) posy;
}

//Deconstructor exists, but does nothing.
physics_ball::~physics_ball()
{
}

//Provides the ability to reset the size of the space that the ball is bouncing in.
//Width and height do noy have to be the same size as the LCD screen.
void physics_ball::define_space(int desired_width, int desired_height)
{
    _width = desired_width;
    _height = desired_height;
}

//An alternative means of setting desired radius and colored.
void physics_ball::set_param(int desired_radius, int desired_color)
{
    radius = desired_radius;
    color = desired_color;
}

//An alternative means of setting desired positions and velocities.
void physics_ball::set_state(int desired_x, int desired_y, float desired_vx, float desired_vy)
{
    posx = desired_x;
    posy = desired_y;
    _posx_f = (float) posx;
    _posy_f = (float) posy;
    speedx = desired_vx;
    speedy = desired_vy;
}

//The heart of the matter: the calculation used to update the position of a ball
//using inputs from an accelerometer.
void physics_ball::update(float time_step, MMA8452Q& accelerometer)
{
    //If upside down, hold ball still.
    if (accelerometer.readZ() < 0) {
        if (_upside_down_status == 0) {
            _reset_upside_down();
            _upside_down_status = 1;
        }
    } else {
        _upside_down_status = 0;

        // Make circle bounce off of edges if at the edges:
        if (posx <= radius) {
            posx = radius + BUFFER;
            speedx = -speedx;
            }
        if ((posx + radius) >= _width) {
            posx = _width - radius - BUFFER;
            speedx = -speedx;
            }
        if (posy <= radius) {
            posy = radius + BUFFER;
            speedy = -speedy;
            }
        if ((posy + radius) >= _height){
            posy = _height - radius - BUFFER;
            speedy = -speedy;
            }

        //Accelerate per actual real world physics:
        speedx -= GRAVITY * accelerometer.readY(); //* time_step;
        speedy -= GRAVITY * accelerometer.readX(); //* time_step;

        //Position update depends on speed:
        _posx_f = _posx_f + speedx * time_step;
        _posy_f = _posy_f + speedy * time_step;
        
        //Actual position has to be able to update in less than integer increments.
        //Report out position is expected in integers, however.
        posx = (int) _posx_f;
        posy = (int) _posy_f;
    }
}

void physics_ball::_reset_upside_down()
{
    //Increment color when the accelerometer turned upside down.
    //It's up to the main code to interpret the color.
    color += 1;
    if (color > 2) {
        color = 0;
    }
}