全程只需要四个主要的函数:
Map();Gameover();Move(); Creatfood();
和两个用于隐藏光标和移动光标的函数:
gotoxy();hide_cursor();
1,Map() ----- 用于构造地图
2,Move() ----- 用于移动Snake
3,Creatfood() ----- 用于创造食物
4,Gameover() ----- 用于结束游戏
基本思路:
首先利用数组作为结构体成员,用于存储蛇的坐标信息
struct {
int len;//长度
//记录蛇身每个方块的坐标
int x[SNAKESIZE];
int y[SNAKESIZE];
}snake;
1,蛇的移动:“加头去尾”,其中“消除尾部”用以下代码实现:
//在蛇的尾部处打印空格
//主要是从蛇尾坐标出发,不段记录前一个位置的坐标,从而实现不断移动
if(snake.flag==1)//还没吃到食物,把尾巴擦掉
{
gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);
printf(" ");
}
for(int i=snake.len-1;i>0;i--)//移动蛇身
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}
而“增加头部”用以下代码实现:
//头坐标在之前已经没用了,改变头坐标
switch(key)
{
case 'w':snake.y[0]--;break;
case 'a':snake.x[0]-= 2;break;
case 'd':snake.x[0]+= 2;break;
case 's':snake.y[0]++;break;
}
gotoxy(snake.x[0],snake.y[0]);
printf("■");
2,蛇吃食物:“加头不去尾”,只要蛇长度加一,把flag设置为0,不实现以下代码部分即可
if(snake.flag==1)//还没吃到食物,把尾巴擦掉
{
gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);
printf(" ");
}
游戏规则:
通过按’w’,‘a’,‘s’,'d’键控制Snake的移动,连续按两下相同方向的键加速
注:
构造蛇对象的图形为方块,占两个水平格,一个竖直格;
食物对象的图形为圆性,占据位置上同;
温馨提醒:_kbhit()可以检测是否按键,若按键则返回真,并通过_getch()接收按键信息,若没按键则返回假,不执行该部分内容
if (_kbhit())
{
fflush(stdin);
key = _getch();
snake.breaker = 0;//打开加速开关
}
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#define width 60
#define hight 25
#define SNAKESIZE 200//蛇身的最长长度
char key='w';//初始化蛇的运动方向,向上
//'w'为上
//'s'为下
//'a'为左
//'d'为右
struct {
int len;
//用来记录蛇身每个方块的坐标
int x[SNAKESIZE];
int y[SNAKESIZE];
int speed; // 速度
int breaker; //加速开关
int flag;//用来标识是否生成食物,1表示蛇还没吃到食物,0表示吃到食物
}snake;
struct
{
int x;int y;
}food;
//该部分新手无需深入
void gotoxy(int x,int y)//设置CMD窗口光标位置
{
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
void hide_cursor() //隐藏CMD窗口光标
{
CONSOLE_CURSOR_INFO cci;
cci.bVisible = FALSE;
cci.dwSize = sizeof(cci);
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorInfo(handle, &cci);
}
void Map()
{
//打印图框
for (int y = 0; y < hight; y++)
{
for (int x = 0; x < width; x+=2)
{
if (x == 0 || y == 0 || y == hight - 1 || x == width - 2)
{
gotoxy(x, y);
printf("■");
}
}
}
//打印蛇头
snake.len=3;
snake.x[0]=width/2;
snake.y[0]=hight/2;
gotoxy(snake.x[0],snake.y[0]);
printf("■");
//打印蛇身
for(int i=1;i<snake.len;i++)
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1]+1;
gotoxy(snake.x[i],snake.y[i]);
printf("■");
}
//初始速度
snake.speed = 10;
//初始加速开关
snake.breaker = 0;
//初始标识
snake.flag = 1;
//初始食物位置
food.x=20;
food.y=20;
gotoxy(food.x,food.y);
printf("●");
}
void Move()//按键处理函数
{
int history_speed;
char history_key=key;
if (_kbhit())
{
fflush(stdin);
key = _getch();
snake.breaker = 0;//打开加速开关
}
if(snake.flag==1)//还没吃到食物,把尾巴擦掉
{
gotoxy(snake.x[snake.len-1],snake.y[snake.len-1]);
printf(" ");
}
for(int i=snake.len-1;i>0;i--)//移动蛇身
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}
if(history_key=='w'&&key=='s'){
key='w';
snake.speed-=10; //减速
}
else if(history_key=='s'&&key=='w'){
key='s';
snake.speed-=10; //减速
}
else if(history_key=='a'&&key=='d'){
key='a';
snake.speed-=10;//减速
}
else if(history_key=='d'&&key=='a'){
key='d';
snake.speed-=10;//减速
}
else if(history_key=='w'&&key=='w'||history_key=='s'&&key=='s'||history_key=='a'&&key=='a'||history_key=='d'&&key=='d'){
if(snake.breaker==0){
snake.speed+=10;//加速
snake.breaker = 1;//关闭加速开关
}
}
if(snake.speed >= 270)//速度最大值为270
snake.speed = 270;
switch(key)
{
case 'w':snake.y[0]--;break;
case 'a':snake.x[0]-= 2;break;
case 'd':snake.x[0]+= 2;break;
case 's':snake.y[0]++;break;
}
gotoxy(snake.x[0],snake.y[0]);
printf("■");
snake.flag=1;
}
void Creatfood()
{
if(snake.x[0] == food.x && snake.y[0] == food.y)//只有蛇吃到食物,才能生成新食物
{
snake.flag=0;
snake.len++;
if(snake.speed<=100)snake.speed+=10;
srand((unsigned int) time(NULL));
food.x=(rand()%(width/2-3)+1)*2;//限定食物的x范围不超出围墙,保证food.x为偶数
food.y=rand()%(hight-2)+1;
for(int i = 0; i<snake.len; i++)//如果产生的食物与蛇身重合则重新生成食物
{
if(food.x==snake.x[i]&&food.y==snake.y[i]){
food.x=rand()%(width-6)+2;
food.y=rand()%(hight-2)+1;
i = 0;//重新查找
}
}
gotoxy(food.x,food.y); printf("●");
}
}
bool Gameover()
{
//碰到围墙,结束
if(snake.x[0]==0){
snake.x[0] = width - 4;
}else if(snake.x[0]==width-2){
snake.x[0] = 2;
}
if(snake.y[0]==0){
snake.y[0] = hight-2;
}else if(snake.y[0]==hight-1 ){
snake.y[0] = 1;
}
//蛇身达到最长,结束
if(snake.len==SNAKESIZE) return false;
//头碰到蛇身,结束
for(int i=1;i<snake.len;i++)
{
if(snake.x[0]==snake.x[i]&&snake.y[0]==snake.y[i])
return false;
}
return true;
}
int main()
{
system("mode con cols=60 lines=27");
Map();
hide_cursor();
while(Gameover())
{
Move();
Creatfood();
Sleep(350-snake.speed);//蛇的移动速度
}
return 0;
}