Su 200943147

Dependencies:   Gamepad N5110 mbed

Revision:
9:6ee4c806f3e9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Engine/Engine.cpp	Thu May 04 14:20:35 2017 +0000
@@ -0,0 +1,294 @@
+#ifndef ENGINE_H
+#define ENGINE_H
+
+#include "Engine.h"
+
+Engine::Engine()
+{
+}
+
+//initialise each variable and start the game
+void Engine::Init(N5110 &lcd)
+{
+    _Shape.Init();
+    Boundary();
+
+    BottomCollision=0;
+    LeftSideCollision=0;
+    RightSideCollision=0;
+    NEW=0;
+    AddScore=0;
+    Score=0;
+    ScoreDisplay=0;
+}
+
+/** ReadInput
+*
+* Read the input from the microcontroller
+*/
+void Engine::ReadInput(Gamepad &pad)
+{
+    d = pad.get_direction();  //direction
+}
+
+/** Update
+*
+* A function contain all the function of the game
+*/
+void Engine::Update(N5110 &lcd,Gamepad &pad)
+{
+    _Shape.Rotate(pad);
+    _Shape.Update(pad);
+    CollisionCheck();
+    Movement(pad);
+    Dropping(pad);
+    if(NEW==1) {
+        NEW=0;
+        NewBlock();
+    }
+    DeleteLine();
+    GameOver(lcd,pad);
+    Scores(lcd);
+}
+
+/** Pixel
+*
+* Print the array into screen
+*/
+void Engine::Pixel(N5110 &lcd)
+{
+    for(int i=0; i<84; i++) {
+        for(int j=0; j<48; j++) {
+            if(_Shape.ShapeArray[i][j]==1) {
+                lcd.setPixel(i,j);               //Print the shape onto lcd
+            }
+            if(FillArray[i][j]==1) {
+                lcd.setPixel(i,j);               //Print the boundary/game state onto lcd
+            }
+        }
+    }
+    lcd.refresh();                               //refresh the screen
+    lcd.clear();
+}
+
+/** Boundary
+*
+* Set the game plane area
+*/
+void Engine::Boundary()
+{
+    for(int i=0; i<84; i++) {                 //boundary condiction
+        for(int j=0; j<48; j++) {
+            FillArray[0][j]=1;
+            FillArray[29][j]=1;
+        }
+    }
+}
+
+/** CollisionCheck
+*
+* Chech if the moving block collide with the boundary or
+* other block in the game. When it happen set a flag(e.g command)
+* for the following function
+*/
+void Engine::CollisionCheck()
+{
+    for(int i=0; i<84; i++) {
+        for(int j=0; j<48; j++) {
+            if(_Shape.ShapeArray[i][j]==1) {         //searching for bottom collision
+                if(FillArray[i][j+1]==1) {
+                    BottomCollision=1;               //set the flag
+                }
+            }
+            if(_Shape.ShapeArray[i][47]==1) {        //check if the shape block hit the bottom of the game
+                BottomCollision=1;                   //set the flag
+            }
+        }
+    }
+    for(int i=0; i<84; i++) {
+        for(int j=0; j<48; j++) {
+            if(FillArray[i][j]==1) {                  //check if the shape hit the left side of the boundary
+                if(_Shape.ShapeArray[i+1][j]==1) {    //by compare the shape array with boundary array
+                    LeftSideCollision=1;              //set the flag
+                }
+            }
+            if(FillArray[i+1][0]==1) {               //check if the shape hit the right side of the boundary
+                if(_Shape.ShapeArray[i][j]==1) {     //by compare the shape array with boundary array
+                    RightSideCollision=1;            //set the flag
+                }
+            }
+        }
+    }
+    //printf("BottomCollision=%d\n",BottomCollision);
+    //printf("LeftCollision=%d\n",LeftSideCollision);
+    //printf("RightCollision=%d\n",RightSideCollision);
+}
+
+/** Movement
+*
+* The direction of horizontal movement is control by the joystick,
+* it shift pixel by pixel depend on the joystick direction
+*/
+void Engine::Movement(Gamepad &pad)
+{
+    if(d == W) {
+        if(LeftSideCollision==1) {         //if collision occured left movement stop
+            _Shape.x=_Shape.x;             //stop movement
+            LeftSideCollision=0;           //clear flag
+        } else {                           //no collision, movement continue
+            _Shape.x=_Shape.x-1;           // move to the left
+        }
+
+    } else if(d == E) {
+        if(RightSideCollision==1) {        //if collision occured left movement stop
+            _Shape.x=_Shape.x;             //stop movement
+            RightSideCollision=0;          //clear flag
+        } else {                           //no collision, movement continue
+            _Shape.x=_Shape.x+1;           //move to the right
+        }
+    }
+   // printf("x=%d\n",_Shape.x);
+}
+
+/** Dropping
+*
+* Create the falling of each block of shape
+* if collision occurred as it receive the flag command
+* it stop the block of shape from falling
+*/
+void Engine::Dropping(Gamepad &pad)
+{
+    if(BottomCollision==1) {                //if collision occured stop dropping
+        BottomCollision=0;                  //clear flag
+        _Shape.y=_Shape.y;                  //stop moving
+        NEW=1;                              //Set a new flag
+        AddScore=1;                         //Set a new flag
+        pad.tone(400.0,0.1);                //sound feedback
+    } else {
+        _Shape.y=_Shape.y+1;                //continue dropping
+    }
+    //printf("y=%d\n",_Shape.y);
+}
+
+/** SaveBlock
+*
+* Save the block of shape into a array
+*/
+void Engine::SaveBlock()
+{
+    for(int i=0; i<84; i++) {
+        for(int j=0; j<48; j++) {
+            if(_Shape.ShapeArray[i][j]==1) {                 //when there is a one in the shape array save to the game array
+                FillArray[i][j]=_Shape.ShapeArray[i][j];
+            }
+        }
+    }
+    for(int i=0; i<84; i++) {
+        for(int j=0; j<48; j++) {
+            _Shape.ShapeInit[i][j]=0;                         //clear both array for new block
+            _Shape.ShapeArray[i][j]=0;
+        }
+    }
+}
+
+/** NewBlock
+*
+* Generate a new block when current block is in place
+*/
+void Engine::NewBlock()
+{
+    SaveBlock();                               //run this function
+    _Shape.x= 0;                               //clear variable x
+    _Shape.y= 0;                               //clear variable y
+    _Shape.New=0;                              //clear flag
+    _Shape.ShapePicker();                      //run this function
+}
+
+/** Gameover
+*
+* Check the state of the game
+* When the game is over show on the lcd display
+*/
+void Engine::GameOver(N5110 &lcd,Gamepad &pad)
+{
+    for(int i=1; i<29; i++) {
+        if(FillArray[i][2]==1) {
+            for(int i=0; i<84; i++) {
+                for(int j=0; j<48; j++) {
+                    FillArray[i][j]=0;
+                    _Shape.ShapeArray[i][j]=0;                //clear everything when game is over
+                    _Shape.ShapeInit[i][j]=0;
+                }
+            }
+            while(1) {
+                lcd.printString("Game Over",2,2);             //print to screen
+                lcd.refresh();                                //refresh the screen
+                pad.leds_on();                                //led on
+                wait(0.1);                                    //time delay
+                pad.leds_off();                               //led off
+                wait(0.1);                                    //time delay
+                pad.tone(200.0,0.1);                          //sound feedback
+            }
+        }
+    }
+}
+
+/** DeleteLine
+*
+* Delete the row when it is full
+*/
+void Engine::DeleteLine()
+{
+    int j;
+    for(j=0; j<48; j++) {
+        for(int i=1; i<29; i++) {
+            if(FillArray[i][j]==1) {
+                Pixels++;                             //count the pixel
+            }
+          //  printf("Pixels=%d\n",Pixels);
+        }
+        if(Pixels==28) {
+            for(int i=1; i<29; i++) {
+                FillArray[i][j]=0;                    //delete the specific line when it is full
+            }
+            for(int y=j-1; y>-1; y--) {
+                for(int x=1; x<29; x++) {
+                    FillArray[x][y+1]=FillArray[x][y]; //move a row down
+                }
+            }
+            Pixels=0;                                  //clear the number of pixel
+            Score=Score+7;                             //add a score of 7 when the line delete
+          //  printf("Score=%d\n",Score);
+        } else {
+            Pixels=0;                                  //clear the number of pixel
+        }
+    }
+}
+
+/** Scores
+*
+* Each block has a score of one and show on the screen
+*/
+void Engine::Scores(N5110 &lcd)
+{
+    if(AddScore==1) {
+        AddScore=0;
+        CurrentScore=0;
+        for(int i=1; i<29; i++) {
+            for(int j=0; j<48; j++) {
+                if(FillArray[i][j]==1) {
+                    CurrentScore=CurrentScore+1;             //one block has a score of one
+                }
+            }
+        }
+    }
+    ScoreDisplay=Score+CurrentScore/4;                       //score calculation system
+  //  printf("ScoreDisplay=%d\n",ScoreDisplay);
+
+    char buffer[14];                                         //create a buffer to store data
+    sprintf(buffer,"%2d",ScoreDisplay);                      //print the buffer with relative variable
+    lcd.printString("Tetris",45,1);
+    lcd.printString("Score",50,3);                           
+    lcd.printString(buffer,55,4);                            //print the score to the screen
+}
+#endif
\ No newline at end of file