ELEC2645 (2015/16) / Mbed 2 deprecated HarryPetrovicPong

Dependencies:   N5110 mbed

Fork of 2645_Physics_Engine_Example by Craig Evans

Revision:
0:6a561e8d6713
Child:
1:6632d8423c65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Mar 11 09:52:11 2016 +0000
@@ -0,0 +1,135 @@
+#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%
+}
\ No newline at end of file