v1.0
Dependencies: LCDTFT TFT_fonts mbed
snake_main_game.cpp
- Committer:
- trapsis
- Date:
- 2016-06-10
- Revision:
- 0:5c5a85d917be
File content as of revision 0:5c5a85d917be:
//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(); }