The present code implements a single player squash game, using joystick to move paddle right or left. And checks the current temperature inside the device.

Dependencies:   2645_I2C_TMP102 2645_Physics_Engine_Example Paddle mbed

main.cpp

Committer:
bonnyngangu
Date:
2016-05-08
Revision:
1:fe4ac8f10309
Parent:
0:61128d697217
Child:
2:c1b442f26087

File content as of revision 1:fe4ac8f10309:

#include "mbed.h"
#include "N5110.h"
#include "game.h"
#include "SDFileSystem.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

InterruptIn interrupt_button(PTB18); // interrupting the sleep mode.
PwmOut buzzer(PTA2); // buzzer connection to PwmOut.

// connections for joystick
DigitalIn button(PTB10);
AnalogIn xPot(PTB2);
AnalogIn yPot(PTB3);

// Connections to SD card holder on K64F (SPI interface)
SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCK, CS

void delete_file(char filename[]);

// function prototypes
void init_ball();
void game_timer_isr();
void BallMove();
void redraw_screen();
void update_physics_engine();
void check_collisions();
void Squash_Court();
void getPaddle();
void PaddleMove();
void updateJoystick();
void drawCircle(int x0,int y0,int radius,int fill);


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

vector_t pos;  // ball position
vector_t vel;  // ball velocity
vector_t acc;  // ball acceleration

float refresh_rate = 25.0;  // how often to update display (Hz)
float g_dt = 2.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 scoring = 0;// setting the value of starting score.
int m = 42;

int main()
{
     
    wait(1.0);  // short delay for power settling
    lcd.init(); // initialising the display
    
    // creating introduction screen  
    lcd.printString(" SQUASH!",15,2);
        lcd.inverseMode(); // invert colours
        lcd.drawLine(41,0,0,23,1);
        lcd.drawLine(41,0,83,23,1);
        lcd.drawLine(0,23,41,47,1);
        lcd.drawLine(83,23,41,47,1);
        lcd.refresh(); 
        wait(5.0);
        lcd.clear();
        
        lcd.printString("Game starting",5,2);
        lcd.normalMode();      // normal colour mode
        lcd.setBrightness(0.5); // put LED backlight on 50%
        
        buzzer.period_ms(1.5);
        buzzer.pulsewidth_ms(1.9);
        getPaddle();
        wait(3.0);
            
    init_ball();
    
    // setup ticker
    game_timer.attach(&game_timer_isr,g_dt);

    redraw_screen();  // draw initial screen
            
    while (1) {
                      
        Squash_Court(); // draw squash court
        
        // setting the joystick control.
        if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
        joystick.direction = CENTRE;
        int m = 42;
        lcd.drawLine(m-6,45,m+6,45,1);
        lcd.refresh();
        wait(0.05);
        lcd.clear();        
        } 
        
        else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
        joystick.direction = LEFT;
        int m = 18;
        lcd.drawLine(m-6,45,m+6,45,1); 
        lcd.refresh();
        wait(0.05);
        lcd.clear();     
        }
        
        else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
        joystick.direction = RIGHT;
        int m = 66;
        lcd.drawLine(m-6,45,m+6,45,1);
        //m-=1;// moving a pixel a time. 
        lcd.refresh();
        wait(0.05);
        lcd.clear();     
        }
        
        BallMove();
    }
}

void getPaddle() // setting paddle moving
{   
    int m = 42 ; // set paddle into origin 42 on X axis.
    
    // draw a circle x,y,radius,black fill
    lcd.drawCircle(42,40,2,1);
      
    // drawing the paddle.
    lcd.drawLine(m-6,45,m+6,45,1);
    lcd.refresh();
}

void Squash_Court()
{
          
    lcd.drawRect(0,0,83,47,0);    // transparent, just outline
    lcd.refresh();   // need to refresh screen after drawing rects
                         
    for (int i = 0; i < 84; i++) {
    
    lcd.setPixel(i,24);// at y = 24 pixels (centre)
    }
            
    for (int i = 0; i < 84; i++) {
    
    lcd.setPixel(i,16);// // at y = 14 pixels 
    }
            
    // need to refresh display after setting pixels
    lcd.refresh();
    
}

void BallMove()
{
      if ( g_timer_flag ) {  // ticker interrupt
          g_timer_flag = 0;  // clear flag
            update_physics_engine();
            check_collisions();
            redraw_screen();
        }
}

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 = -1.0 * vel.y;  // y velocity is reflected and dampened 
        // y accleration is still gravity
    }
   
    else if ( pos.y >= 45 - BALLRADIUS) {
        pos.y = 45 - BALLRADIUS;  // need to force this or else ball can end up going 'underground'
        vel.y = -4.0 * 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 = -1.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 = 1.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 calibrateJoystick()
{
    button.mode(PullDown);
    // must not move during calibration
    joystick.x0 = xPot;  // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly)
    joystick.y0 = yPot;
}
void updateJoystick()
{
    // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred)
    joystick.x = xPot - joystick.x0;
    joystick.y = yPot - joystick.y0;
    // read button state
    joystick.buttonjoystick = button;

    // calculate direction depending on x,y values
    // tolerance allows a little lee-way in case joystick not exactly in the stated direction
    if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
        joystick.direction = CENTRE;
    } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
        joystick.direction = UP;
    } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) {
        joystick.direction = DOWN;
    } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
        joystick.direction = RIGHT;
    } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) {
        joystick.direction = LEFT;
    } else {
        joystick.direction = UNKNOWN;
    }

    // set flag for printing
    printFlag = 1;
}

void game_timer_isr()
{
    g_timer_flag = 1;
}