C语言控制台贪吃蛇3
蛇动起来及随方向移动
一、🐍蛇直线动
1、逻辑:从尾巴向头,每个节点完全复制前一个节点,蛇头单独处理
(1)蛇方向的枚举变量中对方向进行赋值:
//蛇方向 enum {to_east = 2, to_west = -2, to_south = 1, to_north = -1};
(2)在蛇移动函数中进行从蛇尾向蛇头遍历,并初始化蛇移动方向为向西:
#define DEF_SNAKE_LONG 20 int g_nSnakeDir = to_west;//自动向西移动 int i = DEF_SNAKE_LONG - 1; //从后向前遍历 for(; i >= 1; i--) { //过滤掉非法蛇身 if(0 == g_arrSnake[i][1]) { continue; } //把前面一个节点的值赋给前一个节点 g_arrSnake[i][0] = g_arrSnake[i-1][0]; g_arrSnake[i][1] = g_arrSnake[i-1][1]; g_arrSnake[i][2] = g_arrSnake[i-1][2]; } g_arrSnake[0][2] = g_nSnakeDir;
(3)处理蛇头:
//处理蛇头 if(to_west == g_arrSnake[0][2] || to_east == g_arrSnake[0][2]) { g_arrSnake[0][1] += g_arrSnake[0][2]; } else { g_arrSnake[0][0] += g_arrSnake[0][2]; }
(4)之后要重新画出蛇身,调用DrawSnake函数
2、销毁残留蛇身
//遍历每行,遇到初始蛇的位置拷贝方块空格 for(; g_arrSnake[i][0] != 0; i++) { strncpy(&g_strgameback[g_arrSnake[i][0]][g_arrSnake[i][1]], " ", 2); }
二、加入方向键,让蛇随方向键动起来
1、定义函数void SnakeDir()//改变蛇的方向,用到异步检测按键(同步和异步的区别):GetAsyncKeyState()
代码如下:
if(GetAsyncKeyState('W')) { g_nSnakeDir = to_north; } else if(GetAsyncKeyState('S')) { g_nSnakeDir = to_south; } else if(GetAsyncKeyState('A')) { g_nSnakeDir = to_west; } if(GetAsyncKeyState('D')) { g_nSnakeDir = to_east; }
全部代码(此时并未进行蛇的死亡判断,当蛇移动到边界时不会死亡并会出现BUG):
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #include <windows.h> #include <time.h> typedef int bool; #define true 1 #define false 0 //三件套:添加音乐的函数 #include <Windows.h> #include <mmsystem.h> #pragma comment(lib,"winmm.lib") #define DEF_SNAKE_LONG 20 //定义边框数组 char g_strgameback[20][48] = { "■■■■■■■■■■■■■■■■■■■■■■■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■ ■\n", "■■■■■■■■■■■■■■■■■■■■■■■\n"}; //定义蛇数组 int g_arrSnake[DEF_SNAKE_LONG][3] = {0}; //蛇方向 enum {to_east = 2, to_west = -2, to_south = 1, to_north = -1}; int g_nSnakeDir = to_west; void Cover();//显示首页 void BGM();//播放音乐 void ButtonTest();//显示首页 void ShowBack();//打印游戏边框 void SetSnakeRandPos();//为蛇产生随机位置 void DrawSnake();//将蛇显示到背景上 void Snakemove();//蛇动起来 void Clean();//销毁残留蛇身 void SnakeDir();//改变蛇的方向 int main() { BGM();//播放音乐 Cover();//显示首页 ButtonTest();//检测按键 PlaySound(NULL, 0, 0);//停止播放 system("cls");//清屏 SetSnakeRandPos();//为蛇产生随机位置 ShowBack(); while(1) { system("cls"); SnakeDir();//改变蛇的方向 Snakemove();//蛇动 ShowBack();//显示背景 Sleep(500); } system("pause"); return 0; } //显示首页 void Cover() { printf("\n\n\n\t\t\t <<SNAKE>>\n\n"); printf("\n\n\n\t\t\t<<W,S,A,D control move>>\n\n"); printf("\n\n\n\t\t\t <<space begin>>\n\n\n\n"); } //播放音乐 void BGM() { PlaySound("C:\\Windows\\Media\\Alarm03.wav" , NULL, SND_FILENAME | SND_ASYNC); //以C盘系统文件中.wav文件为例 } //检测按键 void ButtonTest() { char chinput; //检测空格 while(1) { chinput = _getch(); if(' ' == chinput) { break; } } } //打印游戏边框 void ShowBack() { int i = 0; for(; i < 20; i++) { printf(g_strgameback[i]); } } //为蛇产生随机位置 void SetSnakeRandPos() { int nX = -1; int nY = -1; //产生随机数 srand((unsigned int)time(NULL));//中种子 nX = rand()%19 + 1;//对19取余得0~18,+1得0~19 nY = rand()%18 + 1; //初始化的三个节点 g_arrSnake[0][0] = nY; //行 g_arrSnake[0][1] = nY*2; //列 g_arrSnake[0][2] = to_west; //方向 g_arrSnake[1][0] = nY; g_arrSnake[1][1] = nY*2 + 2; g_arrSnake[1][2] = to_west; g_arrSnake[2][0] = nY; g_arrSnake[2][1] = nY*2 + 4; g_arrSnake[2][2] = to_west; //将蛇显示到背景上 DrawSnake(); } //将蛇显示到背景上 void DrawSnake() { int i = 0; for(; g_arrSnake[i][0] != 0; i++)//遍历每行,遇到初始蛇的位置拷贝方块 { strncpy(&g_strgameback[g_arrSnake[i][0]][g_arrSnake[i][1]], "■", 2); } } //蛇动起来 void Snakemove() { int i = DEF_SNAKE_LONG - 1; Clean();//销毁残留蛇身 //从后向前遍历 for(; i >= 1; i--) { //过滤掉非法蛇身 if(0 == g_arrSnake[i][1]) { continue; } //把前面一个节点的值赋给前一个节点 g_arrSnake[i][0] = g_arrSnake[i-1][0]; g_arrSnake[i][1] = g_arrSnake[i-1][1]; g_arrSnake[i][2] = g_arrSnake[i-1][2]; } g_arrSnake[0][2] = g_nSnakeDir; //处理蛇头 if(to_west == g_arrSnake[0][2] || to_east == g_arrSnake[0][2]) { g_arrSnake[0][1] += g_arrSnake[0][2]; } else { g_arrSnake[0][0] += g_arrSnake[0][2]; } //画蛇 DrawSnake(); } //销毁残留蛇身 void Clean() { //同画蛇的代码,只不过拷贝上的是空格 int i = 0; for(; g_arrSnake[i][0] != 0; i++)//遍历每行,遇到初始蛇的位置拷贝方块空格 { strncpy(&g_strgameback[g_arrSnake[i][0]][g_arrSnake[i][1]], " ", 2); } } //改变蛇的方向 void SnakeDir() { if(GetAsyncKeyState('W')) { g_nSnakeDir = to_north; } else if(GetAsyncKeyState('S')) { g_nSnakeDir = to_south; } else if(GetAsyncKeyState('A')) { g_nSnakeDir = to_west; } if(GetAsyncKeyState('D')) { g_nSnakeDir = to_east; } }