#include<stdio.h>
#include<stdlib.h> //清屏命令在这里。
#include <windows.h> //延时10毫秒-sleep,gotoxy函数
#include <iostream>
#include <conio.h> //getch()----不用按回车,就可以输入字符。
using namespace std;
//函数外定义全局变量
#define High 20
#define Width 50 //定义游戏画面尺寸
int canvas[High][Width] = {0}; //二维数组记录游戏画面中对应的元素
//0为空格,-1为边框#,1为蛇头@,>1为蛇身体*,-2表示食物F
int moveDirection; //小蛇移动方向,1,2,3,4 表示上下左右移动方向。
int food_x, food_y; //记录食物的位置。
int score=0; //吃到的分数
void gotoxy(int x, int y) // 光标移动到intx,inty位置
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void HideCursor() //
{
CONSOLE_CURSOR_INFO cursor_info = { 1,0 }; //第二个值为0,表示隐藏光标
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void startup() //数据初始化
{
//==========以下设定边框的数值========
int i, j;
for (i = 0; i < High; i++) //处理边框,设置上下边框。
{
canvas[i][0] = -1;
canvas[i][Width - 1] = -1;
}
for (j = 0; j < Width; j++) //处理边框,设置左右边框。
{
canvas[0][j] = -1;
canvas[High-1][j] = -1;
}
//==========以上设定边框的数值========
//==========以下初始化蛇头蛇身体========
canvas[High / 2][Width / 2] = 1; //蛇头是1
for (i = 1; i <= 4;i++) //蛇身子>1,为什么大于1,终于解释清楚了。
{
canvas[High / 2][Width / 2-i] = i+1;//蛇身子>1,为什么大于1,终于解释清楚了。
}
//初始化小蛇移动方向向右。
moveDirection = 4;
//食物位置初始化。随机位置
food_x = rand() % (High - 5) + 2;
food_y = rand() % (Width - 5) + 2;
canvas[food_x][food_y] = -2;
HideCursor(); //隐藏光标
}
void moveSnakeByDirection()
{
int i, j;
int max = 0;
int oldertail_i, oldertail_j; //记录。。旧的蛇尾x和y坐标
int olderhead_i, olderhead_j; //记录,旧的蛇头x和y坐标。
for (i = 1; i < High - 1; i++)
{
for (j = 1; j < Width - 1; j++)
{
if (canvas[i][j] > 0)
{
//对所有大于0的元素+1
canvas[i][j]++;
//求出最大值,并且记录下来。
if (max < canvas[i][j])
{
max = canvas[i][j]; //对所有大于0的元素遍历,就可以求出最大值!
oldertail_i = i;
oldertail_j = j;
}
//找出了旧的蛇头部分。 x和y坐标
if (canvas[i][j] == 2)
{
olderhead_i = i;
olderhead_j = j;
}
}
}
}
int newhead_i, newhead_j; //定义了新的蛇头x和y坐标
if (moveDirection == 1) //向上移动
{
//canvas[olderhead_i - 1][olderhead_j] = 1;
newhead_i = olderhead_i - 1;
newhead_j = olderhead_j; //每次改变方向,都把新蛇头位置赋值给newhead
}
else if (moveDirection == 2)//向下移动
{
//canvas[olderhead_i + 1][olderhead_j] = 1;
newhead_i = olderhead_i + 1;
newhead_j = olderhead_j;
}
else if (moveDirection == 3)//向左移动
{
//canvas[olderhead_i][olderhead_j - 1] = 1;
newhead_i = olderhead_i ;
newhead_j = olderhead_j-1;
}
else if (moveDirection == 4)//向右移动
{
//canvas[olderhead_i][olderhead_j + 1] = 1;
newhead_i = olderhead_i ;
newhead_j = olderhead_j+1;
}
//判断小蛇蛇头是否碰到食物
if (canvas[newhead_i][newhead_j] == -2)
{
//食物位置归零
canvas[food_x][food_y] = 0; //归零
//产生新的食物。。
food_x = rand() % (High - 5) + 2;
food_y = rand() % (Width - 5) + 2;
canvas[food_x][food_y] = -2;
//吃到食物,不用把最大值设为0;长度+1;
score++;
}
else
{
//没有吃到食物的时候,长度不变
canvas[oldertail_i][oldertail_j] = 0; //让蛇尾最大值处部=0
}
//判断蛇头撞到边框或者自身,游戏结束
if ((canvas[newhead_i][newhead_j]>0) || (canvas[newhead_i][newhead_j]==-1))
{
printf("游戏失败\n");
exit(0);
}
else
{
canvas[newhead_i][newhead_j] = 1; //设置一下新蛇头的位置,状态。
}
}
void show() //显示画面
{
gotoxy(0, 0); //光标移动到原点位置,以下重置清屏
int i, j;
for (i = 0; i < High;i++) //2个for循环,将飞机,子弹,敌机都现在在屏幕上,通过不停的循环。巧妙的思路。
{
for (j = 0; j < Width;j++)
{
if (canvas[i][j] == 0)
{
printf(" "); //输出空格
}
else if (canvas[i][j]==-1)
{
printf("#"); //输出边框#
}
else if (canvas[i][j] == 1)
{
printf("@"); //输出蛇头@
}
else if (canvas[i][j] > 1)
{
printf("*"); //输出蛇身*
}
else if (canvas[i][j] ==-2)
{
printf("F"); //输出食物F
}
}
printf("\n"); //这个位置不能乱动!否则错位。
}
//printf("得分:%d\n :", score);
cout << "得分:" << score << endl;
Sleep(150);
}
void UpdateWithoutInput() //与用户输入无关的更新,例如子弹自动往上飞,敌机自动往下落
{
moveSnakeByDirection();
}
void UpdateWithInput() //与用户输入有关的更新。
{
char input;
if (kbhit()) //当按键时候执行。
{
input = getch();
if (input=='a')
{
moveDirection = 3;
}
if (input == 'd')
{
moveDirection = 4;
}
if (input == 'w')
{
moveDirection = 1;
}
if (input == 's')
{
moveDirection = 2;
}
}
}
int main()
{
startup(); //数据初始化
while (1)
{
show(); //显示画面
UpdateWithoutInput(); //与用户输入无关的更新
UpdateWithInput(); //与用户输入有关的更新。
}
return 0;
}
网友评论