游戏引擎学习第84天
仓库:https://gitee.com/mrxiao_com/2d_game_2
我们正在试图弄清楚如何完成我们的世界构建
上周做了一些偏离计划的工作,开发了一个小型的背景位图合成工具,这个工具做得还不错,虽然是临时拼凑的,但验证了背景构建的思路。这个过程虽然是一个小插曲,但确实为背景构建提供了一个思路。
另外,不要问为什么屏幕上有这么多浮动的头像,有时候就会出现这些头像。为了避免混淆,现在先把这些头像关闭,恢复到一个浮动的头像,这样更容易处理。
目前的主要任务是完成世界构建,特别是地面部分,以确保我们能够继续推进,标志着 Z 轴的处理已经完成。现在,系统在单一层级上运行良好,但我们已经开始着手实现多层次的功能,这样就可以支持角色走上想象中的楼梯(目前只有矩形表示)。接下来的步骤是实现地面并确保能够正确显示两个层级之间的关系,尤其是在一个层级遮挡另一个层级时能够正确呈现。
我们还没有修改碰撞检测系统来确保角色能够在地面上行走,目前系统只是默认地面在零高度,并且虽然已经标记了地面位置,但并未真正利用这些标记。因此,下一步需要处理的工作就是确保既能绘制地面,又能准确地识别地面的位置,这是当前的关键任务。
思考如何处理地面
目前已经完成了一个能够合成背景中地面的系统,但问题在于,这个地面还没有真正被引入到世界中。它只是在主循环中被调用,所以它只停留在右上角,并没有实际影响游戏世界。因此,下一步的目标是将这个地面纹理实际应用到游戏世界中,让它随着玩家的移动而移动。
为了实现这个目标,可能需要在系统中创建一个实体,这个实体将使用该地面纹理。当这个实体进入视野时,它就会被绘制出来,显示为地面。虽然具体如何实现这一点还没有定下来,但可以先回顾一下当前地面元素的规格,看看是否可以找出一种合理的方法将这个功能整合进现有系统,以避免它成为一个浮动的、独立的部分。
看看我们当前如何指定地面
目前已知系统中有一个“space实体”的概念,它可以描述世界中的space。space实体可以放置在世界中,用来指示玩家能够走动的区域。任何存在space的地方,玩家都可以行走;而space下方没有更多space的地方,则定义为地面。
接下来的问题是如何绘制这些地面区域。是否应当将地面绘制与space实体直接关联,还是将其作为独立的绘制元素来处理,这一点还不确定,考虑起来有些复杂。因此,决定使用黑板来讨论这一想法,以便进一步理清思路。
黑板:我们定义地面的系统
目前系统具有灵活的地面定义方式,使用“空间实体”来定义可行走区域。空间实体并不一定是具体的房间,它们可以是室外区域,表示这是一个可以行走的地方,且底部被视为地面,除非有其他的边界体积重叠。
一种可能的地面定义方式是将地面图像绘制在底部的“平面”上,但这存在问题,尤其是当需要创建更复杂的形状(如挖掘坑洞)时,地面图像的绘制会出现重叠或错误的问题。因此,考虑避免直接存储大规模的地面位图,而是存储重叠的“地面涂抹”信息。通过这种方法,可以从涂抹信息中轻松地重新生成地面纹理,避免存储巨大图像数据集。
此外,考虑到可能存在相邻区域的情况,比如两个房间之间有一个门,或是完全开放的连接区域,平滑滚动时,不希望在边界处出现硬性的接缝。需要确保这些区域的地面涂抹能够无缝连接,形成连续的纹理。
黑板:引擎架构设计的潜在计划和指导原则
目前的设计考虑到如何处理地面涂抹(splat)问题。涂抹不一定需要作为实体存在,因为它们只是用来生成地面纹理,作为实体管理会引入不必要的复杂性。例如,不需要对涂抹进行销毁操作,也不必像实体一样修改它们的属性。涂抹可能只是通过位图覆盖来展示效果,比如显示焦痕,而不会像实体那样进行位置调整。
在架构设计时,需要做出合理的初步判断,并且始终准备好面对可能的错误。在引擎设计中,最重要的是依据游戏实际需求来驱动架构,而不是选择最简单的方案或忽视问题。目标是尽早设想如何使游戏功能有效运行,并通过合理的设置来支持这些需求,确保引擎能够为未来的生产做好准备。
黑板:弄清楚地面的形状
存储涂抹列表的方式可以很简单,基本上可以通过定义一个涂抹区域和涂抹的种类来进行。具体来说,不需要存储所有具体的涂抹内容(如草丛、石头等),而是存储生成这些内容所需的参数。通过这些参数可以重新生成涂抹内容,从而避免存储大量冗余的数据。
更复杂的部分在于确定地面的位置。地面的位置涉及到空间实体,这些空白空间实体定义了可行走的区域,并且需要根据这些空间实体的设置来决定地面的形状。在渲染时,需要知道哪些空间实体与屏幕区域重叠,并根据这些空间实体生成地面。通过将世界划分为多个Z轴层,可以更高效地处理不同层次的地面,并为每个Z轴层单独缓存区域数据。当玩家移动时,可以根据需要重新生成对应的地面区域,而不是一直存储完整的地面数据。
黑板:考虑多个 Z 级别/深度
当处理不同高度的区域时,需要考虑不同的层级和视图。例如,当玩家站在一个平台上,而平台下方有一个悬崖时,地面会被分为不同的Z层,分别表示玩家站立的区域和下方的区域。如果这些区域有不同的Z层高度,那么就需要使用两个独立的缓冲区来处理,而不能将它们合并在同一个缓冲区中。原因在于,不同Z层的区域在渲染时会以不同的速度移动,如果想要实现视差效果,玩家移动时上层区域会比下层区域移动得更快。因此,为了避免合并不同高度的区域,需要为每个层次定义单独的缓存。
为了简化这种处理,可以将空间划分为有限数量的深度层,每个深度层对应一个具体的区域,类似于Z层,但实际上更多是表示层级的深度。例如,深度0层代表玩家站立的位置,深度1层可能表示玩家上方的区域,深度2层可能表示更低的区域。这样,每个层级在渲染时可以独立处理,避免在不同的深度层之间产生混乱。
在进行地面生成时,如果存在空洞或悬崖等结构,则需要特别处理。例如,当区域内有一个坑洞时,需要确保这个空洞部分不会被地面覆盖,而是应该保持透明(Alpha 0),以便显示出下面的部分。生成地面时,可以先填充整个区域的地面,然后再根据空洞的位置将其清除,从而实现挖空区域的效果。
这种方式的关键在于通过填充整个区域并识别空洞,来处理地面的生成。生成的地面可以覆盖整个区域,而空洞部分则通过透明处理去除。这样,地面生成的主要工作就是“雕刻”空洞区域,而不是重新填充整个区域。
黑板:空地物体将会切割出类似的区域
在处理地面生成时,考虑到空洞和悬崖的存在,可以采用一个合理的思路:先将空地区域划分为多个深度层(比如地面、下方区域等),然后根据不同的层次进行划分和处理。对于每个深度层,空地实体(即空洞区域)会根据其最小值的位置被划分到相应的层级中。这意味着,当存在重叠的深度层时,可以根据层次划分来“切割”区域,确保地面和空洞能够正确地显示。
在处理深度剥离(depth peeling)时,当前的做法是通过将实体与相应的深度层进行匹配来决定它们的位置,而不是为每个实体单独生成复杂的几何结构。这避免了使用计算复杂度较高的构造性固体几何(CSG)技术,从而节省了大量不必要的计算工作。这样,虽然实现上有些临时性和简化,但在这种情况下,考虑到操作主要是在几个分层平面上进行的,这种方法仍然是可行的。
因此,考虑到实际需要的复杂度和工作量,将地面区域和深度层进行固定划分并采用简单的处理方式似乎是一个合理的选择,这种方法能够满足大多数场景的需求,并避免了过于复杂的计算和渲染处理。
黑板:该区域的 splats 是什么?
在生成地面区域时,可以采用一种简化的方法,即基于世界坐标生成随机数来决定每个区域的分布。具体来说,可以通过设置一个基于当前位置的随机种子来为每个区域生成“涂抹”效果,而不是存储每个涂抹的具体数据。
例如,在填充一个区域时,可以先定义一个基础分辨率,然后对于每个区域,使用该区域的中心点作为随机种子来生成涂抹效果。接下来,类似于瓦片块系统的工作方式,检查所有可能重叠的区域,生成需要的涂抹效果。这样,涂抹效果只是根据空间位置实时生成,而不需要事先存储所有涂抹的具体信息,这样的方式相对安全且高效。
尝试使地面平面在所有方向上无限滚动
接下来的目标是让地面在所有方向上无限滚动。也就是说,当角色移动时,地面会持续生成,并且始终保持新鲜且不重复的状态。这意味着地面会实时生成,而不是重复使用预先存储的纹理。首先,将通过修改现有的地面生成机制来实现这一目标,并尝试使地面在角色移动时不断生成,以确保无论角色走到哪里,都能有新的地面。
扩大 GroundBuffer,介绍 MaximumZScale 和 GroundOverscan 变量
为了实现地面在所有方向上的无限滚动,首先需要调整现有的地面缓冲区,使其足够大,以便在角色走动时,地面能够扩展并覆盖新的区域。当角色沿着楼梯上升时,地面需要逐渐退到远处,但仍然能够覆盖当前视野区域。因此,地面缓冲区需要有足够的空间,以便地面在深度层次变化时仍能覆盖整个屏幕。
具体实现时,首先通过平台层获得屏幕的宽度和高度,并以此为基础计算缓冲区的大小。接着,考虑到Z轴缩放,当地面随着角色的移动逐渐消失在远处时,地面缓冲区的宽度和高度需要相应增大,以保证能够填充整个屏幕。虽然目前还不确定具体的Z轴缩放因子,但可以通过预设一个缩放比例来为未来的实现做好准备。
此外,为了提高性能,决定引入“过扫描”技术,即在缓冲区的大小上额外增加一些空间,从而减少每一帧更新的次数。这样做有助于在地面滚动时减少计算量,尤其是在后台线程处理中,可以避免每帧都进行完全更新。
最终,地面缓冲区的宽度和高度将根据屏幕尺寸和过扫描比例进行调整,从而确保有足够的空间用于生成新地面并支持角色的移动。
将 GroundBuffer 分区,以便我们可以在其中滚动
在这个过程中,首先需要为地面区域提供足够的空间,以便能够实现滚动。为了达到这一目标,可以通过增加额外的空间来使地面区域能够有效地滚动。接下来,需要将这一区域划分为一个可以更方便使用的结构,以便可以按需进行滚动。此时,必须确保地面区域能够随摄像机一起移动,这是非常重要的功能。
为此,第一步是让地面区域能够随摄像机的运动进行移动。为了实现这一点,摄像机需要以一种合理的方式进行移动。这样可以确保当视角改变时,地面区域的相对位置保持一致,创造出一个连贯的视觉效果。
黑板:当前如何定位 GroundBuffer
在这个过程中,当摄像机移动时,屏幕和缓冲区之间的关系需要特别处理。屏幕展示的是当前视野中的内容,而缓冲区则存储了显示的图像数据。当玩家在某个方向上继续移动时,可能会遇到缓冲区的边界,这时,屏幕上显示的内容就无法继续向该方向滚动。
为了应对这一情况,需要将缓冲区重新居中。具体来说,当玩家继续向某个方向移动并到达缓冲区的边缘时,缓冲区会将已经显示的内容复制到它的起始位置,模拟一个“回弹”的效果。这意味着,当前屏幕上显示的区域将被“传送”到缓冲区的开始位置,同时,缓冲区中的其他内容也会相应地向后移动。这样,就为接下来的地面数据填充腾出了空间,玩家可以继续朝着原来方向前进。
这种操作虽然有效,但在实现时会出现一定的延迟,因为当前的处理过程没有多线程优化,每次重新居中和填充缓冲区时,都会出现短暂的卡顿。这种问题暂时不是优先解决的问题,关键是先让核心功能正常运作,至于如何加快这一过程并通过多线程来优化,计划在后续进行处理。在此之前,尽管会有一定的性能问题,但这是可以接受的,并且会随着开发的推进逐步解决。
确定 GroundBufferP 相对于 CameraP 的位置
为了让地面缓冲区随着摄像机移动,首先需要知道地面缓冲区相对于摄像机的位置。因此,地面缓冲区的初始位置将与摄像机位置重合,然后允许摄像机移动。当摄像机移动到一定距离后,需要将地面缓冲区重新定位,使其与摄像机保持同步。
具体实现时,可以通过屏幕的中心坐标来确定地面缓冲区的位置,结合地面缓冲区的大小进行偏移处理,使得地面缓冲区从屏幕的左上角开始绘制。接着,需要计算摄像机与地面缓冲区的相对位置差异(以某种方式表达为向量),并根据这个差值来调整地面缓冲区的位置。
在此基础上,还需要处理坐标系的转换问题。屏幕坐标是以像素为单位,而地面缓冲区的坐标是以米为单位。因此,必须将米转换为像素,以便正确渲染。
此外,在计算时还会遇到坐标方向上的问题。例如,Y轴的方向在世界坐标系中是向上的,但在屏幕坐标系中可能是相反的。这种问题需要在渲染时进行适当调整。
在实现过程中,可以先将地面缓冲区的位置初始化为摄像机的位置。之后,当摄像机移动时,地面缓冲区的位置会根据摄像机的变化而更新,从而实现地面缓冲区随摄像机的运动同步。
计划在 GroundBuffer 用完像素覆盖时,将其朝摄像机的方向快速移动
当地面缓冲区即将无法覆盖像素时,需要做的是将其位置调整到靠近摄像机的方向。具体来说,当地面缓冲区即将超出屏幕范围时,需要将其位置“吸附”到摄像机的方向,确保它总是能够有效地显示。为此,需要执行一个复制操作,改变地面缓冲区的位置,以便保持其与摄像机视角的对齐。
关闭树木
首先,目标是摆脱当前被树木所限制的情况。因此,暂时关闭生成树木的功能,以便进行测试。接下来,需要清除当前的树木和其他相关物体,以便可以更自由地进行移动和测试。此时,地面测试区域的空间可能不足,因此需要增加空旷区域的大小,确保测试能够顺利进行。可以通过调整“空旷空间添加器”来实现这个目标。为了确保足够的空间,可以将空旷区域做得更大,进一步确保测试的有效性。
关闭 Z 门
通过回到旧的方法,限制生成的内容,确保生成的区域不会出现Z型门。这样在随机选择时,通过指定只生成平坦区域,避免了不必要的复杂性。这使得可以实现之前设想的行走系统,确保了功能的实现,大家都能满意。
另外,之前有一个功能只会生成一个房间,经过调整,停止了这种限制,重新启用了实际的房间生成。这样,房间的生成不再被局限于一个单一房间,而是恢复了更灵活的生成方式。
打开树木
现在可以恢复之前的功能,让生成更多的房间,并确保房间中有更多内容。这样,重新生成的房间变得更加丰富,玩家可以顺利地穿行其中。
接下来,目标是确保这些房间能够填充地面。在进入房间时,必须确保地面始终存在并且被填充。这意味着每当走进一个房间时,都需要确保该区域有稳定的地面支持,保持持续的地面存在。
使地面不断地生成
为了生成填充地面的效果,首先需要智能地生成屏幕内容。在生成这些内容时,不需要复杂的瓦片化处理,操作相对直接。通过使用 DrawTestGround
方法,可以确保填充整个缓冲区。在执行 DrawTestGround
时,关键是要避免使用半径方法,而是要生成一种随机性,能够扩展到缓冲区的边缘。
为了确保生成的地面足够大,并且能够覆盖整个区域,必须在瓦片边界上正确地重新生成种子。这样就能确保每次生成的内容都符合预期,不会出现空白或不连贯的地面区域。
黑板:平铺考虑
在生成地面时,遇到的挑战是当玩家移动到屏幕一侧时,需要复制缓冲区的一部分并将其填充到新的区域。然而,由于不是使用简单的重复瓦片,而是随机生成地面内容,这个过程变得复杂。如果地面内容是重复的瓦片,直接填充就能解决问题,但随机生成的内容涉及更多因素,比如区域内可能有不同的地形特征,生成过程也需要考虑这些因素。
为了保证每次填充相同的区域时能生成一致的内容,必须避免受随机因素的影响。一种解决方案是将地面分割成多个“块”,每个块可以根据固定的参数来生成内容,而不是依赖于动态的随机因素。这样,生成的内容在每次填充时都能保持一致,确保整个地面填充过程的连贯性和稳定性。
将 DrawTestGround 改为 DrawGroundChunk
为了生成地面块,需要通过一个“DrawGroundChunk”绘制方法,将其与缓冲区进行交互。在绘制时,首先需要知道每个块的位置,并确保生成的内容基于相同的初始位置,以确保随机生成的内容每次一致。通过使用块的位置坐标(如块的X、Y、Z值),可以生成一个随机种子,这个种子决定了该区域的内容。
接下来,生成的地面块需要填充指定区域,而不是依赖固定的半径或像素大小。在绘制时,使用随机因素来确定偏移量,确保地面内容覆盖整个区域。通过这种方式,可以摆脱传统的固定尺寸和半径计算,使用整个位图的尺寸作为偏移量来生成地面。最终,生成的地面块会精确覆盖区域,并使用随机值来调整偏移量,以便每次填充的结果都能保持一致。
这些步骤确保了地面生成的灵活性和一致性,但目前的实现还相对简化,代码未完全优化,仍然有改进空间。
问:为什么不填满整个游戏窗口,而是留那么多黑色空间?
在填充整个缓冲区时,尽管目前已经填充了大部分区域,但细节层面尚未达到预期。因此,需要提高填充的细节度,可能需要增加参数值以获得更精细的覆盖。然而,这个问题可以在后续阶段进一步解决。
至于在开发过程中不使用全屏显示,这是为了避免出现绘制错误,因为全屏可能会让问题隐藏在屏幕边缘。开发时,通常会以窗口模式显示游戏内容,而不是全屏,这样更容易检测到潜在的绘制问题。在未来的调试过程中,可能会采用一种居中显示的方式,并且会标出安全区域,确保开发人员能够看到更多的游戏区域,尤其是屏幕之外的部分。
这种显示方式帮助开发者更好地定位和修复问题,而不仅仅是展示玩家视角。全屏显示主要用于最终测试,以确保游戏在实际玩家体验中正常运行。
问:处理多个层级显示时的一些问题,是否源于没有一个 Z 坐标来让摄像机直接进行线性插值?
在处理多层显示时,并不主要由于缺少相机的Z坐标进行插值(lerp)引起问题,因为相机的Z坐标是有的,问题更多是由于没有完整的3D几何体。如果游戏完全采用3D构建,这些问题就不会存在。然而,使用2D游戏时,艺术创作会变得相对简单,单个艺术家就能完成整个2D游戏的制作,而3D游戏则需要更多的人员和资源。
2D游戏虽然在艺术质量上可能有所提升,但程序复杂性相对较低,因为不需要处理复杂的资产管道、预处理和着色器等3D开发中的问题。尽管2D游戏在一些方面简化了开发,但如果要做一些有趣的、复杂的功能,开发仍然会变得更加复杂。
如果想避免解决复杂的编程问题,也可以选择使用单一Z轴水平或者不做平滑的楼梯上升,这也是可以接受的做法。但如果追求更多复杂的编程挑战,采取这些方式就会限制开发的灵活性。通过这个编程流,目的是展示如何超越简单的工具,推动代码开发的边界,做一些在现成工具中无法轻易实现的事情。例如,程序化生成的地面就是一个典型的例子,这种功能可能无法通过简单的现成工具实现,因此展示如何进行这类创新是重点。
问:如果没有人问相关问题,能否大致估算一下添加字体和文本渲染系统何时会变得有用或必要?
添加字体和文本渲染系统的时间框架已经在开发计划中,预计不会太久。虽然目前的工作重点是解决一些更为复杂的问题,这些问题并不直接需要字体显示,但在处理诸如资产流式传输之类的任务时,字体系统将变得非常重要,尤其是在调试时,需要显示调试信息,这时就需要字体系统来支持显示调试文本。此时,可以使用临时的调试字体,而不需要最终的字体设计。
讨论学习 C++
关于学习C++或OpenGL等编程问题,推荐的学习资料并不多,且目前市场上充斥着许多质量不高的教程。尽管如此,还是可以找到一些有用的教程。例如,OpenGL方面,之前有一个名为Arc Synthesis的教程系列,虽然它被认为是一个不错的学习资源,但目前似乎已经无法找到这些教程了。如果这些教程确实消失了,就需要另寻其他合适的学习资源。目前,考虑到开发进度,可能会在将来的直播中涉及一些图形API的内容,若幸运的话,未来也许会用到Vulkan图形API。因此,尽管目前没有明确推荐的OpenGL教程,但Arc Synthesis教程曾经是一个不错的选择。
问:你提到将地面绘制工作转移到单独的线程以防止卡顿。是否有可能将绘制工作分配到多个帧中,并且这比任何一种方法有益吗?
计划将地面绘制的工作分配到单独的线程上,以防止主线程出现卡顿。这种做法的目的是为了利用CPU上的空闲资源,尤其是在2D游戏中,一旦开始使用GPU进行渲染,通常CPU上会有多个核心处于空闲状态。因此,希望将一些生成性工作完全异步地从主线程中分离出来,比如生成或加载数据等。可能会有一个专门用于后台加载和解压的CPU线程,以及另一个用于生成工作的线程,这些线程之间不需要直接关联,而是通过队列进行通信。这种方法将能有效提高性能,尽管目前无法保证最终一定会这样实现,但这是一种可能的优化方案。
问:你的游戏目前使用了多少内存占用?当然它不会很大,但我更想了解有多少不同的容器?
游戏的内存占用目前不会很大,但问题是关于使用了多少种不同的容器。如果能更具体地说明“容器”指的是什么,可以更好地回答这个问题。
问:2D 图形的程序生成:是否有一些主流的数学方法?
程序生成2D图形并没有明确的主流数学公式。虽然其中有一些数学元素,比如噪声模式等,但更多的是一种黑魔法。程序生成2D图形是一个需要不断学习和实践的过程。例如,将会进行更好的地面生成,这将是一个探索这类技术的实际案例。
问:目前已经使用了多少不同的类?
在编程中,并不使用传统的类,而是采用了系统化的方式。例如,使用“模拟区域”(Sim Region)来处理游戏区域的模拟,使用“世界表示”(World Representation)来将世界划分为多个块并允许快速访问。这些“系统”通过结构体来定义数据布局,而不是传统的面向对象的类。系统之间的结构较为宽泛,通常更侧重于整体的系统设计,而非按类划分。
问:有没有一种简单的方式来解释 C++ 中的指针和引用?
在C++中,指针和引用之间的差异实际上并不复杂,它们只是语法上的不同。指针使用*
符号来表示一个指向某个变量的地址,而引用则是某个变量的别名。
-
指针:通过声明一个指针(如
int* x
),我们实际上是在声明一个指向整数的内存地址。这意味着,指针存储的是另一个变量的地址,通过解引用(*x
)可以访问该地址存储的值。指针允许访问和修改它所指向的内存位置。 -
引用:引用则是某个变量的别名。例如,
int& x = y;
表示x
是y
的引用,意味着x
和y
实际上指向相同的内存位置。引用无需解引用操作符(*
),直接当作原变量来使用。引用在语法上看起来更像是直接访问变量,但底层仍然是通过指针来实现的。
在实际使用中,指针和引用在大多数情况下有相同的效果。在函数调用中,无论是通过指针还是引用传递参数,最终都能够修改原始数据。差异在于引用更简洁,语法上更易于理解,而指针则提供了更灵活的操作,例如指针可以为空,而引用则不能。
实际上,指针和引用的实现方式相同,都是指向内存地址,区别在于它们的语法和用法。除非有特定的C++特性要求使用引用,否则指针可以提供更多灵活性,引用则更多用于简化代码。
相关文章:
游戏引擎学习第84天
仓库:https://gitee.com/mrxiao_com/2d_game_2 我们正在试图弄清楚如何完成我们的世界构建 上周做了一些偏离计划的工作,开发了一个小型的背景位图合成工具,这个工具做得还不错,虽然是临时拼凑的,但验证了背景构建的思路。这个过…...
Python----Python高级(文件操作open,os模块对于文件操作,shutil模块 )
一、文件处理 1.1、文件操作的重要性和应用场景 1.1.1、重要性 数据持久化: 文件是存储数据的一种非常基本且重要的方式。通过文件,我们可 以将程序运行时产生的数据永久保存下来,以便将来使用。 跨平台兼容性: 文件是一种通用…...
“AI 大模型内容安全审核软件系统:守护网络世界的卫士
在如今这个信息爆炸的互联网时代,网络上的内容那是五花八门、层出不穷。这时候,咱就得靠 AI 大模型内容安全审核软件系统来给咱把把关了。 咱就说社交媒体平台吧,每天都有海量的用户在上面发布文字、图片、视频啥的。要是没有一个靠谱的审核系…...
快速入门Python的异步库:asyncio
目录 异步 Python asyncio 1. async 关键字 2. await 关键字 3. asyncio.run() 4. asyncio.sleep() 5. 协程 程序执行流程 可以被等待的异步 协程 任务 Futures 任务 asyncio.create_task() await 和任务结果 Reference 异步 我们首先先来谈谈异步,…...
大美祖国-使用Java盘点那些在地名中出现最多的汉字
目录 前言 一、地名数据准备 1、全国地名数据 二、使用Java进行汉字统计 1、汉字数据统计 2、汉字分割统计 三、浅谈地名汉字名次及其意义 1、山、城、江、河 2、安、平、宁 3、地名中的方位 四、总结 前言 在中国这片古老而又年轻的土地上,地名不仅仅是地…...
华为OD机试E卷 --羊、狼、农夫过河--24年OD统一考试(Java JS Python C C++)
文章目录 题目描述输入描述输出描述用例题目解析JS算法源码Java算法源码python算法源码c算法源码c++算法源码题目描述 羊、狼、农夫都在岸边,当羊的数量小于狼的数量时,狼会攻击羊,农夫则会损失羊。农夫有一艘容量固定的船,能够承载固定数量的动物。 要求求出不损失羊情况…...
Java - WebSocket
一、WebSocket 1.1、WebSocket概念 WebSocket是一种协议,用于在Web应用程序和服务器之间建立实时、双向的通信连接。它通过一个单一的TCP连接提供了持久化连接,这使得Web应用程序可以更加实时地传递数据。WebSocket协议最初由W3C开发,并于2…...
JavaWeb开发(十五)实战-生鲜后台管理系统(二)注册、登录、记住密码
1. 生鲜后台管理系统-注册功能 1.1. 注册功能 (1)创建注册RegisterServlet,接收form表单中的参数。 (2)service创建一个userService处理业务逻辑。 (3)RegisterServlet将参数传递给ser…...
【深度学习】利用Java DL4J 训练金融投资组合模型
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程,高并发设计,Springboot和微服务,熟悉Linux,ESXI虚拟化以及云原生Docker和K8s…...
【MySQL篇】事务的认识以及四大特性
何为事务? 事务(Transaction)是指一组操作的集合,这些操作要么全部执行成功,要么全部不执行。事务通常用于保证数据库的一致性、完整性和可靠性,确保数据的完整性与正确性。 有效避免部分执行࿰…...
CSS 网络安全字体
适用于 HTML 和 CSS 的最佳 Web 安全字体 下面列出了适用于 HTM L和 CSS 的最佳 Web 安全字体: Arial (sans-serif)Verdana (sans-serif)Helvetica (sans-serif)Tahoma (sans-serif)Trebuchet MS (sans-serif)Times New Roman (serif)Georgia (serif)Garamond (se…...
实战演示:利用ChatGPT高效撰写论文
在当今学术界,撰写论文是一项必不可少的技能。然而,许多研究人员和学生在写作过程中常常感到困惑和压力。幸运的是,人工智能的快速发展为我们提供了新的工具,其中ChatGPT便是一个优秀的选择。本文将通过易创AI创作平台,…...
显卡(Graphics Processing Unit,GPU)架构详细解读
显卡架构主要分为两大类:GPU 核心架构(也称为图形处理单元架构)和显卡的其他组件(如内存、控制器、输出接口等)。本篇文章将对显卡架构进行详细分析,重点介绍 GPU 核心架构、显卡计算单元、显存结构、显卡管…...
OpenCV相机标定与3D重建(63)校正图像的畸变函数undistort()的使用
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 转换图像以补偿镜头畸变。 该函数通过变换图像来补偿径向和切向镜头畸变。 此函数仅仅是 initUndistortRectifyMap(使用单位矩阵 R…...
人工智能-机器学习之多分类分析(项目实战二-鸢尾花的多分类分析)
Softmax回归听名字,依然好像是做回归任务的算法,但其实它是去做多分类任务的算法。 篮球比赛胜负是二分类,足球比赛胜平负就是多分类 识别手写数字0和1是二分类,识别手写数字0-9就是多分类 Softmax回归算法是一种用于多分类问题…...
【JDBC】数据库连接的艺术:深入解析数据库连接池、Apache-DBUtils与BasicDAO
文章目录 前言🌍 一.连接池❄️1. 传统获取Conntion问题分析❄️2. 数据库连接池❄️3.连接池之C3P0技术🍁3.1关键特性🍁3.2配置选项🍁3.3使用示例 ❄️4. 连接池之Druid技术🍁 4.1主要特性🍁 4.2 配置选项…...
【Envi遥感图像处理】006:影像融合(高光谱+多光谱)的方法
文章目录 一、图像融合概述二、加载数据三、图像融合操作四、结果比对五、高光谱与多光谱一、图像融合概述 图像融合是指将不同类型传感器的影像进行融合,既能使图向具有较高的空间分辨率,又具有多光谱的特性。 二、加载数据 三、图像融合操作 在ENvi中,图像融合使用的工具…...
C语言内存之旅:从静态到动态的跨越
大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 引言正文一 动态内存管理的必要性二 动态…...
Git本地搭建
Git本地搭建 (项目突然不给创建仓库了,为了方便管理项目只能自己本地搭建git服务) 为了在本地搭建Git环境并实现基本的Git操作,步骤如下: 安装Git软件 Windows:从Git官方网站下载并安装适用于Windows…...
电商|基于java的农业电商系统(源码+数据库+文档)
农业电商系统 目录 基于java的农业电商系统 一、前言 二、系统设计 三、系统功能设计 系统功能实现 前台: 后台: 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️…...
c语言分支和循环
文章目录 前言 一、分支结构 if语句 switch语句 三目运算符 二、循环结构 while循环 do-while循环 for循环 循环嵌套 循环控制语句 总结 前言 分支和循环是C语言中非常重要的控制结…...
大象机器人发布首款穿戴式数据采集器myController S570,助力具身智能数据收集!
myController S570 具有较高的数据采集速度和远程控制能力,大大简化了人形机器人的编程。 myController S570 是一款可移动的轻量级外骨骼,具有 14 个关节、2 个操纵杆和 2 个按钮,它提供高数据采集速度,出色的兼容性,…...
【HarmonyOS NEXT】华为分享-碰一碰开发分享
关键词:鸿蒙、碰一碰、systemShare、harmonyShare、Share Kit 华为分享新推出碰一碰分享,支持用户通过手机碰一碰发起跨端分享,可实现传输图片、共享wifi等。我们只需调用系统 api 传入所需参数拉起对应分享卡片模板即可,无需对 U…...
基于python+Django+mysql鲜花水果销售商城网站系统设计与实现
博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育、辅导。 所有项目都配有从入门到精通的基础知识视频课程ÿ…...
Linux C\C++方式下的文件I/O编程
【图书推荐】《Linux C与C一线开发实践(第2版)》_linux c与c一线开发实践pdf-CSDN博客 《Linux C与C一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要 书评 试读】- 京东图书 Lin…...
2025寒假备战蓝桥杯01---朴素二分查找的学习
文章目录 1.暴力方法的引入2.暴力解法的思考 与改进3.朴素二分查找的引入4.朴素二分查找的流程5.朴素二分查找的细节6.朴素二分查找的题目 1.暴力方法的引入 对于下面的这个有序的数据元素的组合,我们的暴力解法就是挨个进行遍历操作,一直找到和我们的这…...
AI时代:弯道超车的新思维与实践路径
大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的…...
HunyuanDiT代码笔记
HunyuanDiT 是由腾讯发布的文生图模型,适配中英双语。 在模型方面的改进,主要包括: transformer结构text encoderpositional encoding Improving Training Stability To stabilize training, we present three techniques: We add layer nor…...
C++: Dtrees:load(constg String filepath, const String nodeName)中nodeName参数含义
1. nodeName 的作用 当你保存模型时,整个决策树会被序列化到一个 XML 或 YAML 文件中。nodeName 是加载时指定的一个逻辑路径,用于从文件中找到某个节点或子结构,而不是存储在文件中的字段。如果你不指定 nodeName,OpenCV 默认会…...
项目练习:若依后台管理系统-后端服务开发步骤(springboot单节点版本)
文章目录 1、用Maven搭建项目脚手架,父子工程依赖。2、引入SpringBoot Web容器依赖3、引入Mybatisdruid依赖4、实现接口查询数据5、整合logback日志功能 1、用Maven搭建项目脚手架,父子工程依赖。 root模块的pom添加plugin配置 <build><plugins…...
Ubuntu安装docker
snap install docker # version 27.2.0, or apt install podman-docker # version 3.4.4ds1-1ubuntu1.22.04.2 apt install docker.io # version 24.0.7-0ubuntu2~22.04.1 我应该安装哪一个,部署企业级应用? 在部署企业级应用时,选择合适的容器化…...
windows11下 podman-desktop 复制插件文件 到 RabbitMQ 容器内,并启用
目的: 刚启用的 RabbitMQ 容器,发现没有rabbitmq_delayed_message_exchange 插件,开始手动安装 官网 https://www.rabbitmq.com/community-plugins 或 https://github.com/rabbitmq/rabbitmq-delayed-message-exchange 下载rabbitmq_delay…...
Quickstart C++ with cmake, visualstudio | CPP
本文属于 C 系列文章,下一篇文章见 Quick get started with vcpkg, windows visual studio | CPP 目录 cmake-visualstudio-quickstartDepsConfigureBuild with CLILINKS cmake-visualstudio-quickstart https://github.com/hailiang-wang/cmake-visualstudio-quic…...
惊叹数据结构之美,品味排序算法之妙:对四大排序的详细介绍
大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 正文一、冒泡排序(Bubble Sor…...
机器学习——什么是代价函数? 下
“上次课讲了机器学习的模型表示,讲了一个线性模型的例子,那怎样在可能的拟合直线里选择一条最合适的呢?有没有数学的方法让这个直线合适还是不合适变得可以量化呢?这就要说代价函数了。” 本次课前半段内容非常简单,带领我们一起复习初中平面几何的知识,后半段给出了代价…...
Ubuntu本地部署网站
目录 1.介绍 2.安装apache 3.网页升级 1.介绍 网站其实就相当于一个文件夹,用域名访问一个网页,就相当于访问了一台电脑的某一个文件夹,在网页中看见的视频,视频和音乐其实就是文件夹里面的文件。为什么网页看起来不像电脑文件夹…...
hydra破解密码
hydra九头蛇是常用的密码破解工具 1、破解centos ssh密码 hydra -l root -P password.txt ssh://192.168.1.107:2222 hydra -l root -P password.txt -s 2222 192.168.1.107 ssh2、破解ftp hydra -l allen -P e:\aa.txt ftp://127.0.0.1 hydra -l allen -P e:\aa.txt ftp:…...
华为OD机试E卷 --字符串变换最小字符串 --24年OD统一考试(Java JS Python C C++)
文章目录 题目描述输入描述输出描述用例题目解析JS算法源码java算法源码python算法源码c算法源码c算法源码 题目描述 给定一个字符串s,最多只能进行一次变换,返回变换后能得到的最小字符串(按照字典序进行比较)。 变换规则&#…...
用户中心项目教程(二)---umi3的使用出现的错误
目录 1.情况的说明 2.遇到的问题 1)第一个问题-关于npx的使用 2)第二个问题--unsupport问题 3)第三个收获--nodejs安装问题 4)第四个收获---nvm下载问题 5)第五个问题--尚未解决的问题 3.个人总结 1.情况的说明…...
具身智能新突破!Physical Intelligence推出机器人动作tokenizer,训练提速5倍
具身智能,是人工智能(AI)行业的下一个浪潮。如何有效训练 Transformers 模型来控制具身机器人,是当前亟需要解决的难题,尤其是对于更复杂、需要精确和高频控制的精巧技能,现有的视觉-语言-动作(…...
Unity 学习指南与资料分享
Unity学习资料 Unity学习资料 Unity学习资料 Unity 作为一款强大的跨平台游戏开发引擎,在游戏开发及实时 3D 内容创作领域占据着重要地位。它功能丰富、易于上手,支持多平台发布,为开发者提供了广阔的创作空间。下面为你带来全面的 Unity 学…...
react什么时候用箭头函数,什么时候不需要
最近从vue项目转到react,太久没写了。遇到了一些卡住的问题,记录一下。 在 JavaScript 和 React 开发中,箭头函数(Arrow Functions)的使用主要取决于上下文、代码简洁性和特定需求。以下是关于何时使用箭头函数以及何时…...
软考中级复习篇章:数据结构部分的复习
软考中级快速通过篇章:数据结构部分的复习 一、引言 在软考中级的备考过程中,数据结构是极为重要的一个部分。它不仅是计算机科学的基础,也是软考中考查的重点知识领域。扎实掌握数据结构相关内容,对于顺利通过软考中级考试起着…...
【Vim Masterclass 笔记22】S09L40 + L41:同步练习11:Vim 的配置与 vimrc 文件的相关操作(含点评课内容)
文章目录 S09L40 Exercise 11 - Vim Settings and the Vimrc File1 训练目标2 操作指令2.1. 打开 vimrc-sample 文件2.2. 尝试各种选项与设置2.3. 将更改内容保存到 vimrc-sample 文件2.4. 将文件 vimrc-sample 的内容复制到寄存器2.5. 创建专属 vimrc 文件2.6. 对于 Mac、Linu…...
Spring Boot 整合 PageHelper 实现分页功能
在开发 Web 应用时,分页功能几乎是必不可少的。Spring Boot 提供了强大的功能来简化开发,而 PageHelper 则是一个优秀的 MyBatis 分页插件,可以极大地简化分页查询的代码。本文将介绍如何在 Spring Boot 项目中整合 PageHelper,并…...
Redis和MongoDB的区别
前言 在项目选型阶段,MongoDB被选中主要是基于其处理大规模数据集的能力,而当时并未深入探讨其他替代方案。此前,Redis被用于管理少量但访问频繁的热数据。目前,项目采用MongoDB存储百万级数据,预计未来数据量将增长至…...
Java基础(2)
博客:深入理解浮点型数据、计算机视觉信息存储与类型转换 四、浮点型数据 在编程语言中,浮点型数据主要包括float(单精度)和double(双精度)。计算机默认使用double类型存储小数,这会引发一些特…...
D3.js及实例应用
文章目录 D3.jsd3.js 应用实例图标展示点击选择拖拉拽应用 D3.js D3.js是一个功能强大的JavaScript库,除了图标展示,还能实现多种类型的交互效果: 数据可视化交互 动态更新图表:根据用户操作(如点击按钮、选择下拉菜…...
管理权限特权
管理权限 Oracle 用户权限分为两种类型: 系统权限:允许用户在数据库中执行特定的操作。 对象权限:允许用户访问和操作特定的对象。 系统权限 Oracle 数据库中有超过100种不同的系统权限。权限中的 “ANY” 关键字表示用户在任何模式&#x…...
基于海思soc的智能产品开发(视频的后续开发)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们讨论了camera,也讨论了屏幕驱动,这些都是基础的部分。关键是,我们拿到了这些视频数据之后,…...