简单贪吃蛇模拟(C语言版本·)

简单贪吃蛇模拟(C语言版本·)

  • 一、所需win32 API知识
  • 二、游戏逻辑实现

一、所需win32 API知识

1.在这儿,直接弱化概念,把在贪吃蛇中用到的API知识说一下!
 1.1用cmd命令来设置控制台窗口的长宽
1
1

  1.2.用title 指令设置控制台窗口的名字
1

#include <stdio.h>
#include <windows.h>
int main()
{
	//设置控制台尺寸
	system("mode con cols=100 cols=30");
	//设置控制台名字
	system("title 贪吃蛇");
	system("pause");
	return 0;
}

 1.3.表示一个字符在控制台屏幕上的坐标COORD

可以设置一个坐标COORD pos = {10,20};

 1.4.GetStdHandle函数介绍!
  *此函数检索指定设备的句柄!(标准输入,标准输出,标准错误)
原型是:HANDLE WINAPI GetStdHandle(
In DWORD nStdHandle
);

1
1

  1.5.GetConsoleCursorInfo
 *检索有关指定控制台屏幕缓冲区的游标大小和游标可见性的信息。
BOOL WINAPI GetConsoleCursorInfo(
In HANDLE hConsoleOutput,
Out PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
);


1

  *参数作用: dwSize:由光标填充的字符单元格的百分⽐。 此值介于1到100之间。 光标外观会变化,范围从完全填充单元格到单元底部的⽔平线条!
  bVisible:游标的可⻅性。 如果光标可⻅,则此成员为TRUE

 1.6.SetConsoleCursorInfo
BOOL WINAPI SetConsoleCursorInfo(
In HANDLE hConsoleOutput,
In const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);

1
1
 1.7.SetConsoleCursorPosition
BOOL WINAPI SetConsoleCursorPosition(
In HANDLE hConsoleOutput,
In COORD dwCursorPosition
);
设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD类型的pos中,调⽤SetConsoleCursorPosition函数将光标位置设置到指定的位置

//设置一个函数,用于定位位置
void SetPos(short x, short y)
{ 
	COORD  pos = { x,y };
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	//设置位置
	SetConsoleCursorPosition(handle, pos);
}

 1.8.GetAsyncKeyState
SHORT GetAsyncKeyState(
[in] int vKey
);
将键盘上每个键的虚拟键值传递给函数,函数通过返回值来分辨按键的状态。GetAsyncKeyState 的返回值是short类型,在上⼀次调⽤ GetAsyncKeyState 函数后,如果返回的16位的short数据中,最⾼位是1,说明按键的状态是按下,如果最⾼是0,说明按键的状态是抬起;如果最低位被置为1则说明,该按键被按过,否则为0。
如果我们要判断⼀个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1.

  要判断一个键盘上的键是否按过,要看GetAsyncKeyState返回值的最低位是否是1,如果最低位是1,则表示按键按过,做出相应的操作,如果最低位是0,则表示按键没按过,不执行任何操作!

#define KEY_PRESS(VK)  ((GetAsyncKeyState(VK) & 0x1)? 1:0)
int main()
{
	//按键控制模块
	while (1)
	{
		if (KEY_PRESS(VK_NUMPAD0))
		{
			printf("0\n");
		}
		else if (KEY_PRESS(VK_NUMPAD1))
		{
			printf("1");
		}
	}

	return 0;
}

  1.9.打印宽字符
宽字符x轴占两格子,Y轴占一个格子

#include <locale.h>
int main() {
	setlocale(LC_ALL, "");
	wchar_t ch1 = L'●';
	wchar_t ch2 = L'★';
	printf("%c%c\n", 'a', 'b');
	wprintf(L"%c\n", ch1);
	wprintf(L"%c\n", ch2);
	return 0;
}

二、游戏逻辑实现

 首先,对于现在的我来说,写这样一个贪吃蛇还是很难的,写这个东西,让我感觉最深刻的是枚举类型的运用,这是一个好东西,还有结构体的运用,能够学到大概一个简答的东西,怎么组织,怎么来写,这是很重要的一点,看整个代码,不是很难,但是如果你自己要组织出来,要写出来还是很难得,特别是枚举的应用!
 1.数据存储结构的设
  首先蛇的每一个节点都要存储,选用链表结构来存储蛇的每一个节点的数据!蛇吃的食物也是一个节点,所以可以直接定义!

typedef struct SnakeNode
{
	//存储坐标信息
	int x;
	int y;
	struct SnakeNode* next;
}SnakeNode,*pSnakeNode;

  蛇的方向和游戏状态可以用枚举类型一一列举,我认为这说的这个游戏设计最好的地方,这个方面跟能让你感受枚举的作用!!!

enum DIRECTION
{
	UP = 1,
	DOWN,
	LEFT,
	LEFT
};

enum GAME_STATE
{
	OK = 1,//正常运行
	ESC,//按ESC退出游戏
	KILL_BY_WALL,//撞墙死亡退出游戏
	KILL_BY_SELF //撞自己死亡退出游戏
};

  这儿再说一下,枚举这样写,也看不出来,有什么作用,但是到后面设计的时候有奇效!!!
  下面来定义一个结构体存放整个贪吃蛇游戏中所用到的所有信息!!!

struct Snake
{
	//定义蛇头
	pSnakeNode pSnake;
	//定义食物
	pSnakeNode pFood;
	//方向 
	DIRECTION Direction;
	//状态
	GAME_STATE GameState;
	//获得的总分
	int Score;
	//食物的分数
	int FoodWeight;
	//睡眠时间
	//决定贪吃蛇速度的快慢
	int SleepTime;
};

2整个思路设计
1
3.游戏逻辑实现

//先写测试代码,Test.c
void test()
{
	//创建贪吃蛇
	int ch = 0;
	do
	{
		Snake snake = { 0 };
		GameStart(&snake);
		GameRun(&snake);
		GameEnd(&snake);
		SetPos(20, 15);
		printf("再来一局吗?(Y/N):");
		ch = getchar();
		getchar();//清理\n
	} while (ch == 'Y'||ch == 'y');
}
int main()
{
	//修改适配本地中文环境
	srand((unsigned int)time(NULL));
	setlocale(LC_ALL, "");
	//测试贪吃蛇
	test();
	SetPos(0, 28);
	return 0;
}
//写Snake.c文件,各个逻辑的写法,时间不够,详细不说了
#include "Snake.h"

//设置光标位置的函数

void SetPos(short x, short y)
{
	COORD pos = {x,y};
	HANDLE houtput = NULL;
	houtput = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(houtput, pos);
}
void WelcomeToGame()
{
	//欢迎信息
	SetPos(40, 12);
	printf("欢迎来到贪吃蛇游戏!\n");
	SetPos(41, 18);
	system("pause");
	system("cls");

	//功能介绍信息
	SetPos(29, 12);
	printf("用↑.↓.←.→分别控制蛇的移动,F3为加速,F4为减速\n");
	SetPos(29, 13);
	printf("加速将能得到更高分数!");
	SetPos(29,20);
	system("pause");
	system("cls");
}

void CreatMap()
{
	//上
	SetPos(0, 0);
	for (int i = 0; i <= 56; i += 2)
	{
		wprintf(L"%lc", WALL);
	}
	//SetPos(57, 0);
	//printf("---->X");
	//wprintf(L"%lc", L'┉');
	//wprintf(L"%lc", L'▶');
	//下
	SetPos(0, 26);
	for (int i = 0; i <= 56; i += 2)
	{
		wprintf(L"%lc", WALL);
	}
	//左
	SetPos(0, 1);
	for (int i = 1; i <= 25; i++)
	{
		wprintf(L"%lc\n", WALL);
	}
	//SetPos(0, 27);
	//wprintf(L"%lc\n", L'┋');
	//wprintf(L"%lc", L'▼'); 
	//printf("Y");
	//右
	SetPos(56, 1);
	for (int i = 1; i <= 25; i++)
	{
		wprintf(L"%lc\n", WALL);
		SetPos(56, 1 + i);
	}
}

void InitSnake(pSnake ps)
{
	//创建5个蛇身节点
	pSnakeNode cur = NULL;
	for (int i = 0; i < 5; i++)
	{
		cur = (pSnakeNode)malloc(sizeof(SnakeNode));
		if (cur == NULL)
		{
			perror("InitSnake malloc fail!");
			return;
		}
		//申请成功
		cur->x = POS_X + 2 * i;
		cur->y = POS_Y;
		cur->next = NULL;
		//头插
		if (ps->pSnake == NULL)
		{
			ps->pSnake = cur;
		}
		else
		{
			cur->next = ps->pSnake;
			ps->pSnake = cur;
		}
	}

	//打印蛇身
	cur = ps->pSnake;
	while (cur)
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BOOY);
		cur = cur->next;
	}

	//贪吃蛇其它信息初始化
	ps->dir = RIGHT;
	ps->FoodWeight = 10;
	ps->pFood = NULL;
	ps->Score = 0;
	ps->SleepTime = 400; //ms
	ps->status = OK;
}

void CreatFood(pSnake ps)
{
	int x = 0;
	int y = 0;
	//处理随机生成的坐标,不能在墙外面,x必须是2的倍数
again:
	do {
		x = rand() % 53 + 2;
		y = rand() % 25 + 1;
	} while (x % 2!=0);

	//食物不能是蛇的节点
	pSnakeNode cur = ps->pSnake;
	while (cur)
	{
		if ((x == cur->x) && (y == cur->y))
		{
			goto again;
		}
		cur = cur->next;
	}
	//创建食物
	pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (pFood == NULL)
	{
		perror("CreatFood malloc fail!");
		return;
	}
	pFood->x = x;
	pFood->y = y;
	pFood->next = NULL;
	ps->pFood = pFood;
	SetPos(x, y);
	wprintf(L"%lc", FOOD);
}
void PrintHelpInfo()
{
	SetPos(62, 15);
	printf("1.不能穿墙,不能咬到自己");
	SetPos(62, 16);
	printf("2.用↑.↓.←.→分别控制蛇的移动");
	SetPos(62, 17);
	printf("  F3为加速,F4为减速");
	SetPos(62, 18);
}

void pause()
{
	//
	while (1)
	{
		Sleep(200);
		//如果按键按下,跳出循环
		if (KEY_PRESS(VK_SPACE))
		{
			break;
		}
	}
}
int NextIsFood(pSnake ps, pSnakeNode pnext)
{
	if ((ps->pFood->x == pnext->x) && (ps->pFood->y == pnext->y))
	{
		return 1;
	}
	return 0;
}

void EatFood(pSnake ps, pSnakeNode pnext)
{
	//头插
	pnext->next = ps->pSnake;
	ps->pSnake = pnext;
	//打印蛇身
	pSnakeNode cur = ps->pSnake;
	while (cur)
	{
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BOOY);
		cur = cur->next;
	}
	ps->Score += ps->FoodWeight;
	//释放旧的食物
	free(ps->pFood);
	//创造新的食物
	CreatFood(ps);
}

void NotEatFood(pSnake ps, pSnakeNode pnext)
{
	//头插
	pnext->next = ps->pSnake;
	ps->pSnake = pnext;

	//找到倒数第二个节点
	pSnakeNode cur = ps->pSnake;
	while (cur->next->next)
	{
		//打印感觉有问题
		SetPos(cur->x, cur->y);
		wprintf(L"%lc", BOOY);
		cur = cur->next;
	}
	//打印倒数第二个节点
	SetPos(cur->x, cur->y);
	wprintf(L"%lc", BOOY);
	//最后一个节点
	pSnakeNode tail = cur->next;
	cur->next = NULL;
	//将尾结点的地方打印成空格
	SetPos(tail->x, tail->y);
	printf("  ");
	free(tail);
	tail = NULL;
	//打印蛇身
}
//检测撞墙
KillByWall(pSnake ps)
{
	if ((ps->pSnake->x == 0) || (ps->pSnake->x == 56) ||
		(ps->pSnake->y == 0) || (ps->pSnake->y == 26))
	{
		ps->status = KILL_BY_WALL;
	}
}
//检测撞到自己
KillBySelf(pSnake ps)
{
	pSnakeNode cur = ps->pSnake->next; //从第二个开始遍历
	while (cur)
	{
		if ((cur->x == ps->pSnake->x) &&(cur->y == ps->pSnake->y))
		{
			ps->status = KILL_BY_SELF;
			//结束
			break;
		}
		cur = cur->next;
	}
}
void SnakeMove(pSnake ps)
{
	pSnakeNode pnext = (pSnakeNode)malloc(sizeof(SnakeNode));
	if (pnext == NULL)
	{
		perror("SnakeMove malloc fail");
		return;
	}
	pnext->next = NULL;
	switch (ps->dir)
	{
	case UP:
		pnext->x = ps->pSnake->x;
		pnext->y = ps->pSnake->y - 1;
		break;
	case DOWN:
		pnext->x = ps->pSnake->x;
		pnext->y = ps->pSnake->y + 1;
		break;
	case LEFT:
		pnext->x = ps->pSnake->x-2;
		pnext->y = ps->pSnake->y;
		break;
	case RIGHT:
		pnext->x = ps->pSnake->x+2;
		pnext->y = ps->pSnake->y;
		break;
	}
	//下一个坐标是否是食物
	if (NextIsFood(ps, pnext))
	{
		//是食物就吃掉
		EatFood(ps,pnext);
	}
	else
	{
		//不是食物正常走
		NotEatFood(ps,pnext);
	}
	//检测撞墙
	KillByWall(ps);
	//检测撞到自己
	KillBySelf(ps);
}

void GameStart(pSnake ps)
{
	system("mode con cols=100 lines=30");
	system("title 贪吃蛇");
	//隐藏光标
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO cursorinfo;
	//获取控制台光标信息
	GetConsoleCursorInfo(handle, &cursorinfo);
	cursorinfo.bVisible = false;
	SetConsoleCursorInfo(handle, &cursorinfo);

	//打印欢迎信息
	WelcomeToGame();
	//绘制地图
	CreatMap();
	//初始化蛇
	InitSnake(ps);
	//创建食物
	CreatFood(ps);
}


void GameRun(pSnake ps)
{
	//打印帮助信息
	PrintHelpInfo();
	do
	{
		//do...while循环先进去,打印分数
		//分数
		SetPos(62, 10);
		printf("总分:%5d\n", ps->Score);
		SetPos(62, 11);
		printf("食物的分值:%02d\n", ps->FoodWeight);
		//检测按键
		//上 下 左 右 ESC 空格 F3 F4
		//下面怎么控制按下按键,做出对应的响应的操作
		//它是通过枚举来控制按键对应的操作
		if (KEY_PRESS(VK_UP) && ps->dir != DOWN)
		{
			//按下上键,则方向变为上
			ps->dir = UP;
		}
		else if (KEY_PRESS(VK_DOWN) && ps->dir != UP)
		{
			ps->dir = DOWN;
		}
		else if (KEY_PRESS(VK_LEFT) && ps->dir != RIGHT)
		{
			ps->dir = LEFT;
		}
		else if (KEY_PRESS(VK_RIGHT) && ps->dir != LEFT)
		{
			ps->dir = RIGHT;
		}
		else if (KEY_PRESS(VK_ESCAPE))
		{
			ps->status = ESC;
			//按下ESC做出的响应是跳出这个游戏的循环
			break;  
		}
		else if (KEY_PRESS(VK_SPACE))
		{
			//暂停
			pause();  //暂停和恢复暂停
			//第一次按下空格键,检测到则调用了pause函数
			//程序死循环睡眠
			//再次按下则在pause函数里面响应,跳出死循环,执行其它操作
		}
		else if (KEY_PRESS(VK_F3))
		{
			//还是通过枚举来控制
			if (ps->SleepTime >= 80)
			{
				ps->SleepTime -= 30;
				ps->FoodWeight += 2;
			}
		}
		else if (KEY_PRESS(VK_F4))
		{
			//F4按下对应的响应
			if (ps->FoodWeight > 2)
			{
				ps->SleepTime += 30;
				ps->FoodWeight -= 2;
			}
		}

		//睡眠一下
		//停留一下,执行一下,停留时间的长短由Sleep控制
		Sleep(ps->SleepTime);
		// 走一步
		SnakeMove(ps);
	} while (ps->status == OK);
}

void GameEnd(pSnake ps)
{
	SetPos(25, 12);
	switch (ps->status)
	{
	case ESC:
		printf("主动退出游戏!");
		break;
	case KILL_BY_WALL:
		printf("撞墙而死!");
		break;
	case KILL_BY_SELF:
		printf("撞自身而死!");
		break;
	}

	//释放所有申请的节点
	pSnakeNode cur = ps->pSnake;
	while (cur)
	{
		pSnakeNode next = cur->next;
		free(cur);
		cur = next;
	}
	ps->pSnake = NULL;
	free(ps->pFood);
	ps->pFood = NULL;
}
//写Snake.h文件
#pragma once
#include <stdio.h>
#include <locale.h>
#include <windows.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>

#define KEY_PRESS(VK)  ((GetAsyncKeyState(VK) & 0x1)? 1:0)

#define WALL L'□'
#define BOOY L'●'
#define FOOD L'★'
//蛇起始位置
#define POS_X  24
#define POS_Y  5

//控制游戏状态
enum GAME_STATUS
{
	OK = 1,
	ESC, //退出
	KILL_BY_WALL, //撞墙
	KILL_BY_SELF //撞自身
};

//控制方向来用
enum DIRECTION
{
	UP=1,
	DOWN,
	LEFT,
	RIGHT
};

//蛇身节点
typedef struct Snakenode
{
	int x;
	int y;
	struct Snakenode* next;
}SnakeNode,*pSnakeNode;

//维护整个贪吃蛇游戏
typedef struct Snake
{
	pSnakeNode pSnake; //蛇头
	pSnakeNode pFood;  //食物指针
	int Score;   //累计分数
	int FoodWeight; //一个食物分数
	int SleepTime; //蛇休眠的时间,休眠的时间越短,蛇的速度越快,休眠的时间越长,蛇的速度越慢
	enum GAME_STATUS status; //游戏当前状态
	enum DIRECTION dir;  //方向
}Snake,*pSnake;

void GameStart(pSnake ps);
void SetPos(short x, short y);
void WelcomeToGame();
void CreatMap();
void InitSnake(pSnake ps);
void CreatFood(pSnake ps);
void GameRun(pSnake ps);
void PrintHelpInfo();
void SnakeMove(pSnake ps);
int NextIsFood(pSnake ps, pSnakeNode pnext);
void EatFood(pSnake ps, pSnakeNode pnext);
void NotEatFood(pSnake ps, pSnakeNode pnext);
//检测撞墙
KillByWall(pSnake ps);
//检测撞到自己
KillBySelf(pSnake ps);
void GameEnd(pSnake ps);
void SetPos(short x, short y);

完结!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/395582.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python入门----基础

这里写目录标题 重点虚拟环境/与//的区别/// 关于print字符串可以用号拼接单双引号转义符换行三引号 变量变量的定义变量名的命名 API库导库以及使用 注释单行注释多行注释 数据类型strboolNoneTypetype函数 交互模式介绍开启 input作用延伸 if-else条件嵌套语句逻辑运算符内容…

世界顶级名校计算机专业,都在用哪些书当教材?

前言 在当今信息化、数字化时代&#xff0c;计算机科学已成为全球最为热门和重要的学科之一。世界顶级名校的计算机专业&#xff0c;更是培养未来行业领袖和创新人才的重要基地。那么&#xff0c;这些名校的计算机专业究竟使用哪些教材呢&#xff1f;这些教材又具有哪些特色和…

11. Springboot集成Dubbo3(二)示例demo

目录 1、前言 2、注册中心 3、快速开始 3.1、添加dubbo3依赖 3.2、dubbo3-api ​编辑 3.3、dubbo3-server 3.3.1、添加依赖 3.3.2、实现IUserService 3.3.3、添加配置文件application.properties 3.3.4、修改Application启动类 3.3.5、出错解决 3.4、dubbo3-porta…

Golang 更严格的代码格式化工具 gofumpt

一、前言 gofmt 是 golang 自带的代码自动格式化工具&#xff0c;是保证 Go 代码风格一致的大杀器。我们这次要推荐的 gofumpt 在 gofmt 的基础上添加了一系列更加严格的格式化规则&#xff0c;并保证了对 gofmt 的兼容。 二、gofumpt 简介 gofumpt(https://github.com/mvda…

职业性格在求职应聘和跳槽中的作用

性格测试对跳槽者的影响大不大&#xff1f;首先我们要弄清楚两个问题&#xff0c;性格对我们的职业生涯又没有影响&#xff0c;性格测试是什么&#xff0c;职场中有哪些应用&#xff1f;性格可以说从生下来就有了&#xff0c;随着我们的成长&#xff0c;我们的性格也越来越根深…

2024开工大吉,便宜寄快递该怎么选呢?

随着春节的结束&#xff0c;大部分人回到了工作的岗位&#xff0c;相信许多人还沉浸在过年的喜悦的氛围中呢&#xff0c;但是我们可以期盼下一个春节的到来了&#xff0c;言归正传&#xff0c;工作中总会收发快递了&#xff0c;尤其是最近&#xff0c;需要联络客户的感情了&…

串口通信功能介绍和配置

用户GPIO中其实很多IO口可以复用成串口功能&#xff08;可查看复用定义表&#xff09;&#xff0c;但是我们这里按照默认定义所以只对8脚、9脚进行复用测试&#xff0c;引脚定义入下图&#xff1a; 硬件连接 测试串口我们需要一个串口调试工具&#xff0c;可以使用串口烧录工具…

练习题解(关于最短路径)

目录 1.租用游艇 2.邮递员送信 3.【模板】单源最短路径&#xff08;标准版&#xff09; 1.租用游艇 P1359 租用游艇 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 输入数据&#xff1a; 3 5 15 7 因为这道题数据不大&#xff0c;所有我们直接使用Floyd 算法。 这道题大…

解决传统单一模态难题!多模态图学习新SOTA来了!

多模态图学习是一种结合了图神经网络和多模态数据集成的学习方法&#xff0c;它涉及了数据科学、机器学习、图神经网络、多模态分析等多个前沿领域。这种跨学科特性为我们提供了丰富的创新点和探索空间。因此&#xff0c;多模态图学习也是发表高质量论文的好方向。 通过整合和…

BUGKU-WEB 留言板1

题目描述 题目截图如下&#xff1a; 进入场景看看&#xff1a; 解题思路 之间写过一题类似的&#xff0c;所以这题应该是有什么不同的那就按照之前的思路进行测试试试提示说&#xff1a;需要xss平台接收flag&#xff0c;这个和之前说的提示一样 相关工具 xss平台&#xf…

小米4A路由器如何刷OpenWRT并结合内网穿透实现公网远程访问

文章目录 推荐前言1. 安装Python和需要的库2. 使用 OpenWRTInvasion 破解路由器3. 备份当前分区并刷入新的Breed4. 安装cpolar内网穿透4.1 注册账号4.2 下载cpolar客户端4.3 登录cpolar web ui管理界面4.4 创建公网地址 5. 固定公网地址访问 推荐 前些天发现了一个巨牛的人工智…

《汇编语言》- 读书笔记 - 第10章-CALL 和 RET 指令

《汇编语言》- 读书笔记 - 第10章-CALL 和 RET 指令 10.1 ret 和 retf检测点 10.1 10.2 call 指令10.3 依据位移进行转移的 call 指令检测点 10.2 10.4 转移的目的地址在指令中的 call 指令检测点 10.3 10.5 转移地址在寄存器中的 call 指令10.6 转移地址在内存中的 call 指令检…

【shell】2、Makefile

文章目录 一、变量1.1 定义简单变量1.2 定义数组1.3 引用变量1.4 规则中定义变量 一、变量 1.1 定义简单变量 用变量名 值的语法来定义变量。这些变量可以用于存储命令、文件名、目录路径等信息&#xff0c;以便在Makefile规则中重复使用 # 定义一个变量 VAR_NAME value# …

Latent Diffusion Models / Stable Diffusion(LDM)

High-Resolution Image Synthesis with Latent Diffusion Models&#xff08;CVPR 2022&#xff09;https://arxiv.org/abs/2112.10752latent-diffusionstable-diffusion cross-attention&#xff08;用于多模态任务&#xff09; Cross-attention vs Self-attention&#xff…

MC10T1S-10BASE-T1S车载以太网转换器

更多资讯可以查看官网或者联系我们http://www.hdn-vdo.com

Java+Swing+Txt实现通讯录管理系统

目录 一、系统介绍 1.开发环境 2.技术选型 3.功能模块 4.系统功能 1.系统登录 2.查看联系人 3.新增联系人 4.修改联系人 5.删除联系人 5.工程结构 二、系统展示 1.登录页面 2.主页面 3.查看联系人 4.新增联系人 5.修改联系人 三、部分代码 Login FileUtils …

不知如何获取1688工厂档案信息,你还在为此烦恼吗?

阿里巴巴集团旗下的B2B电子商务网站&#xff0c;提供海量优质商品&#xff0c;为采购商和供应商提供交流、合作、采购等服务&#xff0c;是很多没有货源优势的电商卖家首选的货源途径&#xff0c;也是国内最大、货源种类最齐全的货源网站。 不少做跨境电商无货源的朋友都想要1…

SpringBoot源码解读与原理分析(五)SpringBoot的装配机制

文章目录 2.5 Spring Boot的装配机制2.5.1 ComponentScan2.5.1.1 ComponentScan的基本使用方法2.5.1.2 TypeExcludeFilter(类型排除过滤器)2.5.1.3 AutoConfigurationExcludeFilter(自动配置类排除过滤器) 2.5.2 SpringBootConfiguration2.5.3 EnableAutoConfiguration2.5.3.1 …

Vue3中 状态管理器 ( Pinia ) 详解及使用

传送门&#xff1a; Vue中 状态管理器&#xff08;vuex&#xff09;详解及应用场景 传送门&#xff1a;Pinia 中文文档 注意&#xff1a;本文项目使用脚手架为 Vite&#xff1b; 1. 前言 Pinia 对比 Vuex Pinia 同时支持 Vue2 以及 Vue3 &#xff0c;这让同时使用两个版本的…

QT串口通讯上位机_数据超时接收功能及定时发送功能设计

目录 1.概述2.本次内容最终实现3.代码部分4.完整工程文件下载 1.概述 基于《串口开发基础》 在该基础上增加超时时间接收功能&#xff0c;加入定时器循环&#xff1b; 例如&#xff0c;接收数据开始后&#xff0c;在100ms内未接收到任何数据&#xff0c;视作本次数据接收结束&…
最新文章