顯示方式:清屏打印二位數組,數組即游戲地圖,包括牆面(用‘W’表示),蛇(‘H’表蛇頭,‘B’表身體)和食物(用‘f’表示)。
const int MaxMap = 20; char map[MaxMap][MaxMap];
邊緣為牆面:
for (int i = 0; i < MaxMap; i++){ map[0][i] = 'W'; map[MaxMap - 1][i] = 'W'; } for (int i = 1; i < MaxMap-1; i++){ map[i][0] = 'W'; map[i][MaxMap - 1] = 'W'; }
蛇的身體用結構體連接:
struct snake{ int x; int y; struct snake *next; }head,body1,body2,tail;
初始蛇長為4,head表示蛇頭,其next指向NULL;tail表示蛇尾,進食后增加的身體加到tail之前。
int centerpoint = MaxMap / 2; head = { centerpoint, centerpoint, NULL }; body1 = { centerpoint, centerpoint-1, &head }; body2 = { centerpoint, centerpoint - 2, &body1 }; tail = { centerpoint, centerpoint - 3, &body2 }; struct snake *p = &tail; while (p != NULL){ map[p->x][p->y] = 'B'; p = p->next; } map[head.x][head.y] = 'H';
引入一個隨機種子,生成食物:
void food(){ int x = 0, y = 0; srand(time(0)); while (map[x][y]!=' '){ x = rand() % (MaxMap - 1) + 1; y = rand() % (MaxMap - 1) + 1; } map[x][y] = 'f'; return; }
蛇的移動:
首先定義蛇的默認移動方向,這里默認為右(WSAD)。
char direction = 'd';
接收鍵盤輸入的移動方向,並將其替換為默認方向;如果鍵盤未輸入,則為默認方向。
(蛇不能向身體方向移動,此方向無效。)
(nextX,nextY表示蛇頭下一個位置與此時的相對位置。)
計算蛇頭應出現的下一個位置。蛇的身體跟隨移動,清除原蛇尾。
char letter = direction; struct snake *p = &tail; int nextX = 0, nextY = 0, tailX = p->x, tailY = p->y; if (_kbhit()){ letter = _getch(); if (letter == 'w' || letter == 's' || letter == 'a' || letter == 'd'){ if (0 != (direction - letter)){ if (!((letter == 'w' && direction == 's') || (letter == 's' && direction == 'w') || (letter == 'a' && direction == 'd') || (letter == 'd' && direction == 'a'))) direction = letter; } } } switch (direction){ case 'w': nextX = -1; nextY = 0; break; case 's': nextX = 1; nextY = 0; break; case 'a': nextX = 0; nextY = -1; break; case 'd': nextX = 0; nextY = 1; break; default: break; } map[p->x][p->y] = ' ';
蛇身的移動,蛇頭位置的計算
while (p->next != NULL){ p->x = p->next->x; p->y = p->next->y; map[p->x][p->y] = 'B'; p = p->next; } map[head.x][head.y] = 'B'; head.x += nextX; head.y += nextY;
吃食和游戲結束判定:
蛇頭出現的下一個位置如果為牆面或自己的身體,游戲結束。
bool gameover(int x,int y){ if (map[x][y] == 'W' || map[x][y] == 'B') return 1; else return 0; }
蛇頭出現的下一個位置如果有食物,蛇長加1。
bool eat(int x,int y){ if (map[x][y] == 'f'){ food(); return 1; } else{ return 0; } }
進食后,new一個新身體:
if (eat(head.x, head.y)){ snake *newBody = new snake; newBody->x = tail.x; newBody->y = tail.y; newBody->next = tail.next; tail.x = tailX, tail.y = tailY; tail.next = newBody; map[tailX][tailY] = 'B'; snakeLength++; } map[head.x][head.y] = 'H';
顯示:
循環執行蛇的移動過程,並清屏打印地圖。
完整代碼:https://github.com/shuiguai/games/blob/master/snake.cpp
環境:win64,VS2010