This is a remake of tetris game for mbed. Please see detail here http://developer.mbed.org/users/sucrelv/notebook/tetris-game-on-mbed
Dependencies: 4DGL-uLCD-SE PinDetect SDFileSystem mbed-rtos mbed wave_player
Diff: main.cpp
- Revision:
- 0:3b5e97ab5884
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Oct 21 15:10:36 2014 +0000 @@ -0,0 +1,480 @@ +#include "mbed.h" +#include "Game.h" +#include "PinDetect.h" +#include "Speaker.h" +#include "TextLCD.h" +#include "Shiftbrite.h" +#include "SDFileSystem.h" +#include "wave_player.h" +#include "rtos.h" + +uLCD_4DGL uLCD(p28, p27, p29); +TextLCD textLCD(p26, p25, p24, p23, p22, p15); +Speaker mySpeaker(p21); +Shiftbrite myShiftbrite(p9, p10, p11, p12, p13); +SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card +Serial pc(USBTX, USBRX); + +PinDetect LEFT_KEY(p16); +PinDetect RIGHT_KEY(p19); +PinDetect ROTATE_KEY(p17); +PinDetect DOWN_KEY(p30); + +int SinglePiecePoints = 50; +int LineClearPoints = 200; +int key_input = 0; +bool gameStarted = false; +void input_left() +{ + if(!gameStarted) + { gameStarted=true; + return; + } + key_input = 1; + mySpeaker.PlayNote(400.0,0.05,0.025); + mySpeaker.PlayNote(500.0,0.05,0.025); +} + +void input_right() +{ + if(!gameStarted) + { gameStarted=true; + return; + } + key_input = 2; + mySpeaker.PlayNote(400.0,0.05,0.025); + mySpeaker.PlayNote(500.0,0.05,0.025); +} + +void input_rotate() +{ + if(!gameStarted) + { gameStarted=true; + return; + } + key_input = 3; + mySpeaker.PlayNote(600.0,0.05,0.025); + mySpeaker.PlayNote(700.0,0.05,0.025); + mySpeaker.PlayNote(800.0,0.05,0.025); + mySpeaker.PlayNote(900.0,0.05,0.025); +} + +void input_down() +{ + if(!gameStarted) + { gameStarted=true; + return; + } + key_input=4; + mySpeaker.PlayNote(500.0,0.05,0.025); + mySpeaker.PlayNote(1500.0,0.05,0.025); + mySpeaker.PlayNote(500.0,0.05,0.025); + mySpeaker.PlayNote(1500.0,0.05,0.025); +} + +void clear_board() +{ + uLCD.filled_rectangle(20,0,79,128,0); +} + +void clear_next_piece() +{ + uLCD.filled_rectangle(92,20,122,50,0); +} + +void UpdateGameStatus(int points,int lines) +{ + textLCD.locate(7,0); + textLCD.printf("%d",points); + textLCD.locate(13,1); + textLCD.printf("%d",lines); +} + +void FlashLight(void const *args) +{ + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,0,0); + + myShiftbrite.RGB(0,0,42); + myShiftbrite.RGB(0,0,42); + Thread::wait(100); + + + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,42,0); + Thread::wait(100); + + myShiftbrite.RGB(0,0,42); + myShiftbrite.RGB(0,0,42); + Thread::wait(100); + + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,0,0); +} + +void GameOverLight(void const *args) +{ + + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,0,0); + + myShiftbrite.RGB(0,0,200); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,200); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,200); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,200); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,200); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,200); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,200); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,200); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,200); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,200); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); +} + +void GameStartLight(void const *args) +{ + + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,0,0); + + myShiftbrite.RGB(0,200,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,200,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,200,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,200,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,0,0); + Thread::wait(100); + myShiftbrite.RGB(0,200,0); + Thread::wait(100); + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,0,0); + +} + +void PlayStartSound() +{ + mySpeaker.PlayNote(500.0,0.05,0.025); + mySpeaker.PlayNote(600.0,0.05,0.025); + mySpeaker.PlayNote(700.0,0.05,0.025); + mySpeaker.PlayNote(800.0,0.05,0.025); + mySpeaker.PlayNote(900.0,0.05,0.025); + mySpeaker.PlayNote(1000.0,0.05,0.025); + mySpeaker.PlayNote(1100.0,0.05,0.025); + mySpeaker.PlayNote(1200.0,0.05,0.025); + mySpeaker.PlayNote(600.0,0.05,0.025); + mySpeaker.PlayNote(700.0,0.05,0.025); + mySpeaker.PlayNote(800.0,0.05,0.025); + mySpeaker.PlayNote(900.0,0.05,0.025); + mySpeaker.PlayNote(1000.0,0.05,0.025); + mySpeaker.PlayNote(1100.0,0.05,0.025); + mySpeaker.PlayNote(1200.0,0.05,0.025); + mySpeaker.PlayNote(1300.0,0.05,0.025); + mySpeaker.PlayNote(700.0,0.05,0.025); + mySpeaker.PlayNote(800.0,0.05,0.025); + mySpeaker.PlayNote(900.0,0.05,0.025); + mySpeaker.PlayNote(1000.0,0.05,0.025); + mySpeaker.PlayNote(1100.0,0.05,0.025); + mySpeaker.PlayNote(1200.0,0.05,0.025); + mySpeaker.PlayNote(1300.0,0.05,0.025); + mySpeaker.PlayNote(1400.0,0.05,0.025); +} + +void PlayOverSound() +{ + mySpeaker.PlayNote(1400.0,0.05,0.025); + mySpeaker.PlayNote(1300.0,0.05,0.025); + mySpeaker.PlayNote(1200.0,0.05,0.025); + mySpeaker.PlayNote(1100.0,0.05,0.025); + mySpeaker.PlayNote(1000.0,0.05,0.025); + mySpeaker.PlayNote(900.0,0.05,0.025); + mySpeaker.PlayNote(800.0,0.05,0.025); + mySpeaker.PlayNote(700.0,0.05,0.025); + mySpeaker.PlayNote(1300.0,0.05,0.025); + mySpeaker.PlayNote(1200.0,0.05,0.025); + mySpeaker.PlayNote(1100.0,0.05,0.025); + mySpeaker.PlayNote(1000.0,0.05,0.025); + mySpeaker.PlayNote(900.0,0.05,0.025); + mySpeaker.PlayNote(800.0,0.05,0.025); + mySpeaker.PlayNote(700.0,0.05,0.025); + mySpeaker.PlayNote(600.0,0.05,0.025); + mySpeaker.PlayNote(1200.0,0.05,0.025); + mySpeaker.PlayNote(1100.0,0.05,0.025); + mySpeaker.PlayNote(1000.0,0.05,0.025); + mySpeaker.PlayNote(900.0,0.05,0.025); + mySpeaker.PlayNote(800.0,0.05,0.025); + mySpeaker.PlayNote(700.0,0.05,0.025); + mySpeaker.PlayNote(600.0,0.05,0.025); + mySpeaker.PlayNote(500.0,0.05,0.025); +} + +void PlayClearSound() +{ + mySpeaker.PlayNote(900.0,0.2,0.025); + mySpeaker.PlayNote(1000.0,0.2,0.025); + mySpeaker.PlayNote(1100.0,0.2,0.025); + mySpeaker.PlayNote(1000.0,0.2,0.025); + mySpeaker.PlayNote(9000.0,0.2,0.025); +} + +int RandomGen(char range) +{ + pc.printf("%c",range); + while(!pc.readable()) wait(0.5); + char buffer[4]; + pc.gets(buffer,4); + int i = buffer[0]-'0'; + return i; +} + +int main() +{ + //hardware setup + LEFT_KEY.mode(PullUp); + RIGHT_KEY.mode(PullUp); + ROTATE_KEY.mode(PullUp); + DOWN_KEY.mode(PullUp); + + LEFT_KEY.attach_deasserted(&input_left); + RIGHT_KEY.attach_deasserted(&input_right); + ROTATE_KEY.attach_deasserted(&input_rotate); + DOWN_KEY.attach_deasserted(&input_down); + + LEFT_KEY.setSampleFrequency(); + RIGHT_KEY.setSampleFrequency(); + ROTATE_KEY.setSampleFrequency(); + DOWN_KEY.setSampleFrequency(); + uLCD.baudrate(3000000); + + myShiftbrite.RGB(0,0,0); + myShiftbrite.RGB(0,0,0); + + sd.disk_initialize(); + uLCD.media_init(); + uLCD.set_sector_address(0x001D, 0x7801); + uLCD.display_image(0,0); + + textLCD.cls(); + textLCD.locate(0,0); + textLCD.printf("Waiting for PC..."); + pc.baud(9600); + pc.format(8,SerialBase::None,1); + pc.printf("0"); + while(!pc.readable()) wait(0.5); + char buffer[4]; + pc.gets(buffer,4); + + //wait for game start + textLCD.cls(); + textLCD.locate(0,0); + textLCD.printf("TETRIS READY!!"); + textLCD.locate(0,1); + textLCD.printf("PRESS ANY KEY..."); + while(!gameStarted) wait(0.5); + PlayStartSound(); + textLCD.cls(); + textLCD.printf("Starting game now..."); + wait(2); + textLCD.cls(); + textLCD.locate(0,0); + textLCD.printf("Points"); + textLCD.locate(0,1); + textLCD.printf("Cleared Line"); + Thread t1(GameStartLight); + //game classes init + bool isGameOver = false; + int mScreenHeight = 128; + Pieces mPieces; + Board mBoard (&mPieces, mScreenHeight); + int a = RandomGen('a'); + int b = RandomGen('b'); + int c = RandomGen('a'); + int d = RandomGen('b'); + Game mGame (&mBoard, &mPieces, mScreenHeight, &uLCD,a,b,c,d); + + + // ----- Main Loop ----- + int prevX=0; + int prevY=0; + int prevPiece=-1; + int prevRot=0; + Timer timer; + timer.start(); + key_input=0; + bool needErase = false; + uLCD.cls(); + while (1) + { + if(isGameOver) + { + wait(1); + continue; + } + // ----- Draw ---- + if(needErase) + { + mGame.ErasePiece(prevX,prevY,prevPiece,prevRot); + needErase=false; + } + mGame.DrawScene(); + + prevX=mGame.mPosX; + prevY=mGame.mPosY; + prevPiece=mGame.mPiece; + prevRot=mGame.mRotation; + + // ----- Input ----- + switch (key_input) + { + case (2): //right + { + if (mBoard.IsPossibleMovement (mGame.mPosX + 1, mGame.mPosY, mGame.mPiece, mGame.mRotation)) + {mGame.mPosX++;needErase=true;} + break; + } + + case (1): //left + { + if (mBoard.IsPossibleMovement (mGame.mPosX - 1, mGame.mPosY, mGame.mPiece, mGame.mRotation)) + {mGame.mPosX--;needErase=true;} + break; + } + + case (4)://down + { + // Check collision from up to down + while (mBoard.IsPossibleMovement(mGame.mPosX, mGame.mPosY, mGame.mPiece, mGame.mRotation)) { mGame.mPosY++; } + needErase=true; + mBoard.StorePiece (mGame.mPosX, mGame.mPosY - 1, mGame.mPiece, mGame.mRotation); + mGame.AddPoints(SinglePiecePoints); + int linesDeleted = mBoard.DeletePossibleLines (); + if(linesDeleted>0) + { + mGame.AddClearedLines(linesDeleted); + mGame.AddPoints(LineClearPoints*linesDeleted); + Thread t1(FlashLight); + PlayClearSound(); + clear_board(); + } + UpdateGameStatus(mGame.GetPoints(),mGame.GetClearedLines()); + + if (mBoard.IsGameOver()) + { + isGameOver=true; + uLCD.cls(); + uLCD.media_init(); + uLCD.set_sector_address(0x001D, 0x7842); + uLCD.display_image(0,0); + Thread t2(GameOverLight); + PlayOverSound(); + + } + + if(!isGameOver) + { + mGame.CreateNewPiece(RandomGen('a'),RandomGen('b')); + clear_next_piece(); + } + break; + } + + case (3)://rotate + { + if (mBoard.IsPossibleMovement (mGame.mPosX, mGame.mPosY, mGame.mPiece, (mGame.mRotation + 1) % 4)) + {mGame.mRotation = (mGame.mRotation + 1) % 4;needErase=true;} + break; + } + + case (0):{break;} + } + key_input = 0; + + // ----- Vertical movement ----- + + if(timer.read_ms()>WAIT_TIME) + { + needErase=true; + if(!isGameOver) + { + if (mBoard.IsPossibleMovement (mGame.mPosX, mGame.mPosY + 1, mGame.mPiece, mGame.mRotation)) + { + mGame.mPosY++; + } + else + { + mBoard.StorePiece (mGame.mPosX, mGame.mPosY, mGame.mPiece, mGame.mRotation); + mGame.AddPoints(SinglePiecePoints); + int linesDeleted = mBoard.DeletePossibleLines (); + if(linesDeleted>0) + { + mGame.AddClearedLines(linesDeleted); + mGame.AddPoints(LineClearPoints*linesDeleted); + Thread t1(FlashLight); + PlayClearSound(); + clear_board(); + } + UpdateGameStatus(mGame.GetPoints(),mGame.GetClearedLines()); + + if (mBoard.IsGameOver()) + { + isGameOver=true; + uLCD.cls(); + uLCD.media_init(); + uLCD.set_sector_address(0x001D, 0x7842); + uLCD.display_image(0,0); + Thread t2(GameOverLight); + PlayOverSound(); + } + + if(!isGameOver) + { + mGame.CreateNewPiece(RandomGen('a'),RandomGen('b')); + clear_next_piece(); + } + } + } + timer.reset(); + } + wait(0.1); + } +}