v1.0

Dependencies:   LCDTFT TFT_fonts mbed

Files at this revision

API Documentation at this revision

Comitter:
trapsis
Date:
Fri Jun 10 03:14:38 2016 +0000
Commit message:
running fine

Changed in this revision

LCDTFT.lib Show annotated file Show diff for this revision Revisions of this file
TFT_fonts.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
snake_main_game.cpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LCDTFT.lib	Fri Jun 10 03:14:38 2016 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/users/cstevens/code/LCDTFT/#b5ecdc15f1a3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TFT_fonts.lib	Fri Jun 10 03:14:38 2016 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/users/cstevens/code/TFT_fonts/#8786a96c2bee
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Jun 10 03:14:38 2016 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/6c34061e7c34
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/snake_main_game.cpp	Fri Jun 10 03:14:38 2016 +0000
@@ -0,0 +1,383 @@
+//ssd0139 LCD display
+#include "mbed.h"
+#include "LCDTFT.h"
+#include "Arial28x28.h"
+
+PortOut MyPort(PortD ,0xFF); // define a port with only the lower 8 bits included - that'llbe PTD0-PTD7 making a single 8 bit port.
+LCDTFT  MyLCD(PTB0,PTB1,PTB2,PTB3,PTC2,&MyPort);//LCDTFT(PinName PIN_RD,PinName PIN_WR,PinName PIN_RS,PinName PIN_CS,PinName PIN_RESET, PortOut *PORTLCD);
+Serial pc(USBTX,USBRX); // terminal for debuggin purposes
+bool GameRunning = 1; //establish if the game is running
+
+void run();
+void countdown();
+void changeDirec();
+void nextmove();
+void initGrid();
+void updateGrid();
+void drawGrid();
+void checkposition();
+void gameover1();
+void gameover2();
+void PrettyPrint(char *message,const unsigned char *font,short xpos,short ypos,short bcol, short fcol);
+void prettyputc(char c, const unsigned char *font,short xpos,short ypos,short bcol, short fcol);
+
+int NowTime =7;
+int StartTime=1;
+//time variables over from Dan's program
+
+const int gridWidth = 64;
+const int gridHeight = 48;
+char grid [48][64];
+char snake [2][255];
+//represent the grid as a 2 dimensional array
+
+char newDirectSnake = 3;
+char newDirectFood = 2;
+char newFoodVel = 0;
+//incoming values from the controller
+
+int snakexpos = 20;
+int snakeypos = 20;
+char directSnake = 3;
+char snakeSize = 3;
+//establish values for the snake
+
+int foodxpos = 2;
+int foodypos = 20;
+char foodvel = 1;
+char directFood = 1;
+//establish values for the food
+
+char message [32];
+//for printing purposes
+
+int framecount = 0;
+//number of iterations in the main loop
+
+
+
+// next two functions need moving to the library.....
+// ok - a simple sub to put in a character from the fonts defined in TFT_fonts
+// c= charactetr to put
+// font = pointer to font to use
+// x,y locatoin of bottom lh of character, bcol = background color, fcol = foreground color
+//prettyputc("m",Arial12x12,50,50,ColorBlack,ColorWhite);
+void prettyputc(char c, const unsigned char *font,short xpos,short ypos,short bcol, short fcol)
+{
+    // Length,horz,vert,byte/vert
+    int length,hor,vert,bpver; // number of bytes per character, horizontal pixels, vertical pixels and bytes per column
+    //
+    int x,y,i,j,k,ptr;
+    short coltowrite;
+    char byte,point;
+    length=font[0];
+    hor=font[1];
+    vert=font[2];
+    bpver=font[3];
+    for(i=0; i<hor; i++) { // loop over columns
+        for(j=0; j<vert; j++) {
+            x=xpos+i;
+            y=ypos+j; // NB assumes colums stored from bottom to top.... ?
+            ptr=((c -32) * length+1) + 4+i*bpver+(j/8);  // pointer in font array to start of the character we want +1 to avoid the first byte that holds the char width
+            byte=(char)font[ptr];
+            k=j%8; // number of the pixel in this byte
+            point=byte & (1<<k); // get the next bit
+            if(point>0) {
+                coltowrite=fcol;
+            } else {
+                coltowrite=bcol;
+            }
+
+            MyLCD.vLCDTFTPoint(x,y,coltowrite);
+
+        }
+    }
+
+}
+
+
+
+
+// ok now a function to use pretty putc to write strings whose bottom left corner are at xpo,ypos
+// general idea is that the string is first formatted byb sprintf and the PrettyPrint is called
+// bcol and fcol are the backgroun adn foreground colors
+//NB max message length = 64 characters
+void PrettyPrint(char *message,const unsigned char *font,short xpos,short ypos,short bcol, short fcol)
+{
+    short x,y,messlength,i,ptr;
+    messlength=strlen(message);
+    if (messlength >64) messlength=64;  // avoid writing too large a string....
+    x=xpos;
+    for(i=0; i<messlength; i++) {
+        // x=xpos+i*(font[1]*8/10); // font[1]=char width 80% to avoid gaps
+        //pointer = &font[((c -32) * offset) + 4]; // start of char bitmap
+        // w = pointer[0];                          // width of actual char
+        ptr=((message[i] -32) * font[0]) + 4;
+
+        y=ypos; // will have to add cod and more to deal with different screen orientations
+        //prettyputc(char c, const unsigned char *font,short xpos,short ypos,short bcol, short fcol)
+        prettyputc(message[i],font,x,y,bcol,fcol);
+        x=x+font[ptr]+2;
+    }
+
+}
+
+
+void run()
+//the main game program
+{
+    while (1) {
+        if (GameRunning == 1) {
+           // countdown();
+            initGrid();
+            while (1) {
+               
+                
+                checkposition();
+                changeDirec();
+                nextmove();
+                updateGrid();
+                drawGrid();
+                framecount++;
+            }
+        }
+    }
+
+}
+
+
+void countdown()
+//countdown before game begins
+{
+    MyLCD.vLCDTFTInit(1);
+    MyLCD.vLCDTFTFillScreen(ColorBlack);
+
+    sprintf(message,"Get Ready!");
+    PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime);
+    wait(1);
+
+    MyLCD.vLCDTFTFillScreen(ColorBlack);
+    sprintf(message,"3");
+    PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime);
+    wait(1);
+
+    MyLCD.vLCDTFTFillScreen(ColorBlack);
+    sprintf(message,"2");
+    PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime);
+    wait(1);
+
+    MyLCD.vLCDTFTFillScreen(ColorBlack);
+    sprintf(message,"1");
+    PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime);
+    wait(1);
+
+    MyLCD.vLCDTFTFillScreen(ColorBlack);
+    sprintf(message,"Run!");
+    PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime);
+    wait(1);
+
+}
+
+void initGrid()
+//initialize the grid
+{
+    MyLCD.vLCDTFTInit(1);
+    MyLCD.vLCDTFTFillScreen(ColorBlack);
+
+    for(int x=0; x<gridHeight; x++) {
+        for(int y=0; y<gridWidth; y++) {
+            grid[x][y] = 0;
+        }
+    }
+    //initialize the pixel grid as an array of zeros
+    snake[0][0] = snakexpos;
+    snake[1][0] = 20;
+    snake[0][1] = 21;
+    snake[1][1] = 20;
+    snake[0][2] = 22;
+    snake[1][2] = 20;
+
+     for(int i=3; i<255; i++) {
+        grid[snake[1][i]][snake[0][i]] = 0;
+    }
+    //initialize the snake as horizontal with respect to its initial size (1 = tile occupied by snake)
+
+    grid[foodypos][foodxpos] = 2;
+    //initialize the food (2 = tile occupied by food)
+}
+
+void updateGrid()
+//update the grid with positions
+{
+    if (grid[snakexpos][snakeypos] == 1)
+    gameover2();
+        else
+        {
+            
+        for(int a=snakeSize-2; a>=0; a--) {
+
+         snake[0][a+1] = snake [0][a];
+         snake[1][a+1] = snake [1][a];
+        }
+        
+        snake[0][0] = snakexpos;
+        snake[1][0] = snakeypos;
+    }
+
+    for(int x=0; x<gridHeight; x++) {
+        for(int y=0; y<gridWidth; y++) {
+            grid[x][y] = 0;
+        }
+    }
+
+    for(int i=0; i<snakeSize; i++) {
+        grid[snake[1][i]][snake[0][i]] = 1;
+
+    }
+    //update the snake, if the tile was previously occupied, snake has hit itself = gameover2
+
+    if (grid[foodypos][foodxpos] == 1) {
+        gameover1();
+    }
+
+    else {
+        grid[foodypos][foodxpos] = 2;
+    }
+    //update the food, if the tile was previously occupied, food has hit snake = gameover1
+}
+
+
+void drawGrid()
+//draw the grid
+{
+
+    for(int x=0; x<gridHeight; x++) {
+        for(int y=0; y<gridWidth; y++) {
+          /*  if (grid[x][y] == 0) {
+                MyLCD.vLCDTFTRectangle(5*y,5*x,5*y+5,5*x+5,1,ColorBlack);
+            }
+            */
+            if (grid[x][y] == 1) {
+                MyLCD.vLCDTFTRectangle(5*y,5*x,5*y+5,5*x+5,1,ColorBlue);
+            }
+            if (grid[x][y] == 2) {
+                MyLCD.vLCDTFTRectangle(5*y,5*x,5*y+5,5*x+5,1,ColorWhite);
+            }
+        }
+    }
+
+     wait (0.1); //the game is 10fps (up for discussion we'll see how this goes)
+}
+
+void changeDirec()
+//changing direction, the command will have to come from the controller program
+//assume 0 for up, 1 for right, 2 for down, 3 for left
+{
+    foodvel = newFoodVel;
+    directFood  =  newDirectFood;
+    //assign new direction and speed to food
+
+    if ((newDirectSnake + directSnake)%2 == 0 && newDirectSnake != directSnake)
+    gameover2();
+    //the snake loses if it tries to double up on itself
+
+    else
+    directSnake =  newDirectSnake;
+    //assign new direction to snake
+}
+
+void nextmove()
+//move the snake and the food by incrementing their coordinates (for the food increment by velocity)
+{
+    if (framecount%5 == 0){
+        snakeSize++;
+        }
+    // every 5 iterations, the snake grows
+   
+    
+    MyLCD.vLCDTFTRectangle(5*foodxpos,5*foodypos,5*foodxpos+5,5*foodypos+5,1,ColorBlack);
+    MyLCD.vLCDTFTRectangle(5*snake[0][snakeSize-1],5*snake[1][snakeSize-1],5*snake[0][snakeSize-1]+5,5*snake[1][snakeSize-1]+5,1,ColorBlack);
+
+    
+    if (directFood == 0) {
+        foodypos -= foodvel;
+    }
+    if (directFood == 1) {
+        foodxpos += foodvel;
+    }
+    if (directFood == 2) {
+        foodypos += foodvel;
+    }
+    if (directFood == 3) {
+        foodxpos -= foodvel;
+    }
+    // check the direction of food and increment position according to velocity
+
+    if (directSnake == 0) {
+        snakeypos -= 1;
+    }
+    if (directSnake == 1) {
+        snakexpos += 1;
+    }
+    if (directSnake == 2) {
+        snakeypos += 1;
+    }
+    if (directSnake == 3) {
+        snakexpos -= 1;
+    }
+
+}
+
+void checkposition()
+//check position to see if either player is out of bounds
+{
+    if (snakeypos > gridHeight || snakeypos < 0)
+        gameover2();
+
+    if (snakexpos > gridWidth || snakexpos < 0)
+        gameover2();
+
+    if (foodypos > gridHeight || foodypos < 0)
+        gameover1();
+
+    if (foodxpos > gridWidth || foodxpos < 0)
+        gameover1();
+
+    //end the game with the appropriate game over screen if either player is out of bounds
+}
+
+
+void gameover1()
+//print game over message and display final score
+{
+    MyLCD.vLCDTFTFillScreen(ColorBlack);
+
+    sprintf(message,"You are snake food!");
+    PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime);
+
+    sprintf(message,"Survival Time:");
+    PrettyPrint(message,Arial28x28,10,100,ColorBlack,ColorLime);
+    wait (1000);
+
+    GameRunning = 0;
+}
+
+void gameover2()
+//an alternate ending is that the snake has made a mistake and that the food wins
+{
+    MyLCD.vLCDTFTFillScreen(ColorBlack);
+    sprintf(message,"The snake is dead!");
+    PrettyPrint(message,Arial28x28,10,50,ColorBlack,ColorLime);
+    wait (1000);
+
+    GameRunning = 0;
+}
+
+
+int main()
+{
+    run();
+}
+
+
+