Two player imu pong
Dependencies: 4DGL-uLCD-SE IMUfilter LSM9DS0 PinDetect mbed
main.cpp
- Committer:
- rrr93
- Date:
- 2015-10-22
- Revision:
- 0:941225f01ccc
File content as of revision 0:941225f01ccc:
#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; } } }