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.
Fork of 2645_Physics_Engine_Example by
main.cpp
- Committer:
- eencae
- Date:
- 2016-03-11
- Revision:
- 0:6a561e8d6713
- Child:
- 1:6632d8423c65
File content as of revision 0:6a561e8d6713:
#include "mbed.h" #include "N5110.h" #define BALLRADIUS 2 // VCC, SCE, RST, D/C, MOSI, SCLK, LED N5110 lcd (PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3); // Can also power (VCC) directly from VOUT (3.3 V) - // Can give better performance due to current limitation from GPIO pin Ticker game_timer; // struct used to store 2D vectors typedef struct vector_t vector_t; struct vector_t { float x; float y; }; // function prototypes void init_display(); void init_ball(); void game_timer_isr(); void redraw_screen(); void update_physics_engine(); void check_collisions(); vector_t pos; // ball position vector_t vel; // ball velocity vector_t acc; // ball acceleration float refresh_rate = 10.0; // how often to update display (Hz) float g_dt = 1.0F/refresh_rate; // global to store time step (F makes it a float, gets rid of compiler warning) volatile int g_timer_flag = 0; int main() { wait(2.0); // short delay for power to settle init_display(); // first need to initialise display init_ball(); // setup ticker game_timer.attach(&game_timer_isr,g_dt); redraw_screen(); // draw initial screen while(1) { if ( g_timer_flag ) { // ticker interrupt g_timer_flag = 0; // clear flag update_physics_engine(); check_collisions(); redraw_screen(); } sleep(); // sleep until next interrupt } } void redraw_screen() { lcd.clear(); lcd.drawCircle(pos.x,pos.y,BALLRADIUS,1); // x,y,radius,black fill lcd.refresh(); // update display } void check_collisions() { // see if ball has hit the floor (subtract the radius since the position is the centre of the ball) if ( pos.y >= 47 - BALLRADIUS ) { pos.y = 47 - BALLRADIUS; // need to force this or else ball can end up going 'underground' vel.y = -0.89 * vel.y; // y velocity is reflected and dampened // y accleration is still gravity } // has ball gone off the right-hand side? if ( pos.x >= 83 - BALLRADIUS ) { pos.x = 83 - BALLRADIUS; // need to force this or else ball can end up going off screen vel.x = -0.5 * vel.x; // reflect and damp velocity acc.x = -acc.x; // reflect accleration } // what about the left? if ( pos.x <= BALLRADIUS ) { pos.x = BALLRADIUS; // need to force this or else ball can end up going off screen vel.x = -0.5 * vel.x; // reflect and damp velocity acc.x = -acc.x; // reflect accleration } } void update_physics_engine() { // from Newton's Laws acc.x = 0.9F*acc.x; // reduce a little due to air friction // calc new velocity (assume 'unit' time) vel.x = vel.x + acc.x; // * g_gt; vel.y = vel.y + acc.y; // * g_gt; // calc new position (assume 'unit' time) pos.x = pos.x + vel.x;// * g_gt; pos.y = pos.y + vel.y;// * g_dt; // should really multiply the above by the time-step, // but since the pixel can only be a integer value, // it makes the motion a little 'jumpy'. } void init_ball() { // initial position (top-left) pos.x = BALLRADIUS; pos.y = BALLRADIUS; // initial velocity - still vel.x = 0.0; vel.y = 0.0; // initial acceleration - gravity and a bit of push to right acc.x = 0.5; acc.y = 2.0; // +ve so ball accelerates to bottom of display (top of screen is y=0, bottom is y=47) // should be 9.8, but can play with value to get a 'nice' ball movement } void game_timer_isr() { g_timer_flag = 1; } void init_display() { lcd.init(); lcd.normalMode(); // normal colour mode lcd.setBrightness(0.5); // put LED backlight on 50% }