bouncing_ball backend
Fork of bouncing_ball by
Diff: bouncing_ball.cpp
- Revision:
- 2:ba1844b0eb9f
- Parent:
- 1:0aa572c0f2b1
- Child:
- 3:30b5a3adc15f
diff -r 0aa572c0f2b1 -r ba1844b0eb9f bouncing_ball.cpp --- a/bouncing_ball.cpp Tue Oct 24 12:33:39 2017 +0000 +++ b/bouncing_ball.cpp Tue Nov 07 12:07:13 2017 +0000 @@ -1,56 +1,95 @@ #include "mbed.h" #include "bouncing_ball.h" -physics_ball::physics_ball(int color_in, int radius_in) +//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 = color_in; - radius = radius_in; + 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() { } -void physics_ball::define_space(int width, int height) +//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) { - space_width = width; - space_height = height; + _width = desired_width; + _height = desired_height; } -void physics_ball::set_param(int radius_in, int color_in) +//An alternative means of setting desired radius and colored. +void physics_ball::set_param(int desired_radius, int desired_color) { - radius = radius_in; - color = color_in; + radius = desired_radius; + color = desired_color; } -void physics_ball::set_state(int x, int y, float vx, float vy) +//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 = x; - posy = y; - speedx = vx; - speedy = vy; + posx = desired_x; + posy = desired_y; + _posx_f = (float) posx; + _posy_f = (float) posy; + speedx = desired_vx; + speedy = desired_vy; } -void physics_ball::update(float time_step, MMA8452Q accelerometer) +//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; - // Move circle. IMPORTANT! Notice how we adjust for sensor orientation! - posx -= (speedx * accelerometer.readY()); - posy -= (speedy * accelerometer.readX()); + // Make circle bounce off of edges if at the edges: + if (( posx <= radius) || ((posx + radius) >= _width)) { + speedx = -speedx; + } + if (( posy <= radius) || ((posy + radius) >= _height)) { + speedy = -speedy; + } - // Make circle sit on edges - if ( posx <= radius + 1 ) { - posx = radius + 1; - } else if ( posx >= space_width - radius ) { - posx = space_width - radius; + //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; } - if ( posy <= radius + 1 ) { - posy = radius + 1; - } else if ( posy >= space_height - radius ) { - posy = space_height - radius; +} + +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 > 3) { + color = 0; } } \ No newline at end of file