Two player imu pong
Dependencies: 4DGL-uLCD-SE IMUfilter LSM9DS0 PinDetect mbed
Diff: main.cpp
- Revision:
- 0:941225f01ccc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Oct 22 16:50:22 2015 +0000 @@ -0,0 +1,260 @@ +#include "mbed.h" +#include "PinDetect.h" +#include "uLCD_4DGL.h" +#include "Speaker.h" +#include "paddle.h" +#include "ball.h" +#include "soundBuilder.h" +#include "LSM9DS0.h" + +Serial pc(USBTX, USBRX); +//IMU +// SDO_XM and SDO_G are pulled up, so our addresses are: +#define LSM9DS0_XM_ADDR 0x1D // Would be 0x1E if SDO_XM is LOW +#define LSM9DS0_G_ADDR 0x6B // Would be 0x6A if SDO_G is LOW +LSM9DS0 imu(p9, p10, LSM9DS0_G_ADDR, LSM9DS0_XM_ADDR); +LSM9DS0 imu2(p28,p27, LSM9DS0_G_ADDR, LSM9DS0_XM_ADDR); + +// Pushbuttons +PinDetect pbUp(p15); +PinDetect pbDown(p16); +// uLCD +uLCD_4DGL uLCD(p13, p14, p29); +//Speaker +Speaker mySpeaker(p21); + +// Global variables needed for the push button interrupts + Paddle paddle(40, 3, 118,1); + Paddle paddle2(40,3, 8, 1); + Ball ball(p19, 1.6,1.2,5,50,21); + +// State machine definitions +enum gameStateType {START, WAIT, GAME_SETUP, GAME, LOSE}; +/* State Definitions: + * START -- Creates the start screen + * WAIT -- After the start screen, goes into wait where mbed spins and does nothing + * GAME_SETUP -- Sets up one time things (like boarders, initializes beginning velocity + * GAME -- When the user actually gets to play + * LOSE -- clears the screen, prints you lose, waits, then goes back to start + */ + +// Global state machine variable (So that the pushbuttons can modify it) +gameStateType gameState = START; + +// Pushbutton callbacks +// WARNING: Do not call to draw anything to the uLCD in these +// as this will cause the uLCD to crash sometimes. Update positions +// and draw elsewhere (like it's done here). +// Only modify the logic inside the callback functions. +void pbUp_hit_callback (void) +{ + switch (gameState) + { + case WAIT: + gameState = GAME_SETUP; + break; + case GAME: + paddle.movePaddle(true); + paddle2.movePaddle(true); + break; + } +} + +void pbDown_hit_callback (void) +{ + switch (gameState) + { + case WAIT: + gameState = GAME_SETUP; + break; + case GAME: + paddle.movePaddle(false); + paddle2.movePaddle(false); + break; + } +} + +int main() +{ + + //IMU + uint16_t status = imu.begin(); + //Make sure communication is working + pc.printf("LSM9DS0 WHO_AM_I's returned: 0x%X\n", status); + pc.printf("Should be 0x49D4\n\n"); + + uint16_t status2 = imu2.begin(); + //Make sure communication is working + pc.printf("LSM9DS0 #2 WHO_AM_I's returned: 0x%X\n", status2); + pc.printf("Should be 0x49D4\n\n"); + + + + float IMU_offset = 0.14; //detrmined empirically + + // This is setting up the pushbuttons + // Don't modify this code. + pbUp.mode(PullUp); + pbDown.mode(PullUp); + wait(0.1); + pbUp.attach_deasserted(&pbUp_hit_callback); + pbDown.attach_deasserted(&pbDown_hit_callback); + pbUp.setSampleFrequency(); + pbDown.setSampleFrequency(); + // Don't modify this code. + + uLCD.display_control(PORTRAIT); + uLCD.cls(); + uLCD.baudrate(BAUD_3000000); + uLCD.background_color(BLACK); + + // Initialize all your variables outside the while/switch statement + // to avoid compiler warning/errors + int i = 0; + int random; + + //paddle stuff + int pmoveMin = 25; + int pmoveMax = 70; + int pmove; + + while (1) + { + switch (gameState) + { + case START: + uLCD.cls(); + uLCD.locate(0,0); + uLCD.printf("Pong!!!\n\n"); + uLCD.printf("Press Key to Start"); + gameState = WAIT; + ball.setX(50); + ball.setY(50); + break; + case GAME_SETUP: + uLCD.cls(); + uLCD.line(0, 0, 127, 0, 0xCFB53B); + uLCD.line(127, 0, 127, 127, 0xCFB53B); + uLCD.line(127, 127, 0, 127, 0xCFB53B); + uLCD.line(0, 127, 0, 0, 0xCFB53B); + ball.setBaseVx(2.0); + ball.setBaseVy(2.0); + random = rand() % 1; + ball.setVxSign(-1); ball.setVySign(((float)random - 0.5)*2); + paddle.initDraw(&uLCD); + paddle2.initDraw(&uLCD); + + Note note1(4000.0, 0.7, 0.5); + Note note2(3000.0, 0.3, 0.5); + Note note3(2000.0, 0.3, 0.5); + Note note4(1000.0, 0.7, 0.5); + Note note5(2500.0, 0.3, 0.5); + SoundBuilder sound(&mySpeaker); + sound.addNote(note1); + sound.addNote(note2); + sound.addNote(note3); + sound.addNote(note4); + sound.addNote(note5); + sound.playSong(); + gameState = GAME; + break; + case GAME: + if(ball.CheckHit()) + { + Note note(1000.0, 0.03, 0.5); + SoundBuilder sound(&mySpeaker); + sound.addNote(note); + sound.playSong(); + } + + if (paddle.checkHitY(ball.getFutureX(), ball.getFutureY(), ball.getRadius())) + { + + ball.reverseYDirection(); + } + + if (paddle2.checkHitY(ball.getFutureX(), ball.getFutureY(), ball.getRadius())) + { + + ball.reverseYDirection(); + } + + if (ball.CheckLose()) + {gameState = LOSE;} + if (paddle.checkHitX(ball.getFutureX(), ball.getFutureY(), ball.getRadius(),false)) + { + Note note(4000.0, 0.03, 0.5); + SoundBuilder sound(&mySpeaker); + sound.addNote(note); + sound.playSong(); + + ball.reverseXDirection(); + uLCD.locate(1,1); + } + + if (paddle2.checkHitX(ball.getFutureX(), ball.getFutureY(), ball.getRadius(),true)) + { + Note note(4000.0, 0.03, 0.5); + SoundBuilder sound(&mySpeaker); + sound.addNote(note); + sound.playSong(); + ball.reverseXDirection(); + uLCD.locate(1,1); + } + + + ball.update(&uLCD); + imu.readAccel(); + + imu2.readAccel(); + + if ( imu.ax + IMU_offset > 0.1) + { + paddle.movePaddle(true); + } + else if (imu.ax+ IMU_offset < -0.1) + { + paddle.movePaddle(false); + } + + if ( imu2.ax + IMU_offset > 0.1) + { + paddle2.movePaddle(true); + } + else if (imu2.ax+ IMU_offset < -0.1) + { + paddle2.movePaddle(false); + } + + // We can assume that these for loops are quick enough that the paddle will move only one interval. + // These movements of the paddle have been optimized. Feel free to draw it out to see how it's been done. + paddle.redraw(&uLCD); + paddle2.redraw(&uLCD); + break; + case LOSE: + uLCD.cls(); + uLCD.printf("YOU LOSE D:"); + Note note6(3000.0, 0.7, 0.5); + Note note7(2000.0, 0.3, 0.5); + Note note8(1000.0, 0.3, 0.5); + Note note9(2300.0, 0.7, 0.5); + Note note10(2500.0, 0.3, 0.5); + SoundBuilder sound2(&mySpeaker); + sound2.addNote(note6); + sound2.addNote(note7); + sound2.addNote(note8); + sound2.addNote(note9); + sound2.addNote(note10); + sound2.playSong(); + paddle.resetScore(); + paddle2.resetScore(); + wait(5.0); + gameState = START; + break; + case WAIT: + // Used to seed the rand() function so we don't get the same starting position every time. + i++; + break; + } + } +} \ No newline at end of file