游戏引擎学习第43天

仓库 https://gitee.com/mrxiao_com/2d_game

介绍运动方程

今天我们将更进一步,探索运动方程,了解真实世界中的物理,并调整它们,以创建一种让玩家感觉愉悦的控制体验。这并不是在做一个完美的物理模拟,而是找到最有趣的控制方式。我们会通过试错来探索这些运动方程,并找到让英雄角色运动感觉最佳的方式。我们不提前知道这些答案,我们将通过尝试和错误的方式来发现。

昨天的回顾。

我们在开发过程中将玩家的位置结构转化为一个联合体,简单来说,这就是一个包含xy坐标的对。我们通过将其与所有相关的代码结合起来,使得这些代码更加简洁和直观。然而,我们仍然保留了一些原始的数学处理方式,如处理xy分量作为独立的标量。虽然这并不是必要的,但它提供了一种更清晰的方式来理解和处理玩家位置。

运行游戏后,我们立即感受到的问题是角色的运动感觉不太好。角色在移动时缺少加速和减速,停止得太快,没有任何动量反馈。这种情况让控制体验显得很生硬,也不符合我们希望的游戏感觉。为了改善这一点,我们需要给角色添加一些基本的运动感,如轻微的加速和减速效果。这不仅能增加游戏的可玩性,还能让玩家感觉更有控制感,同时保持动作游戏的紧凑性,不至于让玩家感到困扰。

动作深入分析:刚体动力学。

在我们讨论对象如何在现实世界中移动时,重力是一个常见的力,它对所有物体产生的向下作用力至关重要。这种力使得任何物体在没有其他外力作用时会逐渐下落。就像一个保龄球,它会一直受到重力的作用,并形成一种自然的运动模式。另一方面,还有线性和角度运动两种基本的运动类型。线性运动涉及物体在空间中平移,而角度运动则涉及物体的旋转,这两种运动在物理学上并无不同,都是由微观物理原理(如原子和夸克运动)决定的。

在我们的模拟过程中,我们主要关注的是这些宏观运动,而不是微观的原子级别行为。因此,无论球是如何旋转或移动的,这些都不需要在图形上详细展示,重要的是我们如何用这些运动来表现物体在空间中的状态。这种理解帮助我们简化了模拟和控制,使得玩家在游戏中的操作更加直观和自然。

线性动力学。

在讨论物体如何在现实中移动时,我们主要关注物体的线性部分。任何物体的运动都受到外力的影响,比如重力和其他可能的外力,如风。这些力作用在物体上并决定其运动方式。为了简化物理模型,我们可以将物体的复杂性减少到一个中心质量点,这就是质心。这一中心点代表了物体的整体质量分布的平均位置。

根据牛顿第二定律,力等于质量乘以加速度,即 F = m a F = ma F=ma。这表明,重物需要更大的力才能产生相同的加速度。我们可以利用这一方程来计算物体的加速度,当我们知道所有作用于物体的力后,再根据这些力来推断物体的位置。这样,我们就能将物理规律与渲染和碰撞检测等计算任务联系起来,从而在虚拟环境中表现物体的运动。

基本运动方程。

当我们讨论运动时,我们谈论的是物体的位置、速度和加速度之间的关系。这三者的相互依赖性定义了物体在任何给定时间的运动方式。例如,速度是位置的变化率,而加速度则是速度的变化率。因此,加速度直接影响物体的位置和运动路径。

在实现这些概念时,我们使用一个时间差的计算,即 delta t,这是帧之间的时间差。这使得我们能够计算物体的移动距离。例如,在游戏开发中,每帧我们会基于物体的当前方向和速度来更新其位置。通过将方向乘以时间增量,我们可以计算出在该时间段内物体的实际移动距离。这些计算反映了物体如何在屏幕上从一个位置移动到另一个位置,并考虑了时间对物体运动的影响。

这些基本的物理方程帮助我们理解和实现物体的运动模拟,在计算机图形学中,这些模拟技术使得物体的运动更加真实和流畅。

如何计算运动。

向量可以看作是一种具有大小的数学实体。我们使用向量来表示物体在一个特定方向上的运动。在计算中,向量的大小是由其长度决定的,通常通过勾股定理来计算。例如,如果一个物体在两个方向上分别移动10米和6米,我们可以使用勾股定理来计算其实际运动的总距离(向量的大小)。

然后,我们结合了物体的速度,每秒移动多少米,以及时间步长来确定实际的运动距离。速度与时间乘积等同于物体在一秒钟内的运动量。这些计算实际上是利用了积分,反映了速度如何累积到一个新的位置。因此,向量和速度的结合帮助我们更清晰地描述物体在时间中的位移。

一些微积分。

我需要从高中微积分课程中的思维方式中转变,这可能并不那么有用,即使所有的工具都在那里。我们不再仅仅依赖于固定的方程,而是要理解和处理不断变化的动态情况。例如,在游戏中,角色的位置和速度并不是固定的,而是随着时间的推移而变化。这就需要我们重新思考和计算这些关系,如位置的导数为速度,速度的导数为加速度。这种方法更符合实际应用的需求,并能够灵活处理各种复杂的动态情境。

以不同方式计算运动。

探讨了如何通过对时间步进行简化的方式,来模拟物体的运动。这些模拟并不需要复杂的常数方程,而是通过在每个时间步上应用一个简单的分段函数来实现。这种方法允许我们在不考虑每一个具体情况的情况下,对物体的运动进行粗略的建模。这实际上是对物理定律的一种简化假设,使得计算更加高效,避免了过多的复杂度。

目前代码的实现。

我们已经有一个方程用于计算物体的位置,这个方程结合了速度与时间的乘积和物体在上一个时间点的位置。这部分的计算其实是我们在写游戏代码时所熟悉的直觉。为了更准确地模拟物体的运动,我们需要考虑速度作为一个独立的量来进行存储。速度的变化需要累积,这意味着物体在每个时间步长中的运动状态都需要反映出来,这样在更新物体位置时才能使用到最新的速度信息

我们打算如何修改它以使用新的方程。

在这段讨论中,我们谈论了从一帧到一帧的更新过程。为了准确地模拟物体的运动,我们需要考虑加速度的累积影响,而不仅仅是瞬时的作用。这意味着在每一帧的开始时,我们需要更新物体的速度,以便将其累加到当前位置。这样做能够更真实地反映物体在整个时间段内的运动,而不仅仅是在单一时刻的加速度。对于写游戏代码的人来说,这意味着不只是简单地把这些物理细节处理掉,而是要仔细思考这些影响和所使用的方程。虽然可以简单地忽略一些细节来优化性能,但如果要做更真实的物理模拟,了解这些细节是非常重要的。只有当这些方程和原理被理解并应用时,才能确保物体在游戏中有可信的行为。

关于时间增量的讨论。

在这段讨论中,我们探讨了如何处理时间步长(delta t)在运动方程中的作用。我们将函数视为在每一帧内的瞬时计算,这些函数将加速度和位移整合到整个时间段内。例如,当计算物体的最终位置时,我们需要考虑在当前帧内加速度的累积影响,而不仅仅是单个时刻的瞬时加速度。每一帧都重新计算这个函数,利用之前计算的值和新的时间步长delta t,来更新物体的速度和位置。这使得我们能够在游戏中更准确地模拟物体的运动,而不是假设加速度仅在某一瞬间作用。通过这种方式,我们不断把握每一帧的运动变化,确保物体在整个时间内的行为是连续和可信的。

分段函数。

在这段讨论中,我们探讨了在游戏编程中如何处理物体的运动函数。在游戏中,当玩家控制某个物体时,物体的加速度在每一帧都是不同的,这意味着需要重新计算并调整函数。这些函数并不像数学中的连续函数那样可以进行线性分析,而是被称为“分段函数”。这些函数是由若干独立的部分组成的,每一部分代表物体在不同时间段内的运动方式。这种方法更能反映游戏中的实际情况,因为物体的运动不一定是平滑的,它可能包含急转弯或其他不连续的动作。这些“分段”之间可能有突出的曲线弯曲点,这种方式可以更好地模拟真实的物理效果,同时也能让游戏中物体的运动更加动态和多样化。

实现。

我们正在处理物体的速度和加速度问题。我们需要存储这些量以便从一帧到下一帧进行更新。速度的变化和加速度都是根据时间的变化计算出来的。为了简化这些计算,我们可以使用一个平方函数来直接将速度和加速度的变化进行处理。这样做不仅可以节省代码量,还能减少出错的可能性。我们假设物体在平滑的运动中加速,不考虑碰撞等细节。这就是我们现在的主要工作。
在这里插入图片描述

在这里插入图片描述

在数学上,一阶导(速度)和二阶导(加速度)与位移 s 的关系如下:

1. 一阶导(速度):

  • 定义:速度 v 是位移 s 随时间 t 的变化率。
  • 数学公式
    v = d s d t v = \frac{ds}{dt} v=dtds
    这里, d s ds ds 是位移的微小变化, d t dt dt 是时间的微小变化。速度 v 表示物体在给定时间内的位移变化。

2. 二阶导(加速度):

  • 定义:加速度 a 是速度 v 随时间 t 的变化率。
  • 数学公式
    a = d v d t a = \frac{dv}{dt} a=dtdv
    这里, d v dv dv 是速度的微小变化, d t dt dt 是时间的微小变化。加速度 a 表示物体速度的变化量,即每单位时间内速度的变化率。

3. 位移公式(s):

  • 定义:位移 s 是物体在给定时间 t 内的路径长度。
  • 数学公式
    s = 1 2 a Δ t 2 + v 0 Δ t + s 0 s = \frac{1}{2} a \Delta t^2 + v_0 \Delta t + s_0 s=21aΔt2+v0Δt+s0
    其中:
    • s 0 s_0 s0 是初始位置,
    • v 0 v_0 v0 是初始速度,
    • a a a 是加速度,
    • Δ t \Delta t Δt 是时间。

这个公式综合了物体的初始位置、初始速度和加速度的影响,用来计算物体在任意时刻的位移。

4. 当前瞬时速度:

在代码中,当前的瞬时速度加速度上次速度的关系是基于运动学公式:

v new = a ⋅ Δ t + v old v_{\text{new}} = a \cdot \Delta t + v_{\text{old}} vnew=aΔt+vold

总结:

  • 加速度控制速度的变化率。
  • 当前帧的瞬时速度是基于上次的速度,加上加速度在这一帧的贡献。

在这里插入图片描述

看一下现在的游戏。我们注意到玩家没有摩擦力。

我们现在实现了一个对象的运动方程,并且这个对象的行为完全符合预期。当前的实现中没有引入摩擦力,因此对象具有类似滑冰运动员或漂浮在太空中的小行星的行为方式。当他移动时,他会以动量为主导,没有任何外部的摩擦力对其速度产生影响。

对象的速度更新是通过叠加加速度和上一帧速度完成的,这是一种基于物理的合理方式。然而,当对象与墙壁发生碰撞时,我们的碰撞检测机制会阻止对象穿过墙壁,这一点已经正确实现,但目前并没有将对象的速度调整为零,而是继续保存其原本的速度。这导致了一种现象,即对象看似仍然在沿着某个方向加速。

这种设计对于玩家体验来说可能不够友好,因为当对象与墙壁接触后,如果玩家想反方向推动对象,他们需要花费一些时间来逆转速度。为了改善体验,我们可能需要在碰撞发生后立即调整速度,这样对象的行为会更加符合直观预期。

接下来可以考虑:

  1. 引入摩擦力,用于逐渐减小对象的速度,使其停止。
  2. 更新碰撞检测后的速度,使对象与墙壁接触时速度立即调整到零,从而避免出现虚假的速度。
  3. 可能在界面上展示速度的可视化效果,让玩家直观地了解对象的运动状态。

当前的实现虽然物理上正确,但对于玩家操作的体验来说可能需要进一步优化。我们需要确保速度的更新逻辑不仅仅是物理上的合理,同时也符合游戏体验的需求。

实现一些摩擦力。

我们尝试在运动中引入摩擦力。假设角色在场景中移动时,我们会受到速度的影响,因此需要某种摩擦或拖拽效应来模拟现实的阻力。

首先,为了简化,我们通过一个近似方法实现摩擦力,而不是完全精确的数学建模。实现时,我们通过计算加速度的反方向分量来模拟摩擦力。这种方法可以使角色在停止时显得更自然。

在代码中,我们调整了加速度的值,以实现合理的摩擦效应。例如,我们尝试将摩擦力的影响降低至速度的一部分(如0.5倍),逐步调整以观察效果。发现随着加速度的增加,角色的运动逐渐趋于自然,停止的响应也更快。

调整与测试

  • 初步测试:角色的运动显得太生硬,因此降低了摩擦强度。
  • 进一步优化:调整摩擦系数和加速度,找到一个平衡点,使角色的运动显得顺滑但不失阻力效果。
  • 最终结果:在不同参数的尝试后,找到了使角色运动更流畅的设置,既保留了惯性,又能迅速减速。

后续改进方向

目前的实现只是一个粗略近似,未来可以通过引入微分方程等更复杂的数学模型,精确模拟力与运动的关系。此外,碰撞检测功能仍需进一步完善,以保证角色在场景中的交互更加自然流畅。

通过这种方式,我们不仅提高了角色的操作手感,还为未来的改进和功能扩展奠定了基础。

在这里插入图片描述

公式(模拟中常用)


这段代码对应的物理模型是速度相关阻力,摩擦力的形式为:
F friction = − k ⋅ v F_{\text{friction}} = -k \cdot v Ffriction=kv
其中:

  • F friction F_{\text{friction}} Ffriction 是摩擦力或阻力,方向与速度 v v v 相反。
  • k k k 是与系统相关的比例系数(这里为 0.75 0.75 0.75)。
  • v v v 是当前速度(在代码中为 GameState->dPlayerP)。

根据牛顿第二定律 F = m a F = ma F=ma,加速度 a a a 和阻力之间的关系为:
a friction = F friction m = − k m ⋅ v a_{\text{friction}} = \frac{F_{\text{friction}}}{m} = -\frac{k}{m} \cdot v afriction=mFfriction=mkv

在代码中,ddPlayer(加速度)增加了一个阻力项:
d d P l a y e r → d d P l a y e r − k ⋅ v ddPlayer \rightarrow ddPlayer - k \cdot v ddPlayerddPlayerkv
这里的 − 0.75 f -0.75f 0.75f 实际上可以看作 − k m -\frac{k}{m} mk 的值。


为什么要使用真实物理,而不是可以手动调校的自定义物理?

在游戏开发中,选择使用真实的物理公式,而不是完全自定义的、手动调整的方式,背后有重要原因。尽管我们可以对参数进行手动调整,并不意味着从头到尾依赖直觉设计是最佳选择。以下是详细的复述与总结:

使用物理公式的核心原因

  1. 基础的重要性

    • 真实物理的基础为开发提供了可靠的起点,这些方程描述了物体在现实中运动的基本规律。
    • 人类对物体运动的直觉是与生俱来的。如果游戏中的运动模式偏离这种直觉,玩家会感到不自然,甚至觉得游戏“手感糟糕”。
    • 基于物理的系统能让玩家更容易理解游戏中的互动,并对操作结果做出合理预测。
  2. 避免低效的开发方式

    • 完全依赖自定义输入或手动调整的运动逻辑,容易因为缺乏对物理基础的理解而失败。
    • 开发者可能花大量时间试图手动优化,却难以获得自然的手感,这种方式风险高且不可控。
  3. 改进体验的灵活性

    • 以物理公式为基础开发后,可以根据需要在特定场景调整或偏离这些规则(如加入空气控制、双跳等)。
    • 这种方法在保持直觉自然的同时,允许高度的定制化,满足设计需求。

物理公式的好处

  1. 自然且真实的运动感

    • 使用物理方程,跳跃、移动等动作会遵循抛物线等自然轨迹,玩家可以更好地预判和适应。
    • 例如,当角色撞到墙上时,现实中的动量会导致滑动或反弹,而不是突然停止。这种符合直觉的细节大幅提升了沉浸感。
  2. 提升玩家体验

    • 如果运动逻辑直观,玩家会更快掌握游戏的操作。
    • 反之,如果运动规则不符合预期,玩家会因为不适应而放弃游戏,即使游戏本身有其他优秀的设计。
  3. 避免破坏感受的设计问题

    • 比如,墙面“粘性”导致角色在墙边停顿或卡顿,这样的体验会让游戏感觉生硬而不流畅。
    • 通过基于物理的调整,可以让角色在接触边缘时滑动、转移,获得更自然的手感。

开发建议

  1. 从真实物理开始

    • 不论最终目标是什么,都建议从最接近实际情况的物理方程开始,并根据需要逐步调整。
    • 这种方式能确保设计的基础是可靠且直观的。
  2. 精益求精,确保“核心感觉”正确

    • 游戏中的“核心感觉”必须准确,如角色的跳跃、移动等主要交互。即使游戏其他方面设计出色,但如果角色移动的体验很差,玩家可能根本不会深入体验游戏。
  3. 学习基础物理编程

    • 理解基本的物理方程是开发者的重要技能。一旦掌握这些规则,可以根据设计需求自由调整,而不会损失基础的自然感。

总结

将物理方程融入游戏开发不是为了实现完全模拟,而是为了打造符合玩家直觉的操作体验。真实物理提供了一个稳定的起点,确保玩家能快速适应游戏逻辑。同时,开发者可以在基础之上添加复杂的自定义效果,而不必担心手感失衡。忽视这一点可能会使玩家因控制体验糟糕而放弃游戏,从而影响游戏整体的成功潜力。

为什么不在碰撞发生时添加一个反向方向的减速度?

当角色碰撞发生时,可以考虑添加基于初始速度 v i v_i vi 的反向减速机制,这样角色在接近墙壁时可以逐渐减速,最终平滑地到达墙体边缘的最后一个像素位置。这种方法的好处在于提供了一种更自然且直观的控制方式。

在设计与墙壁相关的碰撞机制时,这部分非常关键,因此需要深入研究和优化。未来将会专注于这方面的细节,使墙壁交互能够达到理想的效果。通过适当的碰撞处理方式,既能让角色运动自然,也能避免运动的突兀和停滞感。

总结来看,这种基于反向减速的机制可以:

  1. 优化角色靠近墙体的运动

    • 角色在接近墙体时逐渐减速,不会突然停止,从而避免了生硬感。
    • 角色可以流畅地贴近墙体边缘,而不是产生明显的“粘滞”或“卡顿”现象。
  2. 增强玩家的操作反馈

    • 玩家可以更好地控制角色靠近墙体的行为,从而提升交互体验。
    • 碰撞时的平滑运动让玩家更直观地理解角色与墙壁的关系。
  3. 为进一步优化墙壁交互打基础

    • 后续设计中可以结合这种机制,加入更多墙体相关的功能(如壁滑、壁跳),让角色的操作更加丰富和自然。

未来的工作将会围绕墙壁互动展开,确保碰撞的物理表现和控制手感达到最佳状态。这一过程可能需要反复调试和测试,但能够显著提升整体的游戏体验。

是否担心实际物理会削弱世界上最伟大的跳跃代码的美学和优雅?

虽然实际的物理模拟可能会让某些非常规的代码设计显得不再那么纯粹,但这也是为了提升游戏的真实感和玩家体验。开发者在做这些决策时,常常需要权衡各种因素,包括物理模拟对游戏的影响和如何最大化保留游戏设计的独特性和美感。这种平衡可以影响游戏的操作感觉,控制手感以及最终玩家的体验。

如果你想要像Braid那样倒转时间,你需要存储什么?

对于游戏开发和物理模拟来说,涉及到的很多问题是不可逆的。物理学中的非反向能力主要是因为系统中的能量丢失。举个例子,如果一个物体滑动或撞击,会导致能量散失,如摩擦力或空气阻力。即使你尝试倒回这个过程,恢复到原来的状态,许多信息都已经丢失,因此不可能简单地将过程反向播放。为了实现“逆转时间”的效果,必须记录系统中的重要状态点,并理解这些信息在反向播放时的重要性。然而,这种方法无法完全恢复到过去的状态,而只是重新构建一个大致相似但不可逆的模拟。

角色是位图吗?

我们在加载角色时使用了位图,并将其分割为三个部分。这些部分使得角色具有一定的弹性,能够进行一些弹跳和移动的动作。虽然希望在周末之前完成这些工作,但如果不是,下个周末也会完成。接下来,我们还会对这些部分进行更多操作,进一步探索和优化角色的表现。

我们是否会对输入进行归一化,而不是为对角线情况特设?

我们可能会在某些情况下开始对输入矢量进行规范化,而不是仅仅依赖于一个特殊的主角。虽然现在还没有实现这个功能,但我们计划很快就会开始进行这一操作。这将使我们的处理更加标准化和一致。

会不会有一个映射函数来帮助确定摩擦和碰撞的地形?

目前尚未确定是否会有大量滑动或减速的元素,尽管这是这类游戏的典型特征。因此,虽然在脑海中有类似的设想,但还没有特别考虑这些机制带来的独特体验。可能会在未来加入这一类功能,但现在还没有明确的计划。

为什么使用v2而不是vec2或vector2?

通常他们更喜欢名字具有描述性,并在使用时简化它们。对于向量,他们习惯性地使用“v”而不是“vector”,因为它更短、更简洁。虽然目前没有完成过这一点,但他们可能会考虑未来改用更短的命名方式,比如“32”代替“thirty two”,以便使名称更为简洁。

为什么不把代码分成更小的函数?

在编写代码时,不要过早地将代码分解成函数,直到明确知道这些函数应该完成什么任务。这是因为提前将代码分解成函数可能会浪费时间,因为它们可能需要重写或合并到更大的功能中。当一个功能的确立不明朗时,将这些代码块提前拆分可能会增加代码的复杂性,使其更难以阅读和维护。将代码单独放入函数中并命名可能只是简单地增加了语法糖,而并不实际改进代码的可读性。最重要的是,在知道具体需求和功能后,合理地将代码分解成方法,可以提高代码的可维护性和可读性。

难道不应该使用一个最大速度变量吗?

使用一个最大速度变量可能是一个人为的设计决策,因为它限制了游戏中的玩家角色的速度。然而,这种限制不一定是有趣的或需要的。可能希望玩家能够在游戏环境中受到各种力的影响,并自由地以最快的速度移动,而不必受限于一个最大速度。这样设计可以让游戏更具真实性和可探索性。例如,如果玩家在太空中漂浮,他们可以以最快的速度前进,因为没有摩擦力的影响。因此,把最大速度看作是一种人工构造,可能不适合所有的游戏设计需求。

摩擦的负加速度基于当前速度会感觉更好。

有人提到,基于当前速度的摩擦负加速度会显得更自然。对此,我们的设计就是实现了这一点。负加速度与当前的速度相关联,这样摩擦力在玩家的运动过程中逐渐减少,从而产生更自然的减速感觉。这是代码的一部分体现,所以不太理解该提问的具体意思。这就是我们目前使用的设计。

你认为像bullet或box2d这样的东西适合用于玩家运动吗?

我理解你的困惑,像bullet或box2d这样的物理模拟通常会让游戏响应变得很麻烦,无法得到稳定的效果。这主要是因为真实物理模拟很难控制和调试,它们可能会过于复杂且不稳定。一般来说,我倾向于使用一种基础物理模型,确保运动的基本逻辑是正确的,然后再进行游戏设计调整,避免完全依赖复杂的物理模拟。这可以在不影响游戏体验的情况下,提供较为稳定的响应。因此,找到一种折中的方法来处理物理交互问题通常是一个更好的选择。

当何时使用其他积分方法?

数值积分和欧拉法的使用以及它们在不同场景中的应用。用户提到的欧拉法的局限性,尤其是在面对复杂系统时,说明了向后欧拉法的优势,它在逆向求解运动方程时能够避免数值积分的稳定性问题。这种方法能够更好地保持系统的能量稳定,避免数值飞溅问题。虽然向后欧拉法更具挑战性和成本,但在特定复杂的物理系统中,它能够提供更精确的解。这一对话展示了在数值集成中,正确的集成方法和算法选择对于获得稳定和准确的结果是多么重要。

即使英雄已经有弹跳了,我们还会使用刚体吗?

在游戏开发中如何处理物理模拟,特别是刚体(rigid body)的行为和一些非物理效果。即使英雄角色获得了弹性效果,它的物理模拟仍然会基于不同的差分方程,而不是解决与物理材质相似的实际问题,如凝胶状的物质。这意味着这些效果主要是作为视觉和动作上的图形效果,而不是物理行为上的模拟。

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

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

相关文章

Maven(生命周期、POM、模块化、聚合、依赖管理)详解

Maven构建项目的生命周期 在Maven出现之前,项目构建的生命周期就已经存在,软件开发人员每天都在对项目进行清理,编译,测试,部署等工作,这个过程就是项目构建的生命周期。虽然大家都在不停的做构建工作&…

第六届地博会开幕,世界酒中国菜美食文化节同期启幕推动地标发展

第六届知交会暨地博会开幕,辽黔欧三地馆亮点纷呈,世界酒中国菜助力地理标志产品发展 第六届知交会暨地博会盛大开幕,多地展馆亮点频出,美食文化节同期启幕推动地标产业发展 12月9日,第六届粤港澳大湾区知识产权交易博…

通过“思维链”提升ChatGPT提示词质量,更好的辅助学术论文

目录 1.写在开头 2.思维链是啥 1.写在开头 对于初步接触AIGC工具的宝子们,可以直接用最符合你习惯的方式去使用Kimi、ChatGPT这类AI工具。想到什么问题就问什么。对于比较简单直接的问题,不需要去想怎么写好提示词,直接在聊天窗口里表述你…

nacos bootstrap.yml 和 spring.config.import 加载配置的流程区别

相关依赖 springboot:2.7.15 nacos:2.2.3 bootstrap.yml加载方式 加载流程如下图所示 从图中可以看出,: 1.bootstrap.yml 的加载是在 BootstrapApplicationListener.onApplicationEvent 接收到 ApplicationEnvironmentPreparedEventEvent 事件后另起一个 Sprin…

高效项目托管指南:从本地到 GitHub 的完整流程

在现代软件开发中,将项目托管在 GitHub 上是一个常见且高效的方式。GitHub 不仅可以用作版本控制工具,还能帮助你与团队协作或展示自己的项目。本文将带你一步步完成项目的打包和上传。 高效项目托管指南:从本地到 GitHub 的完整流程 1. 准备…

【漏洞复现】CVE-2024-34102 Magento Open Source XXE漏洞

目录 漏洞介绍 影响版本 环境搭建 查看版本 漏洞复现 手动复现 漏洞 poc Magento Open Source 是一个免费开源的电子商务平台,适合中小企业或开发团队通过自定义代码和插件创建在线商店。它由社区开发和支持,功能强大但需要更多的技术投入。Adobe…

Scala的隐式对象

Scala中,隐式对象(implicit object)是一种特殊的对象,它可以使得其成员(如方法和值)在特定的上下文中自动可用,而无需显式地传递它们。隐式对象通常与隐式参数和隐式转换一起使用,以…

C# 委托详解02(委托和事件单独开一篇)

上一篇仅仅简单通过代码,以及相关运行示例,对委托有了基本概念。这一篇侧重对委托的更加深入的理解。有问题欢迎评论。本人技术不高,也欢迎指正。 希望看完我能够解释清楚以下问题,而大家能够从中找到自己的答案。 什么是委托&a…

【零成本抽象】基本概念与在C++中的实现

零成本抽象概念是由 Bjarne Stroustrup 提出的,他在 1994 年的著作中就有相关设想,2016 年其在 C++ 大会登台演讲时,明确阐述了 C++ 中的 “零成本抽象” 这一理念。 一、零成本抽象概念 Bjarne Stroustrup提出的零成本抽象概念,是指在编程中使用高级抽象机制时,不会产生…

Docker 安装 Jenkins:2.346.3

准备:已安装Docker,已配置服务器安全组规则 1581 1、拉取镜像 [rootTseng ~]# docker pull jenkins/jenkins:2.346.3 2.346.3: Pulling from jenkins/jenkins 001c52e26ad5: Pull complete 6b8dd635df38: Pull complete 2ba4c74fd680: Pull complet…

分布式事物XA、BASE、TCC、SAGA、AT

分布式事务——Seata 一、Seata的架构: 1、什么是Seata: 它是一款分布式事务解决方案。官网查看:Seata 2.执行过程 在分布式事务中,会有一个入口方法去调用各个微服务,每一个微服务都有一个分支事务,因…

分布式日志系统设计

一、分布式日志系统定义 分布式日志系统是一种用于收集、存储和分析大规模分布式系统日志的系统。它可以帮助开发人员和系统管理员实时监控和调试系统,提高系统可靠性和可用性,同时也可以用于日志分析和故障排查。 二、简单设计思路 日志收集&#xff…

VSCode设置字体

参考文章:【面向小白】vscode最佳实践(2)—— 字体设置(fira code更纱黑体),这篇文章末尾给了安装字体的链接。 配置的字体还是很好看的。 ‘Fira Code Retina’, ‘Sarasa Mono Sc’ 需要注意的一个点&am…

leaflet 双屏对比

本章主要讲的是leaflet的双屏对比,本文参考了插件:Leaflet.Sync,我这里对原有的文件进行了重写,去掉了一部分不需要的内容,增加了flyTo和panTo方法,新的方法,如果需要可以自行下载资源。 目录 …

什么是语义空间?

一、概念 今天我们来聊一聊一个比较抽象的概念——语义空间。语义空间(Semantic Space)是自然语言处理(NLP)领域中一个重要的概念,在语义空间中,文本中的语义信息通过数学的方式来表示和处理。语义空间是一…

Linux系统nginx版本升级

最近公司漏扫有涉及到需要升级nginx的部分, 以下是一些总结经验 检查当前nginx版本 执行命令: nginx -V 如果没有设置环境变量则需要进入到nginx目录sbin目录下执行: ./nginx -V 下载最新版nginx nginx下载地址: https://nginx.org/en/download.html 1)选择稳定版本 wget h…

如何高效的向AI大模型提问? - 提示工程Prompt Engineering

大模型的输入,决定了大模型的输出,所以一个符合要求的提问Prompt起到关键作用。 以下是关于提示工程Prompt Engineering主要方法的详细表格,包括每种方法的优点、缺点、应用场景以及具体示例: 主要方法优点缺点应用场景示例明确性…

QT 多级嵌套结构体,遍历成员--半自动。<模板+宏定义>QTreeWidget树结构显示

Qt的QTreeWidget来显示嵌套结构体的成员&#xff0c;并以树形结构展示。 #include <QApplication> #include <QTreeWidget> #include <QTreeWidgetItem> #include <QString> #include <cstdint>// 假设这些是你的结构体定义 struct BaseMeterPa…

鸿蒙实现数据管理

目录&#xff1a; 1、鸿蒙实现数据管理的三种方式2、用户首选项3、键值型数据管理3.1、获取KVManager实例&#xff0c;用于管理数据库对象3.2、创建并获取键值数据库3.3、调用put()方法向键值数据库中插入数据3.4、调用get()方法获取指定键的值3.5、调用delete()方法删除指定键…

linux 下硬盘挂载c

1. 检查硬盘的文件系统类型 确保你所尝试挂载的硬盘 /dev/vdb 上已经有一个有效的文件系统。你可以用 lsblk -f 令查看硬盘的文件系统类型。 lsblk -f2. 检查挂载命令的语法 硬盘已经格式化为 ext4 sudo mount -t ext4 /dev/vdb /data 确保你在挂载时没有指定错误的文件系统…