#include <stdio.h> #include <stdlib.h> #include <time.h> #include <pcc32.h> //★○●◎◇◆□■△☆▲※+ typedef struct tagPOINT2D{ int x; int y; }POINT2D, *PPOINT2D; #define MAP_WIDTH 40 #define MAP_HEIGHT 30 #define OFF_SET_X 1 #define OFFSET_Y 1 #define TOTAL_WIDTH (MAP_WIDTH + OFF_SET_X * 2) #define TOTAL_HEIGHT (MAP_HEIGHT + OFFSET_Y * 2) #define BS_SPACE 0 #define BS_SHEAD 1 #define BS_SBODY 2 #define BS_STAIL 3 #define BS_FOOD 4 #define SNAKE_MIN_LEN 5 #define DIR_UP 1 #define DIR_DOWN 2 #define DIR_LEFT 3 #define DIR_RIGHT 4 #define GoToMap(x,y) gotoTextPos((x)*2,(y)) int snakeLength = SNAKE_MIN_LEN; int snakeDir = DIR_RIGHT; int isFood = 0; int isOver = 0; PCCOLOR myColors[] = {CYAN, MAGENTA, RED, GREEN, YELLOW}; char mySharps[][3] = {"□","◆","■","+","★"}; POINT2D mySnake[MAP_WIDTH*MAP_HEIGHT] = {{0}}; POINT2D myFood = {0}; void showLogo(); void drawMap(); void initGame(); void drawSnake(); void drawBlock(int, int, int); void moveSnake(); void doGame(); int isInSnake(int ,int); void drawFood(); void gameOver(); void sayBye(); int main() { showLogo(); gotoTextPos(25,20); setTextColor(LIGHT_RED); puts("press any key to continue"); jkGetKey(); clearText(); initGame(); drawMap(); drawSnake(); doGame(); gameOver(); clearText(); sayBye(); gotoTextPos(25,20); setTextColor(RED); puts("press any key to break"); jkGetKey(); return 0; } void gameOver() { GoToMap(MAP_WIDTH / 4, MAP_HEIGHT / 2); setTextColor(YELLOW); printf("Game Over! Score: %d.", snakeLength - SNAKE_MIN_LEN); jkGetKey(); } void showLogo() { const char LogoMap[8][64] = { " ■ ■ ■ ■ ■ ■ ■■■■", "■ ■ ■ ■■ ■■ ■ ■ ■ ", "■ ■ ■ ■ ■ ■ ■ ■ ■ ", " ■ ■ ■ ■ ■ ■ ■■ ■■■■", " ■ ■ ■ ■ ■■■■■ ■ ■ ■ ", "■ ■ ■■ ■ ■ ■ ■ ■ ■ ", " ■ ■ ■ ■ ■ ■ ■ ■■■■", " " }; int r, y; fixConsoleSize(TOTAL_WIDTH * 2, TOTAL_HEIGHT); setTextColor(LIGHT_GREEN); setConsoleTitle("贪吃蛇 by_N3verL4nd"); setCursorVisible(false); for (r = 0;r < 7;r++) { for (y = 0; y < 18 - r; y++) { gotoTextPos(10, y); setTextColor((r + y) % 10 + 3); puts(LogoMap[6-r]); delayMS(50); if(y < 18 - r - 1) { gotoTextPos(10, y); puts(LogoMap[7]); } } } return; } void drawMap() { int i, j; for (i = 0; i < MAP_HEIGHT; i++) for (j = 0; j < MAP_WIDTH; j++) drawBlock(j, i, BS_SPACE); } void initGame() { int i; for(i = 0; i < snakeLength; i++) { mySnake[i].x = 8 - i; mySnake[i].y = 3; } return; } void drawSnake(void) { drawBlock(mySnake[0].x, mySnake[0].y, BS_SHEAD); int i; for (i = 1; i < snakeLength - 1; i++) drawBlock(mySnake[i].x, mySnake[i].y, BS_SBODY); drawBlock(mySnake[snakeLength-1].x, mySnake[snakeLength-1].y, BS_STAIL); } void drawBlock(int x, int y, int bs) { if (0 > x || x >= MAP_WIDTH) return; if (0 > y || y >= MAP_HEIGHT) return; gotoTextPos((OFF_SET_X + x) * 2, OFFSET_Y + y); setTextColor(myColors[bs]); printf("%2s",mySharps[bs]); } void moveSnake() { int i; int hx = mySnake[0].x; int hy = mySnake[0].y; if(hx == myFood.x && hy == myFood.y) isFood = 0; switch(snakeDir) { case DIR_UP:hy--;break; case DIR_DOWN:hy++;break; case DIR_LEFT:hx--;break; case DIR_RIGHT:hx++;break; default:break; } if(hx < 0 || hx >= MAP_WIDTH || hy < 0 || hy >= MAP_HEIGHT || isInSnake(hx,hy)) { isOver = 1; return; } if(hx == myFood.x && hy == myFood.y) { snakeLength++; isFood = 0; } drawBlock(mySnake[snakeLength-1].x,mySnake[snakeLength-1].y,BS_SPACE); for(i = snakeLength - 1; i >= 0; i--) { mySnake[i+1].x = mySnake[i].x; mySnake[i+1].y = mySnake[i].y; } mySnake[0].x = hx; mySnake[0].y = hy; drawSnake(); return; } void doGame() { int isPause = 1; while(!isOver) { if(!isPause) { moveSnake(); if(!isFood) drawFood(); } delayMS(120 - snakeLength * 2); if(jkHasKey()) { switch(jkGetKey()) { case JK_UP:if(snakeDir != DIR_DOWN) snakeDir = DIR_UP;break; case JK_DOWN:if(snakeDir != DIR_UP) snakeDir = DIR_DOWN;break; case JK_LEFT:if(snakeDir != DIR_RIGHT) snakeDir = DIR_LEFT;break; case JK_RIGHT:if(snakeDir != DIR_LEFT) snakeDir = DIR_RIGHT;break; case JK_ESC:isOver = !isOver;break; case JK_ENTER: case JK_SPACE:isPause = !isPause; default:break; } } } } int isInSnake(int x, int y) { int i; for(i = 0; i < snakeLength; i++) { if(x == mySnake[i].x && y == mySnake[i].y) return 1; } return 0; } void drawFood() { do { myFood.x = rand() % MAP_WIDTH; myFood.y = rand() % MAP_HEIGHT; } while (isInSnake(myFood.x,myFood.y)); drawBlock(myFood.x,myFood.y,BS_FOOD); isFood = 1; } void sayBye() { const char LogoMap[8][64] = { " ■■■ ■ ■ ■■■■■", " ■ ■ ■ ■ ■ ", " ■ ■ ■ ■ ", " ■■■ ■ ■■■■■", " ■ ■ ■ ■ ", " ■ ■ ■ ■ ", " ■■■ ■ ■■■■■", " " }; int r, y; setTextColor(LIGHT_BLUE); for (r = 0;r < 7;r++) { for (y = 0; y < 18 - r; y++) { gotoTextPos(15, y); puts(LogoMap[6-r]); delayMS(50); if(y < 18 - r - 1) { gotoTextPos(15, y); puts(LogoMap[7]); } } } return; }