C语言——贪吃蛇

一. 游戏效果


贪吃蛇


二. 游戏背景

贪吃蛇是久负盛名的游戏,它也和俄罗斯⽅块,扫雷等游戏位列经典游戏的⾏列。
贪吃蛇起源于1977年的投币式墙壁游戏《Blockade》,后移植到各种平台上。具体如下:
起源。1977年,投币式墙壁游戏生产商Gremlin推出了经典的街机游戏《Blockade》,两名玩家要分别控制角色移动,角色会不停长大,而且走过的地方会变成围栏,谁先碰到围栏或碰到自己的身体就算输。
贪吃蛇最初的版本是像素版本,后来又衍生出3D版本、多人对战版本等2 3。
 

三、游戏开发日志

四、知识准备 

本次实现贪吃蛇会使⽤到的⼀些Win32 API知识,那么就学习⼀下

4.1 Win32 API

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

4.2 控制台程序

平常我们运⾏起来的⿊框程序其实就是控制台程序。
我们可以使⽤cmd命令来设置控制台窗⼝的⻓宽,也可以通过命令设置控制台窗⼝的名字:
设置控制台窗⼝的⼤⼩,30⾏,100列,设置控制台窗⼝的名字。
//控制台窗口设置
system("mode con cols=100 lines=35");
system("title 贪吃蛇");

4.3  控制台屏幕上的坐标COORD

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

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

4.4  GetStdHandle

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

4.5 GetConsoleCursorInfo

检索有关指定控制台屏幕缓冲区的光标⼤⼩和可⻅性的信息
HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息

4.5.1  CONSOLE_CURSOR_INFO

这个结构体,包含有关控制台游标的信息
typedef struct _CONSOLE_CURSOR_INFO {
DWORD dwSize;
BOOL bVisible;
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;
(1) dwSize,由光标填充的字符单元格的百分⽐。 此值介于1到100之间。 光标外观会变化,范围从完全填充单元格到单元底部的⽔平线条。
(2)  bVisible,游标的可⻅性。 如果光标可⻅,则此成员为 TRUE。
CursorInfo.bVisible = false; //隐藏控制台光标

5.6  SetConsoleCursorInfo

设置指定控制台屏幕缓冲区的光标的⼤⼩和可⻅性。

HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态

5.7  SetConsoleCursorPosition

设置指定控制台屏幕缓冲区中的光标位置,我们将想要设置的坐标信息放在COORD类型的pos中,调 ⽤SetConsoleCursorPosition函数将光标位置设置到指定的位置。

COORD pos = { 10, 5};
HANDLE hOutput = NULL;
//获取标准输出的句柄(⽤来标识不同设备的数值)
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//设置标准输出上光标的位置为pos
SetConsoleCursorPosition(hOutput, pos);
温馨提示:

这里我们可以将SetPos:封装⼀个设置光标位置的函数

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

5.8 GetAsyncKeyState

获取按键情况,将键盘上每个键的虚拟键值传递给函数,函数通过返回值来分辨按键的状态。
返回值是short类型,在上⼀次调⽤ GetAsyncKeyState 函数后,如果 返回的16位的short数据中,最⾼位是1,说明按键的状态是按下,如果最⾼是0,说明按键的状态是抬起;如果最低位被置为1则说明,该按键被按过,否则为0。
如果我们要判断⼀个键是否被按过,可以检测GetAsyncKeyState返回值的最低值是否为1.
我们这里定义一个宏:
 #define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )

5.9 宽字符打印

在游戏地图上,我们打印墙体使⽤宽字符:□,打印蛇使⽤宽字符●,打印⻝物使⽤宽字符■
普通的字符是占⼀个字节的,这类宽字符是俩个字节。

5.9.1  setlocale函数

char* setlocale (int category, const char* locale);

setlocale 函数⽤于修改当前地区,可以针对⼀个类项修改,也可以针对所有类项。 setlocale 的第⼀个参数如果是LC_ALL,就会影响所有的类项。

C标准给第⼆个参数仅定义了2种可能取值:"C"和"  "。
在任意程序执⾏开始,都会隐藏式执⾏调⽤:
 setlocale(LC_ALL, "C");

当地区设置为"C"时,库函数按正常⽅式执⾏.

当地区设置为"  "时,这种模式下程序会适应本地环境。⽐如:切换到我们的本地模式后就⽀
持宽字符(汉字)的输出等。
setlocale(LC_ALL, " ");//切换到本地环境

宽字符的打印如下:

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

五、游戏实现

5.1 游戏逻辑主体

#define _CRT_SECURE_NO_WARNINGS
#include"snake.h"
#include<locale.h>
#include<stdio.h>
int main()
{char ch;setlocale(LC_ALL, "");//切换到本地环境,支持宽字符srand((unsigned int)time(NULL));do{Snake snake = { 0 };GameInit(&snake);GameRun(&snake);GameOver(&snake);printf("小垃圾还要再来吗?是:Y,否:N\n");ch = getchar();getchar();} while (ch == 'y' || ch == 'Y');return 0;
}

5.2  游戏初始化实现

#define _CRT_SECURE_NO_WARNINGS
#include"snake.h"#define  WALL  L'□'
#define  BODY  L'●'
#define  FOOD  L'█'
void SetPos(short x, short y)
{COORD pos = { x, y };HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值)hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//设置标准输出上光标的位置为posSetConsoleCursorPosition(hOutput, pos);
}
void  WelcomeToGame()
{SetPos(40, 13);printf("欢迎来到贪吃蛇小游戏");SetPos(42, 22);system("pause");//会显示按任意键继续的信息,按任意键后继续执行下一步system("cls");SetPos(25, 12);printf("↑ . ↓ . ← . → 分别控制蛇的移动, F3为加速,F4为减速\n");SetPos(42, 22);system("pause");//会显示按任意键继续的信息,按任意键后继续执行下一步system("cls");/*getchar();*/}
void CreateMap()
{SetPos(0,0);int i = 0;for(i=0;i<58;i=i+2){wprintf(L"%c", WALL);}SetPos(0, 26);for (i = 0; i < 58; i = i + 2){wprintf(L"%c", WALL);}for (i = 1; i <26; i++){SetPos(0, i);wprintf(L"%c", WALL);}for (i = 1; i < 26; i++){SetPos(56, i);wprintf(L"%c", WALL);}/*getchar();*/
}void InitSnake(Snake* snake)
{//初始化蛇身for (int i = 0; i < 5; i++){SnakeNode* node = (SnakeNode*)malloc(sizeof(SnakeNode));node->x = 24 + 2 * i;node->y = 15;node->next = NULL;if (snake->pSnake== NULL){snake->pSnake= node;}else{node->next = snake->pSnake;snake->pSnake = node;}}SnakeNode* cur = snake->pSnake;while (cur){int x = cur->x;int y = cur->y;SetPos(x, y);wprintf(L"%c", BODY);cur = cur->next;}snake->status = RUN;snake->dir = RIGHT;snake->FoodWeight = 10;snake->pFood = NULL;snake->score = 0;snake->SleepTime = 200;
}
void CreateFood(Snake* snake)
{int x = 0;int y = 0;again:do{x = rand() % 53 + 2;y = rand() % 24 + 1;} while (x % 2 != 0);SnakeNode* cur = snake->pSnake;do{if (x == cur->x && y == cur->y){goto again;}cur = cur->next;} while (cur);SnakeNode* food = (SnakeNode*)malloc(sizeof(SnakeNode));food->x = x;food->y = y;snake->pFood = food;SetPos(x, y);wprintf(L"%c", FOOD);/*getchar();*/}void  GameInit(Snake* snake)
{//控制台窗口设置system("mode con cols=100 lines=35");system("title 贪吃蛇");//隐藏光标HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = false; //隐藏控制台光标SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态//打印欢迎界面WelcomeToGame();//创建地图CreateMap();//初始化贪吃蛇InitSnake(snake);//创建食物CreateFood(snake);
}

5.3 游戏运行实现

void PrintHelpInfo()
{SetPos(60, 13);printf("1. 不能穿墙不能咬到自己\n");SetPos(60, 14);printf("2.↑.↓.←.→分别控制蛇的移动\n");SetPos(60, 15);printf("3. F3为加速,F4为减速\n");SetPos(60, 16);printf("4. ESC-退出,空格-暂停\n");
}void Pause()
{while (1){Sleep(200);if (KEY_PRESS(VK_SPACE) == 1){break;}}}
void EatFood(Snake* snake, SnakeNode* snakenext)
{snakenext->next = snake->pSnake;snake->pSnake = snakenext;SnakeNode* cur = snake->pSnake;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}free(snake->pFood);snake->pFood = NULL;CreateFood(snake);}
void NoEatFood(Snake* snake, SnakeNode* snakenext)
{snakenext->next = snake->pSnake;snake->pSnake = snakenext;SnakeNode* cur = snake->pSnake;while (cur->next->next){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);SetPos(cur->next->x, cur->next->y);printf("  ");free(cur->next);cur->next = NULL;
}void SnakeMove(Snake* snake)
{SnakeNode* snakenext = (SnakeNode*)malloc(sizeof(SnakeNode));if (snake->dir == UP){snakenext->x = snake->pSnake->x;snakenext->y = snake->pSnake->y -1;snakenext->next = NULL;}else if (snake->dir == DOWN){snakenext->x = snake->pSnake->x;snakenext->y = snake->pSnake->y +1;snakenext->next = NULL;}if (snake->dir == LEFT){snakenext->x = snake->pSnake->x-2;snakenext->y = snake->pSnake->y ;snakenext->next = NULL;}if (snake->dir == RIGHT){snakenext->x = snake->pSnake->x + 2;snakenext->y = snake->pSnake->y;snakenext->next = NULL;}//判断下一个节点是否为食物if (snakenext->x == snake->pFood->x && snakenext->y == snake->pFood->y){EatFood(snake,snakenext);//吃食物snake->score += snake->FoodWeight;}else{NoEatFood(snake,snakenext);//不吃食物}//碰撞检测if (snake->pSnake->x == 0 || snake->pSnake->x == 56 || snake->pSnake->y == 0 || snake->pSnake->y == 26){snake->status = KILL_BY_WALL;}SnakeNode* cur = snake->pSnake->next;while (cur){if (cur->x == snake->pSnake->x && cur->y == snake->pSnake->y){snake->status = KILL_BY_SELF;}cur = cur->next;}
}void GameRun(Snake* snake)
{//打印帮助信息PrintHelpInfo();do{SetPos(60, 8);printf("游戏总得分:%5d ", snake->score);SetPos(60, 9);printf("每个食物的分数:%2d ", snake->FoodWeight);if (KEY_PRESS(VK_UP) == 1&&snake->dir!=DOWN){snake->dir = UP;}else if (KEY_PRESS(VK_DOWN) == 1 && snake->dir != UP){snake->dir = DOWN;}else if (KEY_PRESS(VK_RIGHT) == 1 && snake->dir != LEFT){snake->dir = RIGHT;}else if (KEY_PRESS(VK_LEFT) == 1 && snake->dir != RIGHT){snake->dir =LEFT;}else if (KEY_PRESS(VK_F3) == 1){if (snake->SleepTime>=80){snake->SleepTime -= 30;snake->FoodWeight += 2;}}else if (KEY_PRESS(VK_F4) == 1){if (snake->SleepTime<=320){snake->SleepTime += 30;snake->FoodWeight -= 2;}}else if (KEY_PRESS(VK_ESCAPE) == 1){snake->status = OVER;break;}else if (KEY_PRESS(VK_SPACE) == 1){Pause();}SnakeMove(snake);Sleep(snake->SleepTime);//每一帧停0.2s} while (snake->status==RUN);
}

5.4 游戏结束实现

void GameOver(Snake* snake)
{switch (snake->status){case KILL_BY_WALL:SetPos(20, 15);printf("你已经撞墙了,小垃圾!\n");break;case KILL_BY_SELF:SetPos(20, 15);printf("你已经自杀了,小垃圾!\n");break;case  OVER:SetPos(20, 15);printf("你退出游戏了,小垃圾!\n");break;}SetPos(0, 29);}

六、 完整代码

6.1 snake.h

#define _CRT_SECURE_NO_WARNINGS
#include<stdbool.h>
#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<time.h>
#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )
enum direction{UP = 1,  DOWN, LEFT, RIGHT};//蛇的方向
enum game_status{RUN,KILL_BY_WALL,KILL_BY_SELF,OVER};typedef struct  SnakeNode
{int x;int y;struct SnakeNode* next;
}SnakeNode;typedef struct Snake
{SnakeNode* pSnake;//指向贪吃蛇头节点SnakeNode* pFood;//指向食物的节点int  score;int FoodWeight;int SleepTime;enum direction dir;//蛇的方向enum  game_status status;//游戏状态
}Snake;
void  GameInit(Snake*snake);
void  WelcomeToGame();
void CreateMap();
void InitSnake(Snake* snake);
void CreateFood(Snake* snake);
void GameRun(Snake* snake);
void PrintHelpInfo();
void Pause();
void SnakeMove(Snake* snake);void EatFood(Snake* snake,SnakeNode*snakenext);
void NoEatFood(Snake* snake, SnakeNode* snakenext);
void GameOver(Snake* snake);

6.2 snake.c

#define _CRT_SECURE_NO_WARNINGS
#include"snake.h"#define  WALL  L'□'
#define  BODY  L'●'
#define  FOOD  L'█'
void SetPos(short x, short y)
{COORD pos = { x, y };HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值)hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//设置标准输出上光标的位置为posSetConsoleCursorPosition(hOutput, pos);
}
void  WelcomeToGame()
{SetPos(40, 13);printf("欢迎来到贪吃蛇小游戏");SetPos(42, 22);system("pause");//会显示按任意键继续的信息,按任意键后继续执行下一步system("cls");SetPos(25, 12);printf("↑ . ↓ . ← . → 分别控制蛇的移动, F3为加速,F4为减速\n");SetPos(42, 22);system("pause");//会显示按任意键继续的信息,按任意键后继续执行下一步system("cls");/*getchar();*/}
void CreateMap()
{SetPos(0,0);int i = 0;for(i=0;i<58;i=i+2){wprintf(L"%c", WALL);}SetPos(0, 26);for (i = 0; i < 58; i = i + 2){wprintf(L"%c", WALL);}for (i = 1; i <26; i++){SetPos(0, i);wprintf(L"%c", WALL);}for (i = 1; i < 26; i++){SetPos(56, i);wprintf(L"%c", WALL);}/*getchar();*/
}void InitSnake(Snake* snake)
{//初始化蛇身for (int i = 0; i < 5; i++){SnakeNode* node = (SnakeNode*)malloc(sizeof(SnakeNode));node->x = 24 + 2 * i;node->y = 15;node->next = NULL;if (snake->pSnake== NULL){snake->pSnake= node;}else{node->next = snake->pSnake;snake->pSnake = node;}}SnakeNode* cur = snake->pSnake;while (cur){int x = cur->x;int y = cur->y;SetPos(x, y);wprintf(L"%c", BODY);cur = cur->next;}snake->status = RUN;snake->dir = RIGHT;snake->FoodWeight = 10;snake->pFood = NULL;snake->score = 0;snake->SleepTime = 200;
}
void CreateFood(Snake* snake)
{int x = 0;int y = 0;again:do{x = rand() % 53 + 2;y = rand() % 24 + 1;} while (x % 2 != 0);SnakeNode* cur = snake->pSnake;do{if (x == cur->x && y == cur->y){goto again;}cur = cur->next;} while (cur);SnakeNode* food = (SnakeNode*)malloc(sizeof(SnakeNode));food->x = x;food->y = y;snake->pFood = food;SetPos(x, y);wprintf(L"%c", FOOD);/*getchar();*/}void  GameInit(Snake* snake)
{//控制台窗口设置system("mode con cols=100 lines=35");system("title 贪吃蛇");//隐藏光标HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = false; //隐藏控制台光标SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态//打印欢迎界面WelcomeToGame();//创建地图CreateMap();//初始化贪吃蛇InitSnake(snake);//创建食物CreateFood(snake);
}void PrintHelpInfo()
{SetPos(60, 13);printf("1. 不能穿墙不能咬到自己\n");SetPos(60, 14);printf("2.↑.↓.←.→分别控制蛇的移动\n");SetPos(60, 15);printf("3. F3为加速,F4为减速\n");SetPos(60, 16);printf("4. ESC-退出,空格-暂停\n");
}void Pause()
{while (1){Sleep(200);if (KEY_PRESS(VK_SPACE) == 1){break;}}}
void EatFood(Snake* snake, SnakeNode* snakenext)
{snakenext->next = snake->pSnake;snake->pSnake = snakenext;SnakeNode* cur = snake->pSnake;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}free(snake->pFood);snake->pFood = NULL;CreateFood(snake);}
void NoEatFood(Snake* snake, SnakeNode* snakenext)
{snakenext->next = snake->pSnake;snake->pSnake = snakenext;SnakeNode* cur = snake->pSnake;while (cur->next->next){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);SetPos(cur->next->x, cur->next->y);printf("  ");free(cur->next);cur->next = NULL;
}void SnakeMove(Snake* snake)
{SnakeNode* snakenext = (SnakeNode*)malloc(sizeof(SnakeNode));if (snake->dir == UP){snakenext->x = snake->pSnake->x;snakenext->y = snake->pSnake->y -1;snakenext->next = NULL;}else if (snake->dir == DOWN){snakenext->x = snake->pSnake->x;snakenext->y = snake->pSnake->y +1;snakenext->next = NULL;}if (snake->dir == LEFT){snakenext->x = snake->pSnake->x-2;snakenext->y = snake->pSnake->y ;snakenext->next = NULL;}if (snake->dir == RIGHT){snakenext->x = snake->pSnake->x + 2;snakenext->y = snake->pSnake->y;snakenext->next = NULL;}//判断下一个节点是否为食物if (snakenext->x == snake->pFood->x && snakenext->y == snake->pFood->y){EatFood(snake,snakenext);//吃食物snake->score += snake->FoodWeight;}else{NoEatFood(snake,snakenext);//不吃食物}//碰撞检测if (snake->pSnake->x == 0 || snake->pSnake->x == 56 || snake->pSnake->y == 0 || snake->pSnake->y == 26){snake->status = KILL_BY_WALL;}SnakeNode* cur = snake->pSnake->next;while (cur){if (cur->x == snake->pSnake->x && cur->y == snake->pSnake->y){snake->status = KILL_BY_SELF;}cur = cur->next;}
}void GameRun(Snake* snake)
{//打印帮助信息PrintHelpInfo();do{SetPos(60, 8);printf("游戏总得分:%5d ", snake->score);SetPos(60, 9);printf("每个食物的分数:%2d ", snake->FoodWeight);if (KEY_PRESS(VK_UP) == 1&&snake->dir!=DOWN){snake->dir = UP;}else if (KEY_PRESS(VK_DOWN) == 1 && snake->dir != UP){snake->dir = DOWN;}else if (KEY_PRESS(VK_RIGHT) == 1 && snake->dir != LEFT){snake->dir = RIGHT;}else if (KEY_PRESS(VK_LEFT) == 1 && snake->dir != RIGHT){snake->dir =LEFT;}else if (KEY_PRESS(VK_F3) == 1){if (snake->SleepTime>=80){snake->SleepTime -= 30;snake->FoodWeight += 2;}}else if (KEY_PRESS(VK_F4) == 1){if (snake->SleepTime<=320){snake->SleepTime += 30;snake->FoodWeight -= 2;}}else if (KEY_PRESS(VK_ESCAPE) == 1){snake->status = OVER;break;}else if (KEY_PRESS(VK_SPACE) == 1){Pause();}SnakeMove(snake);Sleep(snake->SleepTime);//每一帧停0.2s} while (snake->status==RUN);
}void GameOver(Snake* snake)
{switch (snake->status){case KILL_BY_WALL:SetPos(20, 15);printf("你已经撞墙了,小垃圾!\n");break;case KILL_BY_SELF:SetPos(20, 15);printf("你已经自杀了,小垃圾!\n");break;case  OVER:SetPos(20, 15);printf("你退出游戏了,小垃圾!\n");break;}SetPos(0, 29);}

6.3 text.c

#define _CRT_SECURE_NO_WARNINGS
#include"snake.h"
#include<locale.h>
#include<stdio.h>
int main()
{char ch;setlocale(LC_ALL, "");//切换到本地环境,支持宽字符srand((unsigned int)time(NULL));do{Snake snake = { 0 };GameInit(&snake);GameRun(&snake);GameOver(&snake);printf("小垃圾还要再来吗?是:Y,否:N\n");ch = getchar();getchar();} while (ch == 'y' || ch == 'Y');return 0;
}

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

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

相关文章

KDE Plasma 6 将不支持较旧的桌面小部件

KDE Plasma 6 进行了一些修改&#xff0c;需要小部件作者进行调整。开发人员&#xff0c;移植时间到了&#xff01; KDE Plasma 6 是备受期待的桌面环境版本升级版本。 最近&#xff0c;其发布时间表公布&#xff0c;第一个 Alpha 版本将于 2023 年 11 月 8 日上线&#xff0…

NestJS——基于Node.js 服务器端应用程序的开发框架

文章目录 前言什么是 NestJS&#xff1f; 一、NestJS特性&#xff1f;二、使用步骤Typescript 知识后端开发基本知识新建项目目录结构 前言 Nestjs中文文档 什么是 NestJS&#xff1f; Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架。它利用…

HuggingFace模型头的自定义

在线工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 在本文中我们将介绍如何使HuggingFace的模型适应你的任务&#xff0c;在Pytorch中建立自定义模型头并将其连接到HF模型的主体&#…

如何导出PPT画的图为高清图片?插入到world后不压缩图像的设置方法?

期刊投稿的时候&#xff0c;需要图片保持一定的清晰度数&#xff0c;那么我们怎么才能从PPT中导出符合要求的图片呢&#xff1f; 对于矢量图绘图软件所画的图&#xff0c;直接导出即可。 而PPT导出的图片清晰度在60pi&#xff0c;就很模糊。 整体思路&#xff1a; PPT绘图——…

吃透 Spring 系列—MVC部分

目录 ◆ SpringMVC简介 - SpringMVC概述 - SpringMVC快速入门 - Controller中访问容器中的Bean - SpringMVC关键组件浅析 ◆ SpringMVC的请求处理 - 请求映射路径的配置 - 请求数据的接收 - Javaweb常用对象获取 - 请求静态资源 - 注解驱动 标签 ◆ SpringMV…

Leetcode421. 数组中两个数的最大异或值

Every day a Leetcode 题目来源&#xff1a;421. 数组中两个数的最大异或值 解法1&#xff1a;贪心 位运算 初始化答案 ans 0。从最高位 high_bit 开始枚举 i&#xff0c;也就是 max⁡(nums) 的二进制长度减一。设 newAns ans 2i&#xff0c;看能否从数组 nums 中选两个…

【ATTCK】MITRE Caldera -前瞻规划器

CALDERA是一个由python语言编写的红蓝对抗工具&#xff08;攻击模拟工具&#xff09;。它是MITRE公司发起的一个研究项目&#xff0c;该工具的攻击流程是建立在ATT&CK攻击行为模型和知识库之上的&#xff0c;能够较真实地APT攻击行为模式。 通过CALDERA工具&#xff0c;安全…

深入了解JVM和垃圾回收算法

1.什么是JVM&#xff1f; JVM是Java虚拟机&#xff08;Java Virtual Machine&#xff09;的缩写&#xff0c;是Java程序运行的核心组件。JVM是一个虚拟的计算机&#xff0c;它提供了一个独立的运行环境&#xff0c;可以在不同的操作系统上运行Java程序。 2.如何判断可回收垃圾…

机器学习数据预处理——Word2Vec的使用

引言&#xff1a; Word2Vec 是一种强大的词向量表示方法&#xff0c;通常通过训练神经网络来学习词汇中的词语嵌入。它可以捕捉词语之间的语义关系&#xff0c;对于许多自然语言处理任务&#xff0c;包括情感分析&#xff0c;都表现出色。 代码&#xff1a; 重点代码&#…

C# PaddleInference.PP-HumanSeg 人像分割 替换背景色

效果 项目 VS2022.net4.8OpenCvSharp4Sdcb.PaddleInference 包含4个分割模型 modnet-hrnet_w18 modnet-mobilenetv2 ppmatting-hrnet_w18-human_512 ppmattingv2-stdc1-human_512 代码 using OpenCvSharp; using Sdcb.PaddleInference; using System; using System.Col…

酷开科技智能大屏OS Coolita亮相第134届中国进出口商品交易会

作为中国外贸的“风向标”和“晴雨表”&#xff0c;广交会因其历史长、规模大、商品种类全、到会客商多、成交效果好&#xff0c;被称为“中国第一展”&#xff0c;它见证了中国改革开放的时代大潮与对外贸易的蓬勃发展。 2023年10月15日&#xff0c;第134届中国进出口商品交易…

【Spring Cloud】声明性REST客户端:Feign

Spring Cloud Feign ——fallback 服务降级 1. Feign 简介2. Feign 的基础使用2.1 普通 HTTP 请求2.2 Feign 远程调用上传文件接口 1. Feign 简介 Feign 是一个声明式的 HTTP 客户端&#xff0c;它简化了编写基于 REST 的服务间通信代码的过程。在 Spring Cloud 中&#xff0c…

【论文阅读】PSDF Fusion:用于动态 3D 数据融合和场景重建的概率符号距离函数

【论文阅读】PSDF Fusion&#xff1a;用于动态 3D 数据融合和场景重建的概率符号距离函数 Abstract1 Introduction3 Overview3.1 Hybrid Data Structure3.2 3D Representations3.3 Pipeline 4 PSDF Fusion and Surface Reconstruction4.1 PSDF Fusion4.2 Inlier Ratio Evaluati…

AI爆文变现脚本:易用且免费的自动写作脚本更新了

之前给大家分享的AI爆文变现写作脚本 由于时间仓促&#xff0c;加上我对很多东西不熟悉 免费版本对新手小白来说&#xff0c;安装部署起来是非常的困难 于是这几天我加班加点把整个软件的部署简化 现在无需复杂的环境配置安装&#xff0c;下载配置下就可以使用了。 免费版…

[工业自动化-16]:西门子S7-15xxx编程 - 软件编程 - 西门子仿真软件PLCSIM

目录 前言&#xff1a; 一、PLCSIM仿真软件 1.1 PLCSIM仿真软件基础版&#xff08;内嵌&#xff09; 1.2 PLCSIM仿真软件与PLCSIM仿真软件高级版的区别&#xff1f; 1.3 PLCSIM使用 前言&#xff1a; PLC集成开发环境是运行在Host主机上&#xff0c;Host主机与PLC可以通过…

音视频基础知识

图像&#xff08;YUV RGB&#xff09; ​​​​​​​​​​​​​​这个讲的比较好 RGB颜色编码 图像显示主要是由像素组成&#xff0c;每个像素点的颜色组成都是采用RGB格式&#xff0c;RGB就是红、绿、蓝&#xff0c;RGB分别取不同的值&#xff0c;展示不同的颜色。 YUV…

二十五、W5100S/W5500+RP2040树莓派Pico<Modebus TCP Server示例>

文章目录 1 前言2 简介2 .1 什么是Modbus TCP&#xff1f;2.2 Modbus TCP指令介绍2.3 请求数据过程2.4 Modbus TCP协议优点2.5 Modbus TCP应用场景 3 WIZnet以太网芯片4 Modbus TCP示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意…

阿里云OSS和腾讯云COS对象存储介绍和简单使用

对象存储指的是一种云存储服务&#xff0c;其主要是将数据以对象的形式存储在云端&#xff0c;并且提供了完全的API调用&#xff0c;这些API包括上传&#xff0c;下载&#xff0c;删除&#xff0c;复制&#xff0c;预览&#xff0c;权限设置等等。OSS对象存储和COS对象存储都是…

设计模式之十一:代理模式

代理可以控制和管理访问。 RMI提供了客户辅助对象和服务辅助对象&#xff0c;为客户辅助对象创建和服务对象相同的方法。RMI的好处在于你不必亲自写任何网络或I/O代码。客户程序调用远程方法就和运行在客户自己本地JVM对对象进行正常方法调用一样。 步骤一&#xff1a;制作远程…

js案例:打地鼠游戏(打灰太狼)

效果预览图 游戏规则 当灰太狼出现的时候鼠标左键点击灰太狼加10分&#xff0c;小灰灰出现的时候鼠标左键点小灰灰击减10分&#xff0c;不点击不减分不加分。 整体思路 1.把获取背景图片中每个地洞的位置&#xff0c;把所有位置放到一个数组中。 2.封装随机数函数&#xff0c;随…