gotoxy光标函数
void gotoxy(int x, int y)
{
// 更新光标位置
COORD pos;
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(hOutput, pos);
// 隐藏光标
CONSOLE_CURSOR_INFO cursor;
cursor.bVisible = FALSE;
cursor.dwSize = sizeof(cursor);
SetConsoleCursorInfo(hOutput, &cursor);
}//以左上角为原点,向右为x轴正方向,向下为y轴正方向
/**********************************************************/
void gotoprint(int x, int y)
{
gotoxy(x, y);
printf("■");
}
/**********************************************************/
void gotodelete(int x, int y)
{
gotoxy(x, y);
printf(" ");
}
正方形宽2高1
main函数
int main()
{
#include<stdio.h>
#include<string.h>
#include<windows.h>
#include<time.h>
#include<conio.h>
#define up 'w'
#define down 's'
#define left 'a'
#define right 'd'
#define false 0
#define true 1
typedef char bool;
void welcome(); // 开始界面
void Finish(); // 结束界面
void creatgraph(); // 围墙打印
void gotoxy(int x, int y); // 光标跳转,横为X 0,1,2..
void gotoprint(int x, int y); // 跳转打印
void gotodelete(int x, int y);// 跳转删除
void creatfood(); // 食物产生
int ClickControl(); // 获取键盘信号
int Judge(); // 游戏结束判断
void MovingBody(); // 蛇的移动
void Eating(); // 蛇吃到东西后的操作(伸长)
void ChangeBody(int x, int y); // 蛇的坐标变换
/*全局变量 + 预处理:*/
typedef struct Snakes
{
int x;
int y;
struct Snakes* next;
}snake;//蛇链表
snake* head; // 声明蛇头指针
// 申明并定义食物
struct Food
{
int x;
int y;
}food;//失误结构体
char name[20]; // 保存用户名 有兴趣可以制作登录系统
int score = 0; // 分数
char click = 1; // 记录敲下的键盘按键
int speed; // 速度 其实是延迟的毫秒数
/************************************************************/
system("color 7d"); // 设置控制台字体颜色
welcome(); // 欢迎界面
creatgraph(); // 创建地图
creatfood(); // 新建食物
// 捕获鼠标按键 ClickControl
if (ClickControl() == 0) return 0;
return 0;
}
welcome函数
void welcome()//一系列移动光标打印过程
{
gotoxy(15, 10);
printf("/**********************************************/");
gotoxy(15, 20);
printf("/**********************************************/");
gotoxy(20, 13);
printf("WELCOME TO THE GAME OF RETRO SNAKE");
gotoxy(14, 16);
printf("请在英文输入法中操作,反向移动等同于吃到自己,wasd控制p暂停");
gotoxy(20, 18);
printf("PLEASE ENTER YOUR NAME:");
scanf("%s", &name, 20);
system("cls");
}
围墙函数
void creatgraph() {
int i;
/*
注意这里横坐标是每次+2 因为控制台字符宽高比为1:2
*/
for (i = 0; i < 58; i += 2)//x轴方向
{
gotoprint(i, 0);//上围墙
gotoprint(i, 26);//下围墙
}
for (i = 1; i < 26; i++)
{
gotoprint(0, i);//左围墙
gotoprint(56, i);//右围墙
}
gotoxy(63, 10);
printf("hello %s,Welcome To Play", name);
gotoxy(63, 15);
printf("Your Score Is:%d = ̄ω ̄= ", score);
gotoxy(63, 20);
printf("This Game Is Created By 炫");
head = (snake*)malloc(sizeof(snake));//构建蛇身链条
snake* p = (snake*)malloc(sizeof(snake));
snake* q = (snake*)malloc(sizeof(snake));
head->x = 16;
head->y = 15;
p->x = 16;
p->y = 16;
q->x = 16;
q->y = 17;
head->next = p;
p->next = q;
q->next = NULL;
}
产生随机食物函数
void creatfood()
{
// 随机产生一个食物
bool flag = false;
while (!flag)
{
flag = true;
srand((int)time(NULL));
food.y = rand() % (25 - 1 + 1) + 1;
food.x = rand() % (54 - 2 + 1) + 2;//见上面链接
if (food.x % 2 != 0)//判断横坐标是否为偶数,正方形的宽为2
{
food.x = food.x + 1;
}
snake* judge = head;//赋值judge以蛇头地址
while (1) //遍历排除蛇身重复
{
if (judge->next == NULL) break;//蛇尾结束退出循环
if (food.x == judge->x && food.y == judge->y)
{
flag = false;
}
judge = judge->next;//一节一节地判断
}
}
gotoxy(food.x, food.y);
printf("⊙");
}
吃食物加一个方框
void Eating()
{
if (head->x == food.x && head->y == food.y)
{
creatfood();
snake* _new = (snake*)malloc(sizeof(snake));
snake* p;
p = head;
while (1)
{
if (p->next == NULL) break;
p = p->next;
}//p为蛇尾
p->next = _new;//将吃食物新增的方块加在蛇尾
_new->next = NULL;
score += 10;
gotoxy(77, 15);
printf("%d", score);
}
}
更新蛇体坐标
void ChangeBody(int x, int y)
{
snake* p = head;
while (p->next->next != NULL) {
p = p->next;
}//循环到倒数第二个方块
free(p->next);//释放最后一个方块
p->next = NULL;//赋值最后一个方块的next为NULL
snake* new_head = (snake*)malloc(sizeof(snake));//新建内存作为新的蛇头
new_head->x = x;
new_head->y = y;
new_head->next = head;//将旧的蛇头接到新头上
head = new_head;//将全新的蛇的首地址重新赋值给head
}
判断是否游戏结束
int Judge()
{
if (head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)
{
Finish();
return 0;
}//如果碰到墙则结束游戏
snake* p = head->next;//蛇头后面那一个方块
while (1)
{
if (p == NULL) break;
if (head->x == p->x && head->y == p->y)//蛇头如果碰到自己的蛇身
{
Finish();
return 0;
}
p = p->next;//每一节蛇身判断是否碰到
}
return 1;
}
click函数检测输入的值
int ClickControl()
{
char c;
while (1)
{
if (Judge() == 0) return 0;//如果判断触发结束条件,游戏结束
if (_kbhit())//此函数为非阻塞函数,如果按键按下返回非0值,否则返回0值
{
click = _getch();
}
MovingBody();
Eating();
}
return 1;
}