贪吃蛇(简易版)

概要

本文是我想玩所以跟着UP主编写,发现真的好多自己不知道的东西,很多都是自己没用过的类型

其中使用较多的都是windows的API模型。

整体架构流程

简单赘述:

  • 老规矩,搭建hello word 基础框架。
  • 确定游戏窗口大小并进行绘制。
  • 对蛇和果实进行绘画。
  • 对蛇进行移动控制。
  • 进行碰撞处理并刷新果实。
  • 添加得分板。

技术名词解释

一些没用过的函数,类型

  • COORD是Windows API中的坐标结构体类型,表示屏幕坐标。
  • ULONGLONG适合存储文件
  • boolean数据类型 boolean变量存储为8位数值形式,但只能是false或true 且默认值为false.
  • STD_OUTPUT_HANDLE\t标准输出句柄
  • GetStdHandle是一个Windows API函数

技术细节

  • 处理光标:首先先读取命令行现在的 CONSOLE_CURSOR_INFO 结构体信息,需要用到API函数GetConsoleCursorInfo。GetConsoleCursorInfo 需要用到输出句柄,可以通过API函数GetStdHandle获得。\n\n然后改变结构体信息,再使用API函数SetConsoleCursorInfo
  • 隐藏光标:\n\nHANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);\nCONSOLE_CURSOR_INFO cci;\nGetConsoleCursorInfo(hOut,&cci);\ncci.bVisible=false;\nSetConsoleCursorInfo(hOut,&cci);
  • 碰撞检测是降低精度,提高果实碰撞率
  • 移动控制需要进行反向处理,防止掉头
  • 果实需要刷新

小结

附源码如下:

#include<stdio.h>
#include<Windows.h>
#include<conio.h>
#include<time.h>
//窗口
#define WIDTH 90
#define HEIGHT 25
#define TICK 80
#define APPLE_DELAY 10000
//枚举数据
typedef enum
{
	UP,
	DOWN,
	LEFT,
	RIGHT
}Direction;
//初始
int size;
COORD* body;
Direction direction;
COORD apple , tail;
char key;
HANDLE hdl;
ULONGLONG start, apple_event , tick_event , now;
boolean  is_death;
int dx, dy;
//游戏窗口
void draw_wall()
{
	for (int i = 0; i <= HEIGHT; i++)
	{
		for (int j = 0; j <= WIDTH; j++)
		{
			if (i == HEIGHT || i == 0)putchar('=');
			else if (j == WIDTH || j == 0)putchar('=');
			else putchar(' ');
		}
		puts("");
	}
}
//得分
void draw_score()
{
	COORD pos = { WIDTH + 5, HEIGHT / 2 };
	SetConsoleCursorPosition(hdl, pos);
	printf("SCORE:");
}
//果实
void init_apple()
{
	int flag = 1;
	while (flag)
	{
		flag = 0;
		apple.X = rand() % WIDTH;
		apple.Y = rand() % HEIGHT;
		for (int i = 0; i < size; i++)
		{
			if (body[i].X == apple.X && body[i].Y == apple.Y)
			{
				flag = 1;
			}
		}
	}
}
//蛇的初始化
void init_snake()
{
	is_death = FALSE;
	size = 2;
	body[0].X = WIDTH / 2;
	body[0].Y = HEIGHT / 2;
	body[1].X = WIDTH / 2 -1;
	body[1].Y = HEIGHT / 2;
	direction = RIGHT;
	key = 'D';
	dx = 1;
	dy = 0;
}
// 清除
void remove_obj(COORD obj)
{
	SetConsoleCursorPosition(hdl, obj);
	putchar(' ');
}

//苹果刷新
void update_screen()
{
	remove_obj(tail);
	for (int i = 0; i < size; i++)
	{
		SetConsoleCursorPosition(hdl, body[i]);
		if (i == 0)putchar('@');
		else putchar('*');
	}
	SetConsoleCursorPosition(hdl, apple);
	putchar('#');
	COORD pos = { WIDTH + 11, HEIGHT / 2 };
	SetConsoleCursorPosition(hdl, pos);
	printf("%d", size);
}
// 按键检测
void get_direction()
{
	while (_kbhit())
	{
		key = _getch();
		switch (key)
		{
		case 'W':case 'w':case 72:
			if (direction != DOWN)
			{
				direction = UP;
				dx = 0;
				dy = -1;
			}
			break;
		case 'A':case 'a':case 75:
			if (direction != RIGHT)
			{
				direction = LEFT;
				dx = -1;
				dy = 0;
			}
			break;
		case 'S':case 's':case 80:
			if (direction != UP)
			{
				direction = DOWN;
				dx = 0;
				dy = 1;
			}
			break;
		case 'D':case 'd':case 77:
			if (direction != LEFT)
			{
				direction = RIGHT;
				dx = 1;
				dy = 0;
			}
			break;
		}
	}
}
//碰撞检测
void tick()
{
	//判断是否撞墙
	if (body[0].X < 0 || body[0].X >= WIDTH || body[0].Y < 0 || body[0].Y >= HEIGHT)
	{
		is_death = TRUE;
		return;
	}
	//画苹果
	update_screen();
	//按键检测
	get_direction();
	//判断是否撞到自己
	for (int i = 1; i < size; i++)
	{
		if (body[i].X == body[0].X && body[i].Y == body[0].Y)
		{
			is_death = TRUE;
			return;
		}
	}
	//判断是否吃到苹果
	if (apple.X == body[0].X && apple.Y == body[0].Y)
	{
		init_apple();
		size++;
	}
	//更改蛇的位置
	tail = body[size - 1];
	for (int i = size - 1; i > 0; i--)
	{
		body[i] = body[i - 1];
	}
	body[0].X += dx;
	body[0].Y += dy;
}
//主函数
int main()
{
	//初始化:光标
	hdl = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cci = { 1 , 0 };
	SetConsoleCursorInfo(hdl, &cci);
	SetConsoleTitle("SNAKE!!!");
	srand((unsigned)time(NULL));  //随机数种子
	//蛇的初始化,在堆区生成蛇的数组
	body = (COORD*)malloc(sizeof(COORD) * HEIGHT * WIDTH);  //开辟空间
	
	//绘制游戏界面
	draw_wall();
	draw_score();
	//绘制苹果,蛇
	init_snake();
	init_apple();
	//对时间进行初始化
	start = GetTickCount64();
	tick_event = start + TICK;
	apple_event = start + APPLE_DELAY;
	//
	while (1)
	{
		now = GetTickCount64();
		if (now > tick_event)
		{
			tick();
			if (is_death == TRUE)
				break;
			tick_event += TICK;
		}
		if (now > apple_event)
		{
			remove_obj(apple);
			init_apple();
			apple_event += APPLE_DELAY;
		}
	}

	free(body);  //释放空间
	return 0;
}

搞定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Y.易生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值