C语言贪吃蛇详解

news2024/11/18 5:34:54

个人简介:双非大二学生

个人博客:Monodye

今日鸡汤:人生就像一盒巧克力,你永远不知道下一块是什么味的

C语言基础刷题:牛客网在线编程_语法篇_基础语法 (nowcoder.com)

一.贪吃蛇游戏背景

贪吃蛇是久负盛名的游戏,它也和俄罗斯⽅块,扫雷等游戏位列经典游戏的⾏列。
在编程语⾔的教学中,我们以贪吃蛇为例,从设计到代码实现来提升学⽣的编程能⼒和逻辑能⼒。

 二.游戏实现过程

大致分为三个大模块:

  1. GameStart完成游戏的初始化打印
  2. GameRun游戏运行时各个功能的实现
  3. GameEnd游戏结束以后的一些善后工作

 2.1游戏功能

实现基本的功能:
贪吃蛇地图绘制
蛇吃⻝物的功能 (上、下、左、右⽅向键控制蛇的动作)
蛇撞墙死亡
蛇撞⾃⾝死亡
计算得分
蛇⾝加速、减速
暂停游戏

2.2需要掌握的知识

C语⾔函数、枚举、结构体、动态
内存管理、预处理指令、链表、Win32 API等。

三.Win32API

3.1Win32API介绍

      Windows 这个多作业系统除了协调应⽤程序的执⾏、分配内存、管理资源之外, 它同时也是⼀个很⼤ 的服务中⼼,调⽤这个服务中⼼的各种服务(每⼀种服务就是⼀个函数),可以帮应⽤程序达到开启 视窗、描绘图形、使⽤周边设备等⽬的,由于这些函数服务的对象是应⽤程序(Application), 所以便 称之为 Application Programming Interface,简称 API 函数。WIN32 API也就是Microsoft Windows 32位平台的应⽤程序编程接⼝。

3.2控制台程序

     平常我们运⾏起来的⿊框程序其实就是控制台程序 我们可以使⽤cmd命令来设置控制台窗⼝的⻓宽:设置控制台窗⼝的⼤⼩,30⾏,100列
 mode con cols=100 lines=30

也可以通过命令设置控制台窗口的名字

title 贪吃蛇

这些命令我们使用C语言的system便可以实现:

#include <stdio.h>
int main()
{
 //设置控制台窗⼝的⻓宽:设置控制台窗⼝的⼤⼩,30⾏,100列
 system("mode con cols=100 lines=30");
 //设置cmd窗⼝名称
 system("title 贪吃蛇"); 
 return 0;
}

这里我们可以在后面实现的时候加一个getchar(),防止程序运行结束无法确定窗口是否设置成功。

这样就设置好了。

 3.3控制台屏幕上的坐标COORD

COORD 是Windows API中定义的⼀个结构体,表⽰⼀个字符在控制台屏幕上的坐标

typedef struct _COORD {
 SHORT X;
 SHORT Y;
} COORD, *PCOORD;

通过这样一个结构体我们就可以给得到控制台上的坐标了。

这里我们可以设置一个坐标

 COORD pos = { 10, 15 };

 3.4GetStdHandle

GetStdHandle是⼀个Windows API函数。它⽤于从⼀个特定的标准设备(标准输⼊、标准输出或标
准错误)中取得⼀个句柄(⽤来标识不同设备的数值),使⽤这个句柄可以操作设备。

 它就像炒菜的手柄,你想获得API函数的操作权就得有一个可以获得他们的手柄。

举个例子:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

3.5GetConsoleCursorInfo

检索有关指定控制台屏幕缓冲区的光标⼤⼩和可⻅性的信息 ,其实就是获得光标的操作权。

举个例子:

HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息

3.6CONSOLE_CURSOR_INFO

这个结构体,包含有关控制台光标的信息,可以通过它来得到光标的两个参数:可见性,光标所占的百分比,
typedef struct _CONSOLE_CURSOR_INFO {
 DWORD dwSize;
 BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;

 3.7SetConsoleCursorInfo

设置指定控制台屏幕缓冲区的光标的⼤⼩和可⻅性。
举个例子:
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态

3.8 SetConsoleCursorPosition

设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD类型的pos中,调 ⽤SetConsoleCursorPosition函数将光标位置设置到指定的位置。
COORD pos = { 10, 5};
 HANDLE hOutput = NULL;
 //获取标准输出的句柄(⽤来标识不同设备的数值)
 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 //设置标准输出上光标的位置为pos
 SetConsoleCursorPosition(hOutput, pos);

 这里我们可以利用上面讲到的知识,实现一个设置光标位置的函数:

//设置光标的坐标
void SetPos(short x, short y)
{
 COORD pos = { x, y };
 HANDLE hOutput = NULL;
 //获取标准输出的句柄(⽤来标识不同设备的数值)
 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//设置标准输出上光标的位置为pos
 SetConsoleCursorPosition(hOutput, pos);
}

3.9GetAsyncKeyState

 获取按键情况,GetAsyncKeyState的函数原型如下:

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

我们可以将 GetAsyncKeyState的结果与0x1进行&运算这样1代表按键,0代表没按键。

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

四.GameStart 

在这个函数里我们主要完成这样几个功能的实现:

设置控制台的信息,窗口的大小,窗口名

隐藏光标

打印欢迎信息

绘制地图

初始化蛇

创建食物

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();
	//绘制地图
	GetMap();
	//初始化蛇
	InitSnake(ps);
	//创建食物
	CreateFood(ps);
}

这里需要特殊说明一下这里我们打印蛇身的时候使用的是中文符号,可以下载搜狗输入法特殊字符获得,并且,这些中文字符,是普通字符 的二倍大。

五.GameRun

用来实现这样几个功能:

打印欢迎信息PrintfHelpInfo();

按键的实现switch语句

蛇的移动SnakeMove();sleep()一下移动一下

void GameRun(pSnake ps)
{
	PrintfHelpInfo();
	do
	{
		SetPos(62,10);
		printf("总分:%5d\n",ps->Score);
		SetPos(62,11);
		printf("食物的分值:%02d\n",ps->FoodWeight);
		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;
			break;
		}
		else if (KEY_PRESS(VK_SPACE))
		{
			pause();
		}
		else if (KEY_PRESS(VK_F3))
		{
			if (ps->SleepTime >= 80)
			{
				ps->SleepTime -= 30;
				ps->FoodWeight+= 2;
			}
		}
		else if (KEY_PRESS(VK_F4))
		{
			if (ps->FoodWeight > 2)
			{
				ps->SleepTime += 30;
				ps->FoodWeight -= 2;
			}
			
		}
		SnakeMove(ps);
		Sleep(ps->SleepTime);


	} while (ps->status==OK);
	//getchar();

}

这里是GameRun的基本框架,一些具体的函数嵌套,下文会有详细源码。 

 六.GameEnd

这个函数主要用来进行游戏结束时的一些善后工作,

打印退出游戏的信息

逐个销毁创建的贪吃蛇蛇身节点

释放食物节点指针

void GameEnd(pSnake ps)
{
	SetPos(15,12);
	switch (ps->status)
	{
	case ESC:
		printf("主动退出游戏,正常退出\n");
		break;
	case KILL_BY_WALL:
		printf("很遗憾,撞墙了,游戏结束\n");
		break;
	case KILL_BY_SELF:
		printf("很遗憾,咬到自己了,游戏结束了\n");
		break;
	}
	PSnakeNode cur = ps->pSnake;
	PSnakeNode del = NULL;
	while (cur)
	{
		del = cur;
		cur - cur->next;
		free(del);
	}
	free(ps->pFood);
	ps->pFood = NULL;
}

 七.贪吃蛇小项目源码

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"snake.h"

void test()
{
	//创建蛇
	Snake snake = {0};
	GameStart(&snake);
	//GameRun(&snake);
	//GameEnd(&snake);
}
int main()
{
	//修改适配为中文环境
	setlocale(LC_ALL,"");
	test();
	return 0;
}

Snake.h

#define _CRT_SECURE_NO_WARNINGS 1
#include <locale.h>
#include<stdio.h>
#include"stdlib.h"
#include<windows.h>
#include<stdbool.h>
#define KEY_PRESS(VK) ((GetAsyncKeyState(VK) & 0x1) ? 1 : 0)
#define WALL L'□'
#define BODY 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 WelcomeToGame();
void GetMap();
void InitSnake(pSnake ps);
void CreateFood(pSnake ps);
void GameRun(pSnake ps);
void PrintfHelpInfo();
void SnakeMove(pSnake ps);
int NextIsFood(pSnake ps,PSnakeNode pNext);
void EatFood(pSnake ps, PSnakeNode pNext);
void NotFood(pSnake ps, PSnakeNode pNext);
void killByWall(pSnake ps);
void KillBySelf(pSnake ps);
void GameEnd(pSnake ps);






Snake.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"snake.h"
void SetPos(int x,int y)
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { x,y };
	SetConsoleCursorPosition(handle,pos);
	
}
void WelcomeToGame()
{
	SetPos(35,10);
	printf("欢迎来到贪吃蛇小游戏\n");
	SetPos(38,20);
	system("pause");
	system("cls");
	//功能介绍界面
	SetPos(15,10);
	printf("用↑.↓.←.→来控制蛇的移动,F3是加速,F4是减速\n");
	SetPos(15,11);
	printf("加速得到更高的分数\n");
	SetPos(38, 20);
	system("pause");
	system("cls");
}
void GetMap()
{
	//上
	SetPos(0,0);
	int i = 0;
	for ( i = 0;i <= 56; i += 2)
	{
		wprintf(L"%lc", WALL);
		
		
	}

	//下
	SetPos(0,26);
	for (i = 0; i <= 56; i += 2)
	{
		wprintf(L"%lc", WALL);


	}
	//左
	for (i = 1; i <= 25; i ++)
	{
		SetPos(0,i);

		wprintf(L"%lc", WALL);


	}
	//右
	for (i = 1; i <= 25; i++)
	{
		SetPos(56,i);

		wprintf(L"%lc", WALL);


	}
}
void InitSnake(pSnake ps)
{
	PSnakeNode cur = NULL;
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		cur = (PSnakeNode)malloc(sizeof(SnakeNode));
		if (cur == NULL)
		{
			perror("InitSnake malloc!");
			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", BODY);
		cur = cur->next;
	}
	ps->dir = RIGHT;
	ps->FoodWeight = 10;
	ps->pFood = NULL;
	ps->Score = 0;
	ps->SleepTime = 200;
	ps->status = OK;
}

	void CreateFood(pSnake ps)
	{
		int x = 0;
		int y = 0;
	again:
		do
		{
			x = rand() % 53 + 2;
			y = rand() % 24 + 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("CreateFood():malloc");
			return;
		}
		pFood->x=x;
		pFood->y=y;
		ps->pFood = pFood;
		SetPos(x,y);
		wprintf(L"%lc",Food);

	}

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();
	//绘制地图
	GetMap();
	//初始化蛇
	InitSnake(ps);
	//创建食物
	CreateFood(ps);
}
void PrintfHelpInfo()
{
	SetPos(62,15);
	printf("1.不能穿墙,不能咬到自己\n");
	SetPos(62,16);
	printf("用↑.↓.←.→来控制蛇的移动\n");
	SetPos(62,17);
	printf("F3是加速,F4是减速\n");
	SetPos(62,19);
	printf("版权@Monodye\n");

}
void pause()
{
	while (1)
	{
		Sleep(100);
		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;
	}
	else
		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",BODY);
		cur = cur->next;
	}
	ps->Score += ps->FoodWeight;
	free(ps->pFood);
	CreateFood(ps);
}
void NotFood(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",BODY);
		cur = cur->next;
	}
	SetPos(cur->next->x, cur->next->y);
	printf("  ");
	free(cur->next);
	cur->next = NULL;
}
void killByWall(pSnake ps)
{
	if (ps->pSnake->x == 0 ||
		ps->pSnake->x == 56 ||
		ps->pSnake->y == 0 ||
		ps->pSnake->y == 26)
	{
		ps->status = KILL_BY_SELF;
	}
}
void 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;
			return 0;
		}
		cur = cur->next;
	}
}
void SnakeMove(pSnake ps)
{
	PSnakeNode pNext=(PSnakeNode)malloc(sizeof(SnakeNode));
	if (pNext == NULL)
	{
		perror("SnakeMove():malloc()");
		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 {
		NotFood(ps,pNext);
	}
	killByWall(ps);
	KillBySelf(ps);
}
void GameRun(pSnake ps)
{
	PrintfHelpInfo();
	do
	{
		SetPos(62,10);
		printf("总分:%5d\n",ps->Score);
		SetPos(62,11);
		printf("食物的分值:%02d\n",ps->FoodWeight);
		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;
			break;
		}
		else if (KEY_PRESS(VK_SPACE))
		{
			pause();
		}
		else if (KEY_PRESS(VK_F3))
		{
			if (ps->SleepTime >= 80)
			{
				ps->SleepTime -= 30;
				ps->FoodWeight+= 2;
			}
		}
		else if (KEY_PRESS(VK_F4))
		{
			if (ps->FoodWeight > 2)
			{
				ps->SleepTime += 30;
				ps->FoodWeight -= 2;
			}
			
		}
		SnakeMove(ps);
		Sleep(ps->SleepTime);


	} while (ps->status==OK);
	//getchar();

}
void GameEnd(pSnake ps)
{
	SetPos(15,12);
	switch (ps->status)
	{
	case ESC:
		printf("主动退出游戏,正常退出\n");
		break;
	case KILL_BY_WALL:
		printf("很遗憾,撞墙了,游戏结束\n");
		break;
	case KILL_BY_SELF:
		printf("很遗憾,咬到自己了,游戏结束了\n");
		break;
	}
	PSnakeNode cur = ps->pSnake;
	PSnakeNode del = NULL;
	while (cur)
	{
		del = cur;
		cur - cur->next;
		free(del);
	}
	free(ps->pFood);
	ps->pFood = NULL;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

内存对齐的规则

一、为什么要内存对齐 简单来说&#xff0c;就是方便计算机去读写数据。 对齐的地址一般都是 n&#xff08;n 2、4、8&#xff09;的倍数。 (1). 1 个字节的变量&#xff0c;例如 char 类型的变量&#xff0c;放在任意地址的位置上&#xff1b; (2). 2 个字节的变量&#xff0…

IPv4之后直接是IPv6,为何没有IPv5?

网络协议中,我们经常看到IPv4和IPv6,有点人可能会问为啥不提IPv5,是没有还是其他原因?下面我来给大伙普及一下,有不对之处还请指正。 一、什么是IPv4和IPv6 IPv4和IPv6都是互联网协议(Internet Protocol)的版本,用于规定网络设备进行通信时使用的标准格式。IPv4是互联…

京东首页移动端-web实战

设置视口标签以及引入初始化样式 <link rel"stylesheet" href"./css/normalize.css"><link rel"stylesheet" href"./css/index.css"> body常用初始化样式 body {width: 100%;min-width: 320px;max-width: 640px;margin:…

问题:鼻中隔前上部血供主要来自于筛后动脉。( ) #学习方法#其他

问题&#xff1a;鼻中隔前上部血供主要来自于筛后动脉。&#xff08; &#xff09; 对 错 参考答案如图所示

unity 增加系统时间显示、FPS帧率、ms延迟

代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;using UnityEngine;public class Frame : MonoBehaviour {// 记录帧数private int _frame;// 上一次计算帧率的时间private float _lastTime;// 平…

PCIE 参考时钟架构

一、PCIe架构组件 首先先看下PCIE架构组件&#xff0c;下图中主要包括&#xff1a; ROOT COMPLEX (RC) (CPU); PCIE PCI/PCI-X Bridge; PCIE SWITCH; PCIE ENDPOINT (EP) (pcie设备); BUFFER; 各个器件的时钟来源都是由100MHz经过Buffer后提供。一个PCIE树上最多可以有256…

02-Web应用_架构构建_漏洞_HTTP数据包_代理服务器

Web应用_架构构建_漏洞_HTTP数据包_代理服务器 一、网站搭建前置知识1.1 域名1.2、子域名1.3、DNS二、web应用环境架构类三、web应用安全漏洞分类四、web请求返回过程数据包 五、演示案例5.1、架构-Web应用搭建-域名源码解析5.2、请求包-新闻回帖点赞-重放数据包5.3、请求包-移…

09 - python操作Excel

python读取Excel python使用xlrd模块用于读取Excel的数据&#xff0c;支持.xls和.xlsx两种文件格式读取。 使用示例 先安装模块 pip install xlrd 代码 # 导入excel读模块 import xlrd# 获取工作簿对象 wb xlrd.open_workbook(./人员.xls)# 获取所有工作表名 sheet_name…

阿里云服务器多少钱一年?4核16G10M带宽26元/月

2024年2月阿里云服务器租用价格表更新&#xff0c;云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、ECS u1实例2核4G、5M固定带宽、80G ESSD Entry盘优惠价格199元一年&#xff0c;轻量应用服务器2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月、2核…

2024不可不会的StableDiffusion之反向提示词(六)

1. 引言 在之前的文章中&#xff0c;我们先后介绍了Stable Diffusion中的所有关键组件&#xff0c;以及如何根据文本提示词来生成图像的整体流程。在这篇文章中&#xff0c;我将展示如何编辑反向提示词&#xff08; Negative Prompt&#xff09;来控制图像生成功能&#xff0c…

导入jar包的办法,若Maven报日志错误,Cannnot resolve XXXXX.jar

相信很多人在进行涉及到java工程项目&#xff0c;都会遇到很多问题&#xff0c;在pom文件中导入jar包&#xff0c;或许会出现cannot resolve XXXXX的问题&#xff0c;从而会报个别的错误。 接下来我将介绍两种导入jar包的方法 导入jar包&#xff0c;从官网直接下载下来相关的…

5-3、S曲线生成器【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍步进电机S曲线生成器的计算以及使用 一.计算原理 根据上一节内容&#xff0c;已经计算了一条任意S曲线的函数。在步进电机S曲线加减速的控制中&#xff0c;需要的S曲线如图1所示&#xff0c;横…

2024年【高处安装、维护、拆除】最新解析及高处安装、维护、拆除新版试题

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【高处安装、维护、拆除】最新解析及高处安装、维护、拆除新版试题&#xff0c;包含高处安装、维护、拆除最新解析答案和解析及高处安装、维护、拆除新版试题练习。安全生产模拟考试一点通结合国家高处安装、维…

蓝桥杯每日一题-----数位dp练习

题目 链接 参考代码 写了两个&#xff0c;一个是很久以前写的&#xff0c;一个是最近刚写的&#xff0c;很久以前写的时候还不会数位dp所以写了比较详细的注释&#xff0c;这两个代码主要是设置了不同的记忆数组&#xff0c;通过这两个代码可以理解记忆数组设置的灵活性。 im…

ArcGISPro中Python相关命令总结

主要总结conda方面的相关命令 列出当前活动环境中的包 conda list 列出所有 conda 环境 conda env list 克隆环境 克隆以默认的 arcgispro-py3 环境为模版的 my_env 新环境。 conda create --clone arcgispro-py3 --name my_env --pinned 激活环境 activate my_env p…

opensuse安装百度Linux输入法

前言 Linux下有输入法&#xff0c;拼音&#xff0c;百度的都有&#xff0c;但是用起来总感觉不如在windows下与安卓中顺手。 目前搜狗与百度都出了Linux的输入法&#xff0c;但是没有针对OpenSUSE的&#xff0c;只有ubuntu/deepin/UOS的安装包。 本文主要讲的如何把百度Linux输…

如何进行游戏服务器的负载均衡和扩展性设计?

​在进行游戏服务器的负载均衡和扩展性设计时&#xff0c;需要考虑多个方面&#xff0c;以确保服务器的稳定性和可扩展性。以下是一些关键的步骤和考虑因素&#xff1a; 负载均衡的需求分析 在进行负载均衡设计之前&#xff0c;需要深入了解游戏服务器的负载特性和需求。这包括…

记录关于node接收并解析前端上传excel文件formData踩的坑

1.vue2使用插件formidable实现接收文件&#xff0c;首先接口不可以使用任何中间件&#xff0c;否则form.parse()方法不执行。 const express require(express) const multipart require(connect-multiparty); const testController require(../controller/testController)/…

天线阵列车载应用——第1章 介绍 1.1节 汽车工业中的天线阵列:应用和频率范围

1.1 汽车工业中的天线阵列:应用和频率范围 无线通信系统的发展需要新的技术来支持更高质量的通信、新的服务和应用。近年来&#xff0c;汽车无线通信市场得到了极大的扩展。现代汽车使用不同的服务:AM/FM收音机、卫星广播(SDARS)、移动电话通信、数字音频广播(DAB)、远程无钥匙…

Flink面试准备

零. 主要内容 一. Flink 提交 1. Flink怎么提交? Local模式 JobManager 和 TaskManager 共用一个 JVM,只需要jdk支持&#xff0c;单节点运行&#xff0c;主要用来调试。 Standlone模式 Standlone 是Flink自带的一个分布式集群&#xff0c;它不依赖其他的资源调度框架、不依赖y…