当前位置: 首页 > news >正文

使用STM32F103ZE开发贪吃蛇游戏

目录

前言

一、设置FreeROTS用户任务

        (1)事件event任务

        (2)按键输入方向控制任务

        (3)果实食物任务

        (4)显示任务函数

        (3)开始任务

二、主函数

三、ADC采样

四、效果展示


前言

        网络上贪吃蛇游戏的开源资料已经很丰富了,但是详细讲解代码的很少,所以我打算取之开源,回馈于开源,帮助大家能够更好的完成这款很经典的游戏项目。

        为了能够更好的实时处理贪吃蛇的各项任务,如:贪吃蛇任务,果实任务,显示任务等;所以对原始代码上了FreeROTS操作系统。

        这里我就不详细介绍FreeROTS操作系统了,以后我会单独出一期FreeROTS的文章,大家想了解的话,有一份《FreeROTS内核使用指南》可以详读。 

         如果大家英语好的话,推荐读英文版,会少一些翻译上的错误。

        实验平台:STM32F103ZE开发板,5个独立按键

独立按键与开发板连接:

KEYUP→F0

KEYDOWN→F1

KEYLEFT→F2

KEYRIGHT→F3

STOP→F4

        贪吃蛇项目概述:

        贪吃蛇也叫“移动的链表”,先将不同任务所需要的参数组成结构体,在用指针不断调用,还得用TFTLCD进行显示,可以参考我以前写过的博客:

学习记录:调用TFTLCD液晶屏_lcd_shownum_Bitter tea seeds的博客-CSDN博客

        废话不多说,代码(分析)来一波。

一、设置FreeROTS用户任务

        一个任务就是一个线程,由于操作系统管理不同的任务,不同的任务分配在不同的内存块中,所以一开始要给不同的任务设置优先级并为他们分配堆栈空间。被挂起的任务被送回堆栈,就绪任务和运行任务从栈中恢复被送入寄存器。

#ifndef __MY_TASK_H
#define __MY_TASK_H	     
#include "FreeRTOS.h"	 
#include "task.h"//用户任务//任务优先级#define EVENT_TASK_PRIO		7//任务堆栈大小	#define EVENT_STK_SIZE 		128//任务句柄TaskHandle_t EVENTTask_Handler;//任务函数void event_task(void *pvParameters);//任务优先级#define KEY_TASK_PRIO		6//任务堆栈大小	#define KEY_STK_SIZE 		128//任务句柄TaskHandle_t KEYTask_Handler;//任务函数void key_task(void *pvParameters);	//任务优先级#define APPLE_TASK_PRIO		5//任务堆栈大小	#define APPLE_STK_SIZE 		128  //任务句柄TaskHandle_t APPLETask_Handler;//任务函数void apple_task(void *pvParameters);//任务优先级#define SNAKE_TASK_PRIO		4//任务堆栈大小	#define SNAKE_STK_SIZE 		128  //任务句柄TaskHandle_t SNAKETask_Handler;//任务函数void snake_task(void *pvParameters);//任务优先级#define DISPLAY_TASK_PRIO		3//任务堆栈大小	#define DISPLAY_STK_SIZE 		128//任务句柄TaskHandle_t DISPLAYTask_Handler;//任务函数void display_task(void *pvParameters);	//任务优先级#define LED_TASK_PRIO		2//任务堆栈大小	#define LED_STK_SIZE 		128//任务句柄TaskHandle_t LEDTask_Handler;//任务函数void led_task(void *pvParameters);	//任务优先级#define START_TASK_PRIO		1//任务堆栈大小	#define START_STK_SIZE 		128  //任务句柄TaskHandle_t StartTask_Handler;//任务函数void start_task(void *pvParameters);#endif  

        (1)事件event任务

        这是最重要的任务,它负责数据处理,所以得等其他任务完成之后,才轮到它来执行,它的优先级最小,首先设置一个死循环,判断游戏是否正常运行,如果正常运行在判断游戏是否暂停,都没有我们则对按键进行检测,根据按键按下的情况对蛇头坐标进行更改,坐标根据TFTLCD分辨率进行设置,更改完蛇头坐标,对蛇尾坐标进行保存,在进行判断,如果坐标和果实坐标相同的话,蛇的长度加1,果实消失,使能食物函数生成食物,使能LCD进行显示,如果游戏结束,则返回游戏结束函数。

        怎么让蛇的移速随着时间的变化越来越快?

我们可以初始化蛇的速度变量为一个定值,然后通过除以蛇的移速设置延时函数,来控制事件任务执行时间的间隔,随着不断调用蛇的移速,定值不断变大,延时函数时间的间隔边长,任务处理的时间间隔变长,显示出来蛇的移速变快。

void event_task(void *pvParameters)
{while(1){if(event.GameSta==ON)//如果游戏正常则继续{if(event.Process==ON)//如果没有暂停则继续{switch(event.Direction)//检测按键情况,根据方向调整蛇头坐标{case UP:{snake.firsty-=1;if(snake.firsty>GAME_YPART-1){snake.firsty=GAME_YPART-1;}}break;case DOWN:{snake.firsty+=1;if(snake.firsty>GAME_YPART-1){snake.firsty=0;}}break;case LEFT:{snake.firstx-=1;if(snake.firstx>GAME_XPART-1){snake.firstx=GAME_XPART-1;}}break;case RIGHT:{snake.firstx+=1;if(snake.firstx>GAME_XPART-1){snake.firstx=0;}}break;}snake.lastx=snake_axis[0].x;//保存下蛇尾坐标snake.lasty=snake_axis[0].y;if(snake.firstx==apple.x&&snake.firsty==apple.y)//如果此时的坐标与食物坐标相同{event.AppleSta=OFF;	//食物被吃掉snake.energybuf+=apple.energy;//蛇的能量加一vTaskResume(APPLETask_Handler);	//使能生成食物函数		}vTaskResume(DISPLAYTask_Handler);	//使能显示函数			}}else GameOver();//如果游戏为结束状态则游戏结束delay_ms(1000/snake.speed);	//按照蛇的速度调整此核心数据处理函数的时间间隔	}
}

        (2)按键输入方向控制任务

        按键任务通过switch判断语句实现,需要注意的是,我们按的方向如果是蛇移动的方向的反方向,是不能响应的,因为蛇不能有两个脑袋吧?🐶然后就是从结构体中用指针调用参数使用。

void key_task(void *pvParameters)
{u8 key;while(1){key=KEY_PLAY_Scan(0);switch(key){case KEY_UP_PRES:{if(event.Direction!=DOWN)event.Direction=UP;}break;case KEY_DOWN_PRES:{if(event.Direction!=UP)event.Direction=DOWN;}break;case KEY_LEFT_PRES:{if(event.Direction!=RIGHT)event.Direction=LEFT;}break;case KEY_RIGHT_PRES:{if(event.Direction!=LEFT)event.Direction=RIGHT;}break;case KEY_PASS_PRES://按下切换暂停/继续状态{event.Process=!event.Process;}break;		}delay_ms(20);//每20ms响应一次}
}

        (3)果实食物任务

        首先,果实的分布是随机的,所以,通过STM32F1自带的一个ADC采样随机获得ADC的值作为果实,将模拟量转换为数字量,如果在上位机上编写的话,可以使用时间戳来作为随机值。

        得到随机果实的坐标之后,我们还要保证食物的坐标不能出现在蛇的身上。蛇的坐标也是通过LCD分辨率来进行设置的。

void apple_task(void *pvParameters)
{u16 flag,i;while(1){flag=1;while(flag){flag=0;apple.x=Get_Rand()%(u16)(GAME_XPART);apple.y=Get_Rand()%(u16)(GAME_YPART);for(i=0;i<snake.length;i++) {if(snake_axis[i].x==apple.x&&snake_axis[i].y==apple.y){flag++;}}}Display(apple.x,apple.y,RED);vTaskSuspend(APPLETask_Handler);	}
}

        (4)显示任务函数

        对此任务,我们首先得知道自己的LCD型号id然后根据自己LCD的型号进行驱动程序的编写。它的任务是显示出来蛇的身子。

        Display显示出蛇头,如果果实坐标与蛇头坐标相同,蛇身长度+1,速度+1,然后更新蛇头坐标,保存蛇尾坐标,期间检查蛇头有没有碰到自己,遍历蛇身坐标是否与蛇头坐标相同,如果碰到了,游戏结束。

void display_task(void *pvParameters)
{u16 i;while(1){Display(snake.firstx,snake.firsty,RED);//显示蛇头if(snake.energybuf==0) {Display(snake.lastx,snake.lasty,WHITE);for(i=0;i<snake.length-1;i++){snake_axis[i].x=snake_axis[i+1].x;snake_axis[i].y=snake_axis[i+1].y;}	}else //如果吃到了食物{snake.energybuf--;snake.length++; 
//			if(snake.length%2==0)snake.speed++;snake.speed++; }	snake_axis[snake.length-1].x=snake.firstx;snake_axis[snake.length-1].y=snake.firsty;for(i=0;i<snake.length-1;i++){if(snake_axis[i].x==snake.firstx&&snake_axis[i].y==snake.firsty){event.GameSta=OFF; }}vTaskSuspend(DISPLAYTask_Handler);}
}

        (3)开始任务

        使用操作系统,线程进入临界区,为了处理临界区的代码,需要关闭线程中断,处理完毕后在开启中断,这是为了避免同时有其他任务或中断服务ISR进入临界区代码。

void start_task(void *pvParameters)
{taskENTER_CRITICAL();           xTaskCreate((TaskFunction_t )snake_task,     	(const char*    )"snake_task",   	(uint16_t       )SNAKE_STK_SIZE, (void*          )NULL,				(UBaseType_t    )SNAKE_TASK_PRIO,	(TaskHandle_t*  )&SNAKETask_Handler);   //创建食物任务xTaskCreate((TaskFunction_t )apple_task,     (const char*    )"apple_task",   (uint16_t       )APPLE_STK_SIZE, (void*          )NULL,(UBaseType_t    )APPLE_TASK_PRIO,(TaskHandle_t*  )&APPLETask_Handler);        //创建事件任务xTaskCreate((TaskFunction_t )event_task,     (const char*    )"event_task",   (uint16_t       )EVENT_STK_SIZE, (void*          )NULL,(UBaseType_t    )EVENT_TASK_PRIO,(TaskHandle_t*  )&EVENTTask_Handler);  //创建显示任务xTaskCreate((TaskFunction_t )display_task,     (const char*    )"display_task",   (uint16_t       )DISPLAY_STK_SIZE, (void*          )NULL,(UBaseType_t    )DISPLAY_TASK_PRIO,(TaskHandle_t*  )&DISPLAYTask_Handler);  //创建闪烁任务xTaskCreate((TaskFunction_t )led_task,     (const char*    )"led_task",   (uint16_t       )LED_STK_SIZE, (void*          )NULL,(UBaseType_t    )LED_TASK_PRIO,(TaskHandle_t*  )&LEDTask_Handler);  //创建输入任务xTaskCreate((TaskFunction_t )key_task,     (const char*    )"key_task",   (uint16_t       )KEY_STK_SIZE, (void*          )NULL,(UBaseType_t    )KEY_TASK_PRIO,(TaskHandle_t*  )&KEYTask_Handler);  vTaskDelete(StartTask_Handler); taskEXIT_CRITICAL();  
}

二、主函数

        操作系统与裸机开发的一个区别就是,少了那个while(1)死循环,改成了任务调度

int main(void){	 delay_init();	    	 	  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 Rand_Adc_Init();uart_init(115200);	LED_Init();			  KEY_PLAY_Init();	LCD_Init();DisplayInit();Snake_Init(&snake);Apple_Init(&apple);Event_Init(&event);xTaskCreate((TaskFunction_t )start_task,           (const char*    )"start_task",         (uint16_t       )START_STK_SIZE,        (void*          )NULL,                 (UBaseType_t    )START_TASK_PRIO,      (TaskHandle_t*  )&StartTask_Handler);          vTaskStartScheduler();        
}

三、ADC采样

ADC几个比较重要的参数:

(1)测量范围:测量范围对于 ADC 来说就好比尺子的量程,ADC 测量范围决定了你外接的设备其信号输出电压范围,不能超过 ADC 的测量范围(比如,STM32系列的 ADC 正常就不能超过3.3V)。

(2)分辨率:假如 ADC 的测量范围为 0-5V,分辨率设置为12位,那么我们能测出来的最小电压就是 5V除以 2 的 12 次方,也就是 5/4096=0.00122V。很明显,分辨率越高,采集到的信号越精确,所以分辨率是衡量 ADC 的一个重要指标。

(3)采样时间:当 ADC 在某时刻采集外部电压信号的时候,此时外部的信号应该保持不变,但实际上外部的信号是不停变化的。所以在 ADC 内部有一个保持电路,保持某一时刻的外部信号,这样 ADC 就可以稳定采集了,保持这个信号的时间就是采样时间。

(4)采样率:也就是在一秒的时间内采集多少次。很明显,采样率越高越好,当采样率不够的时候可能会丢失部分信息,所以 ADC 采样率是衡量 ADC 性能的另一个重要指标

#include "rand.h"//使用ADC产生16位随机数void  Rand_Adc_Init(void)
{ 	ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1	, ENABLE );	  //使能ADC1通道时钟RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M//PA1 作为模拟通道输入引脚                         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;		//模拟输入引脚GPIO_Init(GPIOA, &GPIO_InitStructure);	ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;	//ADC工作模式:ADC1和ADC2工作在独立模式ADC_InitStructure.ADC_ScanConvMode = DISABLE;	//模数转换工作在单通道模式ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;	//模数转换工作在单次转换模式ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;	//转换由软件而不是外部触发启动ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;	//ADC数据右对齐ADC_InitStructure.ADC_NbrOfChannel = 1;	//顺序进行规则转换的ADC通道的数目ADC_Init(ADC1, &ADC_InitStructure);	//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   ADC_Cmd(ADC1, ENABLE);	//使能指定的ADC1ADC_ResetCalibration(ADC1);	//使能复位校准  while(ADC_GetResetCalibrationStatus(ADC1));	//等待复位校准结束ADC_StartCalibration(ADC1);	 //开启AD校准while(ADC_GetCalibrationStatus(ADC1));	 //等待校准结束
}				  
//获得ADC值
//ch:通道值 0~3
u16 Get_Adc(u8 ch)   
{//设置指定ADC的规则组通道,一个序列,采样时间ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_1Cycles5 );	//ADC1,ADC通道,采样时间为239.5周期	  			    ADC_SoftwareStartConvCmd(ADC1, ENABLE);		//使能指定的ADC1的软件转换启动功能	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束return ADC_GetConversionValue(ADC1);	//返回最近一次ADC1规则组的转换结果
}u16 Get_Rand(void)
{u16 randnum=Get_Adc(ADC_Channel_1)&0x0001,i;for(i=0;i<15;i++){randnum<<=1;randnum+=Get_Adc(ADC_Channel_1)&0x0001;}return randnum;
} 	

四、效果展示

STM32精英开发板制作贪吃蛇游戏

相关文章:

使用STM32F103ZE开发贪吃蛇游戏

目录 前言 一、设置FreeROTS用户任务 &#xff08;1&#xff09;事件event任务 &#xff08;2&#xff09;按键输入方向控制任务 &#xff08;3&#xff09;果实食物任务 &#xff08;4&#xff09;显示任务函数 &#xff08;3&#xff09;开始任务 二、主函数 三、ADC采样…...

如何利用Web3D技术打造在线虚拟展览馆

随着Web3D技术的不断发展&#xff0c;越来越多的企业和组织开始将其应用于虚拟展览馆的建设中。虚拟展览馆可以为观众提供高度沉浸式的展览体验&#xff0c;让观众可以随时随地参观各种展览&#xff0c;同时也为展览组织者提供了更多的展示方式和机会。下面将介绍如何利用Web3D…...

第二十三章 opengl之高级OpenGL(实例化)

OpenGL实例化实例化数组绘制小行星带实例化 综合应用。 如果绘制了很多的模型&#xff0c;但是大部分的模型包含同一组顶点数据&#xff0c;只是不同的世界空间变换。 举例&#xff1a;一个全是草的场景&#xff0c;每根草都是一个包含了几个小三角形的模型。需要绘制很多根草…...

C++ String类总结

头文件 #include <string>构造函数 default (1) basic_string();explicit basic_string (const allocator_type& alloc); copy (2) basic_string (const basic_string& str);basic_string (const basic_string& str, const allocator_type& alloc); su…...

内网升级“高效安全”利器!统信软件发布私有化更新管理平台

随着数字化的深度推进&#xff0c;信息安全重要性进一步凸显。建设自主可控的国产操作系统&#xff0c;提升信息安全自主能力&#xff0c;已成为国家重要战略之一。 操作系统安全对计算机系统的整体安全发挥着关键作用&#xff0c;各类客户往往需要在第一时间获取更新与安全补…...

JAVA开发(自研项目的开发与推广)

https://live.csdn.net/v/284629 案例背景&#xff1a; 作为JAVA开发人员&#xff0c;我们可以开发无数多的web项目&#xff0c;电商系统&#xff0c;小程序&#xff0c;H5商城。有时候作为技术研发负责人&#xff0c;项目做成了有时候也需要对内进行内测&#xff0c;对外进行…...

Mysql用户权限分配详解

文章目录MySQL 权限介绍一、Mysql权限级别分析&#xff08;1&#xff09;全局级别&#xff08;1.1&#xff09; USER表的组成结构&#xff08;1.1.1&#xff09; 用户列&#xff08;1.1.2&#xff09; 权限列&#xff08;1.1.3&#xff09; 安全列&#xff08;1.1.4&#xff09…...

【TypeScript 入门】13.枚举类型

枚举类型 枚举类型:定义包含被命名的常量的集合。比如 TypeScript 支持枚举数字、字符两种常量值类型。 使用方式: enum + 枚举名字 + 花括弧包裹被命名了的常量成员: enum Size {S,M,L } const a = Size.M console.log(Size, Size)...

Python科学计算:偏微分方程1

首先&#xff0c;我们来看初边值问题&#xff1a;伯格斯方程&#xff1a;假设函数是定义在上的函数&#xff0c;且满足&#xff1a;右侧第一项表示自对流&#xff0c;第二项则表示扩散&#xff0c;在许多物理过程中&#xff0c;这两种效应占据着主导地位&#xff0c;为了固定一…...

PLS-DA分类的实现(基于sklearn)

目录 简单介绍 代码实现 数据集划分 选择因子个数 模型训练并分类 调用函数 简单介绍 &#xff08;此处取自各处资料&#xff09; PLS-DA既可以用来分类&#xff0c;也可以用来降维&#xff0c;与PCA不同的是&#xff0c;PCA是无监督的&#xff0c;PLS-DA是有监督的…...

常用hook

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。理解&#xff1a;hook是react提供的函数API官方提供的hook基础hookuseState APIconst [state, setState] useState(initialState); //返回state值 以及更新state的方法 …...

TryHackMe-GoldenEye(boot2root)

GoldenEye 这个房间将是一个有指导的挑战&#xff0c;以破解詹姆斯邦德风格的盒子并获得根。 端口扫描 循例nmap Web枚举 进入80 查看terminal.js 拿去cyberchef解码 拿着这组凭据到/sev-home登录 高清星际大战 POP3枚举 使用刚刚的凭据尝试登录pop3 使用hydra尝试爆破 这…...

Elasticsearch基本安全加上安全的 HTTPS 流量

基本安全加上安全的 HTTPS 流量 在生产环境中&#xff0c;除非您在 HTTP 层启用 TLS&#xff0c;否则某些 Elasticsearch 功能&#xff08;例如令牌和 API 密钥&#xff09;将被禁用。这个额外的安全层确保进出集群的所有通信都是安全的。 当您在模式下运行该elasticsearch-ce…...

C语言-程序环境和预处理(2)

文章目录预处理详解1.预定义符号2.#define2.1#define定义的标识符2.2#define定义宏2.3#define替换规则注意事项&#xff1a;2.4#和###的作用##的作用2.5带副作用的宏参数2.6宏和函数的对比宏的优势&#xff1a;宏的劣势&#xff1a;宏和函数的一个对比命名约定3.undef4.条件编译…...

JVM 收集算法 垃圾收集器 元空间 引用

文章目录JVM 收集算法标记-清除算法标记-复制算法标记-整理算法JVM垃圾收集器Serial收集器ParNew收集器Parallel Scavenge /Parallel Old收集器CMS收集器Garbage First(G1)收集器元空间引用强引用软引用弱引用虚引用JVM 收集算法 前面我们了解了整个堆内存实际是以分代收集机制…...

clip精读

开头部分 1. 要点一 从文章题目来看-目的是&#xff1a;使用文本监督得到一个可以迁移的 视觉系统 2.要点二 之前是 fix-ed 的class 有诸多局限性&#xff0c;所以现在用大量不是精细标注的数据来学将更好&#xff0c;利用的语言多样性。——这个方法在 nlp其实广泛的存在&…...

vue 首次加载慢优化

目前使用的是vue2版本 1.路由懒加载&#xff08;实现按需加载&#xff09; component: resolve > require([/views/physicalDetail/index], resolve)2.gzip压缩插件&#xff08;需要运维nginx配合&#xff09; 第一步&#xff0c;下载compression-webpack-plugin cnpm i c…...

WuThreat身份安全云-TVD每日漏洞情报-2023-03-21

漏洞名称:CairoSVG 文件服务器端请求伪造 漏洞级别:严重 漏洞编号:CVE-2023-27586 相关涉及:CairoSVG 在 2.7.0 版本之前 漏洞状态:POC 参考链接:https://tvd.wuthreat.com/#/listDetail?TVD_IDTVD-2023-06718 漏洞名称:WP Meta SEO WordPress 授权不当导致任意重定向 漏洞级…...

【Android -- 开发工具】Xshell 6 安装和使用教程

一、简介 Xshell 其实就是一个远程终端工具&#xff0c;它可以将你的个人电脑和你在远端的机器连接起来&#xff0c;通过向 Xshell 输入命令然后他通过网络将命令传送给远端Linux机器然后远端的Linux机器将其运行结果通过网络传回个人电脑。 二、Xshell 6 的安装 首先&#…...

国民技术RTC备份寄存器RTC_BKP

根据手册资料知道RTC_BKP的地址&#xff0c;代码如下 #include "main.h" #include "usart.h"void USART2_Configuration(void) {USART_InitType USART_InitStructure;GPIO_InitType GPIO_InitStructure;GPIO_InitStruct(&GPIO_InitStructure);RCC_Ena…...

resnet网络特征提取过程可视化

我们在训练图片时&#xff0c;是不是要看看具体提取时的每个特征图提取的样子&#xff0c;找了很多&#xff0c;终于功夫不负有心人&#xff0c;找到了&#xff0c;通过修改的代码&#xff1a; resnet代码&#xff1a; import torch import torch.nn as nn from torchvision…...

FPGA打砖块游戏设计(有上板照片)VHDL

这是一款经典打砖块游戏,我们的努力让它更精致更好玩,我们将它取名为打砖块游戏(Flyball),以下是该系统的一些基本功能:  画面简约而经典,色彩绚丽而活泼,动画流畅  玩家顺序挑战3个不同难度的级别,趣味十足  计分功能,卡通字母数字  4条生命值,由生命条显示…...

【Unity入门】3D物体

【Unity入门】3D物体 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity入门系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;物体移动旋转缩放 &#xff08;1&#xff09;物体移动 在上一篇文章【Unity入门】场景视图操作我们学会了在场景中创建3…...

网络现代化势在必行,VMware 发布软件定义网络 SD-WAN 全新方案

出品 | CSDN云计算 作为计算存储网络基础设施三大件之一&#xff0c;网络一直是 IT 核心技术&#xff0c;并不断向前发展。 数字化转型浪潮下&#xff0c;各行业都在探索创新应用&#xff0c;而数字化创新&#xff0c;也是对 5G 和云边端等网络基础设施提出更高需求&#xff0c…...

java学习笔记——抽象类

2.1 概述 由来 父类中的方法&#xff0c;被他的子类们重写&#xff0c;子类各自的实现都不尽相同。那么父类的方法声明和方法主体&#xff0c;只有声明还有意义&#xff0c;而方法主体则没有存在的意义了。我们把没有主体的方法称为抽象方法。java语法规定&#xff0c;包含抽象…...

Redis删除策略

删除策略就是针对已过期数据的处理策略。 针对过期数据要进行删除的时候都有哪些删除策略呢&#xff1f; 1.定时删除2.惰性删除3.定期删除1、立即删除 当key设置有过期时间&#xff0c;且过期时间到达时&#xff0c;由定时器任务立即执行对键的删除操作。 优点&#xff1a;节…...

【新星计划2023】SQL SERVER (01) -- 基础知识

【新星计划2023】SQL SERVER -- 基础知识1. Introduction1.1 Official Website1.2 Conn Tool2. 基础命令2.1 建库建表2.2 Alter2.3 Drop2.3 Big Data -- Postgres3.Awakening1. Introduction 1.1 Official Website 官方文档&#xff08;小技巧&#xff09; Officail Website: …...

nginx配置详解

一.nginx常用命令1.Windows(1).查看nginx的版本号nginx -v(2).启动nginxstart nginx(3).快速停止或关闭nginxnginx -s stop(4).正常停止或关闭nginxnginx -s quit(5).配置文件nginx.conf修改重装载命令nginx -s reload2.Linux(1).进入 nginx 目录中cd /usr/local/nginx/sbin(2)…...

关于Java中堆和栈的学习

文章目录1.概述1.1 堆1.2 栈2.堆内存2.1 什么是堆内存?2.2堆内存的特点是什么?2.3new对象在堆中如何分配?3.栈内存3.1什么是栈内存?3.2栈内存的特点3.3栈内存的内存分配机制3.4数据共享4.栈与堆的区别4.1差异4.2相同5. 面试题: java堆和栈的区别**申请方式****申请后系统的…...

ORBSLAM3 --- 闭环及地图融合线程

目录 1.闭环及地图合并线程的目的和意义 2.闭环及地图合并流程 3.ORBSLAM3中的闭环与地图融合线程解...