2018 US Projekt - Stack Attack (Grupa 9) Haris Salman Amir Muminović Glavni program.

Dependencies:   SPI_TFT_ILI9341 Sprites TFT_fonts mbed

Revision:
0:88e77eadd8e1
diff -r 000000000000 -r 88e77eadd8e1 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Jul 02 20:23:26 2018 +0000
@@ -0,0 +1,400 @@
+#include "mbed.h"
+#include "stdio.h"
+#include "string"
+#include "vector"
+
+#include "SPI_TFT_ILI9341.h"
+#include "GraphicsDisplay.h"
+
+#include "Arial12x12.h"
+#include "Arial24x23.h"
+#include "Arial28x28.h"
+#include "font_big.h"
+
+#include "Sprites.h"
+
+// Konstante: Velicina kutije, padding sa lijeva
+#define BoxSize 30
+#define LPAD 10
+
+using std::vector;
+
+//                      MOSI, MISO,  SCK,   CS, RESET,   DC, NAME
+SPI_TFT_ILI9341 display(PTD2, PTD3, PTD1, PTE2, PTA20, PTD5, "display");
+AnalogIn Jx(PTB1);
+AnalogIn Jy(PTB2);
+DigitalIn BTN(PTE5);
+Timer deb;
+
+// Master ticker za igru
+Ticker gridTicker;
+
+vector<vector<bool> > mapa;
+
+double OffsetX, OffsetY;
+bool paused(false);
+bool gameover(false);
+bool toggleDraw(true);
+
+int generateRandom();
+void gameOver();
+
+class Claw {
+    int position, target;
+    bool hasBox;
+    double moveTime; // Vrijeme neophodno da se ruka pomjeri sa jedne lokacije na drugu, u milisekundama
+public:
+    Claw() : position(0), target(generateRandom()), hasBox(true), moveTime(1000) {}
+
+    void GiveBox() {
+        if (position == 0 && !hasBox){
+            hasBox = true;
+            target = generateRandom();
+        }
+    }
+    
+    void MoveClaw() {
+        GiveBox();
+        if (target > position) position++;
+        else if (target < position) position--;
+        else if (target == position) BaciBox();
+    }
+
+    void BaciBox() {
+        hasBox = false;
+        if (mapa[5][position]){
+            bool kraj(true);
+            for(int i(0); i<5; i++) if(mapa[i][position]==0) kraj=false;
+            if(kraj) gameOver();
+        }
+        mapa[5][position] = true; // Dodaj kutiju u 
+        target = 0; // Pokupi novu na pocetku
+    }
+
+    void DrawClaw() {
+        //                         x0         y0               sirina   visina   *bitmap
+        if(!hasBox) display.Bitmap(position*BoxSize + LPAD, 0, BoxSize, BoxSize, claw);
+        else display.Bitmap(position*BoxSize + LPAD, 0, BoxSize, BoxSize, clawBoxColor);
+    }
+    
+    void drawBlank(){
+        display.fillrect(position*BoxSize + LPAD, 0, position*BoxSize + BoxSize + LPAD, BoxSize, White);
+    }
+    
+    void TickerFja(){
+        drawBlank();
+        MoveClaw();
+        DrawClaw();    
+    }
+};
+
+class Player{
+    short int x, y;
+public:
+    Player() : x(5),y(0){}
+    
+    void PomjeriDesno(){
+        if(x < 9){ //Ako moze jos ici desno
+            if (mapa[y][x+1] == 0 && mapa[y+1][x+1] == 0){ //Ako desno nije kutija
+                drawBlank(y,x); drawBlank(y+1,x);
+                x++;
+            }
+            else{ // Ako jeste kutija
+                if (x+1 < 9){ // Ako nije kutija na kraju
+                    if (mapa[y][x+2] == 0 && mapa[y+1][x+1] == 0){ // Ako ima mjesta za pomjeranje kutije
+                        drawBlank(y,x); drawBlank(y+1,x);
+                        x++; //Update lokacije
+                        mapa[y][x] = 0;    //Brisi kutiju
+                        mapa[y][x+1] = 1; //Pomjeri kutiju na novu lokaciju
+                    }
+                }
+            }
+        }
+    }
+    
+    void PomjeriLijevo(){
+        if(x > 0){ //Ako moze jos ici lijevo
+            if (mapa[y][x-1] == 0 && mapa[y+1][x-1] == 0){ // Ako lijevo nije kutija
+                drawBlank(y,x); drawBlank(y+1,x);
+                x--;
+            } else { // Ako jeste kutija
+                if (x-1 > 0){ //Ako nije kutija na kraju
+                    if (mapa[y][x-2] == 0 && mapa[y+1][x-1] == 0){ // Ako ima mjesta za pomjeranje kutije
+                        drawBlank(y,x); drawBlank(y+1,x);
+                        x--; //Update lokacije
+                        mapa[y][x] = 0;    //Brisi kutiju
+                        mapa[y][x-1] = 1; //Pomjeri kutiju na novu lokaciju
+                    }
+                }
+            }
+        }
+    }
+    
+    void PomjeriGore(){
+        // Provjeri da ima od sta ispod sebe da odskoci, kao i ako je dosao do vrha
+        if(y == 0 || (y < 6 && mapa[y-1][x] == 1)){
+            drawBlank(y,x);
+            y++;
+        }
+    }
+
+    void PomjeriGoreDesno(){
+        if(y == 0 || (y < 6 && mapa[y-1][x] == 1)){
+            if (x < 9 && y < 6){ //Ima prostora za skok
+                if (mapa[y+1][x+1] == 0){ // Pomjeri igraca ako nema kutije
+                    drawBlank(y,x); drawBlank(y+1,x);
+                    x++;
+                    y++;
+                }
+                else { // Ako ima kutije, pomakni kutiju
+                    if (x < 8){ // Ako nije boundary
+                        if (mapa[y+1][x+2] == 0) {// Ako se moze pomaci desno
+                            drawBlank(y,x); drawBlank(y+1,x);
+                            x++;
+                            y++;
+                            mapa[y][x] = 0; // Nema tu kutije
+                            mapa[y][x+1] = 1; // Sad je pomaknuta desno
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    void PomjeriGoreLijevo(){
+        if(y == 0 || (y < 6 && mapa[y-1][x] == 1)){
+            if (x > 0 && y < 6){ //Ima prostora za skok
+                if (mapa[y+1][x-1] == 0){ // Pomjeri igraca ako nema kutije
+                    drawBlank(y,x); drawBlank(y+1,x);
+                    x--;
+                    y++;
+                }
+                else { // Ako ima kutije, pomakni kutiju
+                    if (x - 2 > 0){ // Ako nije boundary
+                        if (mapa[y+1][x-2] == 0) {// Ako se moze pomaci desno
+                            drawBlank(y,x); drawBlank(y+1,x);
+                            x--;
+                            y++;
+                            mapa[y][x] = 0; // Nema tu kutije
+                            mapa[y][x-1] = 1; // Sad je pomaknuta desno
+                        }
+                    }
+                }
+            }
+        } 
+    }
+    
+    void DaLiJeZiv(){   
+        if (mapa[y+1][x]) gameOver();
+    }
+    
+    int GetX(){ return x; }
+    int GetY(){ return y; }
+    void SetX(int Ox){ x = Ox; }
+    void SetY(int Oy){ y = Oy; }
+    
+    void drawPlayer(){
+        //             x0                     y0            širina   visina         *bitmap
+        display.Bitmap(x*BoxSize + LPAD + 1, (5-y)*BoxSize, BoxSize, 2*BoxSize + 1, charColor);
+    }
+    
+    void drawBlank(int row, int column){
+        display.fillrect(row*BoxSize + LPAD + 1, column*BoxSize, row*BoxSize + BoxSize + LPAD, column*BoxSize + BoxSize - 1, White);
+    }
+};
+
+// Vraca random broj od 0 do 99 jer FRDM nema sat za random seed
+int generateRandom(){
+    int random(int((Jx+Jy+1) * (rand()%100))%10);
+    if(random < 0) random *= -1;
+    return random;
+}
+
+class Grid{
+    Player p;
+    Claw c;
+    int score;
+public:
+    Grid(){ setupMap(); }
+    
+    Player& Igrac(){ return p; }
+    
+    void setupMap(){
+        p.SetX(5);
+        p.SetY(0);
+        score = 0;
+        mapa.resize(0);
+        vector<bool> novi(10, false);
+        for (int i(0); i < 6; i++) mapa.push_back(novi);
+        
+        mapa[0][0] = mapa[0][1] = mapa[0][7] = true;
+    }
+    
+    int GetScore(){ return score; }
+    
+    void gravity(){
+        if(p.GetY()>0 && !mapa[p.GetY()-1][p.GetX()]) p.SetY(p.GetY()-1);    
+    }
+    
+    void masterTicker(){
+        /*if(BTN){
+            gridTicker.detach();
+            pause();
+            gridTicker.attach(this, &Grid::masterTicker, 1);
+        }*/
+        c.TickerFja();
+        readJoystick();
+        p.drawPlayer();
+        drawMap();
+    }
+    
+    void drawMap(){
+        drawBorders();
+        displayScore();
+        
+        // Crtanje mape ovisno o matrici prisustva
+        for(int i(0); i<6; i++){
+            for(int j(0); j<10; j++){
+                if(mapa[i][j]) drawBox(j, 6-i);
+                else if((i==p.GetY() || i==p.GetY()+1) && j==p.GetX()) continue;
+                else drawBlank(j, 6-i);
+            }
+        }
+        calculatePoints();
+        if(toggleDraw = !toggleDraw) refreshMapa();
+        p.DaLiJeZiv();
+    }
+    
+    void refreshMapa(){
+        // Kad padaju kutije, treba se pozivati svaku sekundu
+        // Gravitacija igrača
+        gravity();
+        for(int i(1); i<6; i++){
+            for(int j(0); j<10; j++){
+                if (mapa[i][j] && !mapa[i-1][j]){
+                    mapa[i][j] = false;
+                    mapa[i-1][j] = true;
+                }
+            }
+        }
+    }
+    
+    void calculatePoints(){
+        bool rowFull(true);
+        // Vidi kakvo je stanje
+        for (int i(0); i < 10; i++){
+            if (mapa[0][i] == 0) rowFull = false;
+        }
+        // Ako je red pun, briši sve i dodaj bodove
+        if (rowFull){
+            for (int i(0); i < 10; i++) mapa[0][i] = 0;
+            score += 100;
+            displayScore();
+        }
+    }
+    
+    void drawBox(int row, int column){
+        display.rect(row*BoxSize + LPAD, column*BoxSize, row*BoxSize + BoxSize + LPAD, column*BoxSize + BoxSize, Black);
+        display.line(row*BoxSize + LPAD, column*BoxSize, row*BoxSize + BoxSize + LPAD, column*BoxSize + BoxSize, Black);
+        display.line(row*BoxSize + BoxSize + LPAD, column*BoxSize, row*BoxSize + LPAD, column*BoxSize + BoxSize, Black);
+    }
+    
+    void drawBlank(int row, int column){
+        display.fillrect(row*BoxSize + LPAD + 1, column*BoxSize, row*BoxSize + BoxSize + LPAD, column*BoxSize + BoxSize - 1, White);
+    }
+    
+    // Nacrtaj granice igre
+    void drawBorders(){
+        display.line(LPAD - 1, 0, LPAD - 1, 211, Black);      // Lijeva granica
+        display.line(311, 0, 311, 210, Black);                // Desna granica
+        display.line(LPAD - 1, 211, 311, 211, Black);         // Donja granica
+    }
+    
+    void displayScore(){
+        display.locate(166, 219);
+        display.printf("SCORE:%6d", score);
+    }
+
+    void readJoystick(){
+        // Debouncing džojstika
+        if(deb.read_ms()<0.4) return;
+        deb.reset();
+        
+        int x = Jx*3.3 - 0.4;  // 0 = Lijevo, 1 = Ništa, 2 = Desno
+        int y = Jy*3.3 - 0.4;  // 0 = Dole,   1 = Ništa, 2 = Gore
+        
+        if(x == 0){
+            if(y == 0) p.PomjeriGoreLijevo();
+            else p.PomjeriLijevo();
+        } else if(x == 2){
+            if(y == 0) p.PomjeriGoreDesno();
+            else p.PomjeriDesno();
+        } else if(y == 0) p.PomjeriGore();
+    }
+};
+
+Grid g;
+
+// Iskljuceno radi problema sa InterruptIn
+void pause(){
+    // Resetuje igru ako je trenutno kraj
+    if(gameover){
+        gameover = false;
+        display.cls();
+        g.setupMap();
+        return;
+    }
+    
+    if(deb.read_ms()>1000){
+        // Toggle trenutno stanje pauze
+        paused = !paused;
+        
+        if(paused){
+            display.locate(LPAD, 219);
+            display.printf("PAUZA");
+            while(paused);
+        } else {
+            // Obriši tekst za pauzu, nastavi igru
+            display.fillrect(LPAD, 219, 70, 231, White);
+        }
+    }
+    deb.reset();
+}
+
+void gameOver(){
+    gridTicker.detach();
+    gameover = true;
+    display.cls();
+    
+    display.locate(58, 100);
+    display.set_font((unsigned char*) Arial28x28);
+    display.printf("GAME OVER");
+    display.set_font((unsigned char*) Arial12x12);
+    display.locate(100, 140);
+    display.printf("SCORE:%6d", g.GetScore());
+    //display.locate(70, 180);
+    //display.printf("Press Joystick to restart...");
+    
+    while(1){
+        if(gameover) wait(0.1);
+        else break;
+    }
+}
+
+// -------------------------------------------------------------------------- //
+
+int main() {
+    display.claim(stdout);
+    display.set_orientation(1);
+    display.background(White);
+    display.foreground(Black);
+    display.cls();
+    display.set_font((unsigned char*) Arial12x12);
+    
+    deb.start();
+    gridTicker.attach(&g, &Grid::masterTicker, 0.25);
+
+    while(1) {
+        wait(1);
+    }
+}
\ No newline at end of file