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

游戏引擎学习第276天:调整身体动画

运行游戏,演示我们遇到的拉伸问题,看起来不太好,并考虑切换到更顶视角的视角

我们开始讨论游戏开发中的一些美学决策,特别是在处理动画方面。虽然我们是游戏程序员,通常不负责设计或艺术部分,但因为这是一个几乎完全由我们自己完成的项目,所以我们不得不做出一些设计决策。

接下来我们会展示目前存在的问题。现在,我将打开手工项目并运行游戏,展示我们需要解决的一个难题。

在游戏中,主角的动作表现已经基本符合预期。正如之前提到的,游戏设计要求角色的头部和身体分别独立运动。角色的身体始终停留在一个方格上,而头部可以自由移动。目前的实现基本上做到了这一点,整体效果看起来很好。

但问题在于,如果我们以一种简单的方式,直接对身体进行拉伸以跟随头部,就会出现分离的现象。虽然我们还没有考虑到头部上下摆动的效果,但即使在这种情况下,我们也必须将身体进一步拉伸才能跟上头部的位置。这个问题在角色上下移动时尤为明显,拉伸后的效果看起来并不好。

目前我担心的主要问题是,是否能够将这种效果做得足够好。我们可能需要进一步调整。为了改善这个问题,有几个方面可能会有所帮助。首先,最终的艺术资源可能会更加倾向于顶视角,而不是现在这种侧视角。这意味着未来的角色设计可能会更加符合上方的视角,而不是完全的侧面视角,这样可以缓解当前问题。

虽然我们可能会在最坏的情况下遇到挑战,但通过调整艺术资源的视角,我们有希望解决目前的拉伸和分离问题。总的来说,虽然现在看起来存在一些问题,但我相信随着进一步的调整和艺术资源的更新,我们可以让整体效果更符合设计要求。

黑板:如何通过顶视图艺术解决分离问题

现在面临的情况是,如果头部运动,那么脖子也必须相应地运动,否则头部就会看起来像是与身体分离。在某些情况下,头部与身体的连接问题更加明显,尤其是当头部运动时,身体和头部看起来像是分开了。

考虑到最终艺术风格可能更倾向于顶部视角(top-down),这意味着头部和身体的关系可能会更加接近,并且头部可以更自由地移动而不会给人分离的感觉。为了更好地实现这一点,头部的位置和身体的连接方式需要做出相应的调整,使得即使头部大幅度移动,身体也不会显得不协调。现在的绘图可能不够精准,但总体思路是,身体和头部的连接可以做得更自然一些。

另外,游戏的风格并不是要求高度的真实感,而是一个卡通式、富有表现力的风格。类似《使命召唤》这样的游戏,头部不必严格按照解剖学方式与身体连接,这样的设计风格对我们来说不算大问题。

然而,尽管如此,还是存在一些挑战。在头部和身体的连接上,特别是当角色移动到某些位置时,依然会出现不自然的情况。我们不能仅仅依靠简单的拉伸(shearing)来解决这个问题,因为这可能不是一个长期有效的方案。

接下来的工作重点是,尝试调整这些算法和方式,找到一种方法来解决头部和身体连接问题,尤其是在角色处于某些特定姿势或角度时。目标是让这些情况看起来更自然,避免出现分离或不协调的效果。

运行游戏并演示侧墙上的碰撞缺失

我们发现一个现象:当角色与某些树木的上边或下边接触时,会发生碰撞,无法穿过去;但当从树的左右两侧接触时,却可以直接穿过,没有发生碰撞。我们目前不知道这是为什么,也没有特别去调查,可能只是一个非常简单的原因,可能与我们的碰撞检测机制有关。

目前看来,我们可能根本没有对这些树的左右两侧进行碰撞检测,或者是在某些方向上使用了不同的碰撞检测方式,比如使用了一种点查询的方法来判断是否发生碰撞,而不是对整块区域进行检测。这导致角色在上下方向会被阻挡,而在左右方向却能穿过。

此外,我们之前也对一些角色的碰撞处理做了调整,可能也间接影响了当前的情况。不过这并不是我们现在要专注的问题,暂时可以忽略。

接下来我们想做的是微调角色的显示效果,特别是将头部位置向下移动。当前头部的位置太高了,不太符合我们后续将要使用的美术资源的视觉效果。通过在绘制时加入偏移量,可以把头部向下挪一点,使其更接近最终的视觉效果。

还有一个我们考虑过但暂时先不处理的内容是角色的结构呈现方式。现在我们是通过图像中的“剪切”来表现分层效果的,未来可能改成通过实际的位移来实现更加真实的效果,不过当前还不是处理这个问题的合适时机,所以先放一边。

总之,我们现在的目标是调整角色头部的位置,并为后续替换美术资源做准备,争取最终呈现更理想的效果。我们会进入相应的模块(例如 world)来修改绘制逻辑,加入偏移来调整显示位置。

game_world_mode.cpp:将头部下移,并将其绘制在斗篷前面

我们在绘制英雄头部的时候,可以任意地决定在Y轴方向上向下偏移一点位置。当前的绘制逻辑中使用了一个叫 push-fit map 的结构,我们猜测这个结构中的 v3 参数允许我们对物体进行位置上的位移。如果想要调整头部的位置,我们可以在这里加入一个Y轴方向的负向偏移,使头部更靠下。

由于我们目前正在处理动画部分,也可以灵活地对现有代码进行修改和测试。可以直接编辑相关绘图代码,观察头部位移后的实际效果。

一个需要注意的问题是:当我们对头部进行位移绘制后,要确保它仍然能正确地显示在角色其他部位之上。当前的绘制顺序控制方式可能并不完善,现在之所以图层之间的覆盖关系看起来是正确的,只是因为碰巧绘制顺序没有出现问题,一旦进行偏移或调整,很可能会出现头部被其他部分遮挡的情况。

因此,为了保证视觉层级的正确,我们在进行位移绘制的同时,还需要合理安排绘制顺序,确保头部始终处于最上层。接下来我们会继续查看绘图代码,调整绘制逻辑,使头部偏移后能够正常显示在顶层。
在这里插入图片描述

黑板:当前艺术资源的打包方式

目前的图像资源并没有进行过真正的处理和整理,依然保持着最初搭建游戏时的原始状态,没有经过任何测试或标准化的流程来确保绘制和排序的正确性。这些资源的底部位置仍然是当时随意设定的,因此在渲染排序时并不可靠,导致我们无法依赖当前资源本身的结构来判断图层之间的显示顺序。

如果头部的位置是在上方,而其锚点或位置点也设置得准确,那么排序本应该是正确的。但现在的资源结构无法支持这种逻辑排序,因此我们也就无法通过正常方式确保头部显示在其他部件上方。

目前我们只能通过某些“hack”的方式来控制渲染顺序,比如人为调整绘制顺序或通过临时逻辑来控制Z值或Y值,来实现视觉上合理的排序。这种方法虽然不理想,但在当前资源条件下是我们可行的手段。

此外,我们还怀疑当前的排序机制中可能存在某些bug,比如与Z值或其他内部机制相关的排序错误。尤其是在将头部向下移动时,理论上由于我们是按照Y值从上到下进行排序的,越靠近屏幕的元素应该被排在前面,因此头部应当会盖在其他部分之上。

为了验证这一点,我们打算进入 render group 模块,仔细检查当前的排序逻辑,确认是否真的是按照Y值进行前后排序,以及是否存在优先级问题或其他导致排序不正确的潜在原因。这样可以帮助我们理清图层排序混乱的根本问题。

game_render_group.cpp:调查排序问题

我们查看了 entity basis P 的处理过程,重点关注了Y轴的排序逻辑。在代码中,我们会将变换后的Y值从排序信息中减去。按照这个逻辑,当一个元素的Y值变小时(即它在屏幕上位置更靠下),经过减法后其排序值应该变大,因而会被排在更前面,显示在上层。

这符合我们对排序的预期:越靠近屏幕底部的对象,应该越靠前绘制,以便产生正确的层级感。不过我们一开始对Y轴方向有些混淆。我们使用的坐标系中,Y轴是向上为正的,也就是说越往下,Y值越小,因此减去Y值后排序键变大,所以位置越低的对象排序键更大,也就是越靠前显示,这符合正确的前后排序逻辑。

在进一步查看代码后,我们发现排序逻辑可能确实没有问题。但还是需要做一个“理智检查”,也就是检查为什么在实际表现中,有些对象的绘制顺序看起来和我们预期的相反。这就要求我们直接查看对象的排序键,确认它们在当前帧中被赋予了什么值。

通过直接打印出这些对象的 sort key 值,我们可以确认是否排序逻辑存在错误,或者只是我们在理解调用方式时存在误解。因为从目前的现象来看,某些对象明明位置更低,却被绘制在了更后面,这可能是一个bug,也可能是由于某种意外的调用顺序或状态错误导致的。

下一步我们将检查具体的排序键值,确保渲染顺序确实按照预期逻辑进行,并排除任何由于Y值处理、Z值叠加或其他渲染管线行为导致的异常。这样可以进一步定位渲染顺序不正确的原因。

调试器:在PushBitmap断点处暂停,检查斗篷和头部的SortKey

我们为了确认当前图像绘制的排序逻辑,开始通过打断点的方式,检查每一个图像元素在渲染时实际使用的 sort key 值。我们重点关注了头部和身体两个部分。

首先设置断点查看头部的绘制调用,跟踪 push_bitmap 函数的执行流程,观察其如何生成 sort key。在断点中查看返回的数据结构,找到头部对应的 sort key4095.320007。随后以相同方式查看身体的 sort key,发现它与头部有显著不同。

从这个结果可以明确看出,排序的差异并不是因为Y轴位置不同导致的,而是由于Z轴的排序造成的,这说明当前系统采用了Z值为主的排序逻辑。

进一步分析后发现,渲染排序的数值是以 4096 为单位分段的,而这个值和对象的 Z轴信息 密切相关。渲染系统中有一个用于控制对象位置与朝向的结构体 object_transform_upright,我们检查了它的设定流程,发现每个对象默认都会被设置为“upright”,也就是说,都会被赋予默认的朝向变换。

接着又检查了与 P.z 相关的两个值:一个是传入的原始 P.z,另一个是 object_transform 中的 offset.z。代码中会同时使用这两个Z值来参与排序的计算。虽然在某些结构里没有包含Z值,但 offset.z 确实在排序时起了作用,这也进一步解释了为什么身体和头部虽然Y值不同,但排序顺序与预期相反。

总结起来,当前渲染系统的排序主要基于Z值而非Y值,即使Y轴在视觉上更靠下,只要Z值不符合期望,渲染顺序仍会出现错误。而这些Z值是在不同的位置被设置或组合进来的,所以要解决图层排序不正确的问题,就必须追踪和管理这些Z值的来源和逻辑,确保它们在头部、身体等部件之间保持一致或合理的前后关系。这样才能从根本上解决头部显示在身体后方的问题。
在这里插入图片描述

在这里插入图片描述

Head:4096.363
在这里插入图片描述

在这里插入图片描述

Body:4096.470

game_world_mode.cpp:稍微更正确地排序身体部件

当前Z值排序系统存在较大的混乱,主要问题出在我们人为设置了某些图层的Z值,导致整体渲染顺序变得不可控。例如,我们曾经手动设置了披风的Z值,使其渲染在其他部分之上,这是为了让披风视觉上覆盖身体或其他部分,但这种处理方式属于临时性的“硬编码 hack”,并不适合长期使用。

检查过程中我们确认,Z值确实在多个位置被传入并叠加使用,比如 object_transform.offset.zoriginal_p.z 两者都会共同作用于最终的排序键。这就导致我们难以直观判断一个对象最终会处于什么渲染层级位置。

为了解决这种错误的遮挡关系(例如头部被披风盖住),我们尝试了一些缓解措施,比如让身体或披风在Y轴上稍微向上或向下偏移,通过Y值参与排序。但这种方式依然存在问题,特别是当角色存在“上下起伏”动作(bobbing)时,Y值会动态变化,导致Z排序出现错误,例如角色跳动过程中披风会意外遮挡头部。

目前Z排序的混乱主要表现在以下几个方面:

  1. Z值来源不统一:不同部件的Z值既可能来自原始数据,也可能来自变换数据,而且两者叠加时缺乏统一标准。
  2. 排序方式不透明:Z值并没有明确的管理机制,导致排序逻辑不可预测,容易引起视觉错误。
  3. 临时 hack 导致连锁问题:之前为了解决某一处排序错误而插入的Z值调整,容易在其他地方引发新的错误。
  4. 缺乏完整的Z排序设计:整体没有一套专门为2D伪3D(如斜45度视角)场景设计的图层控制系统。

我们目前尝试的解决方法包括:

  • 为身体、披风、头部等分别设置极小的Z偏移值,让它们在视觉上保持正确层级。
  • 尽量避免Y轴上的浮动影响Z排序结果。
  • 将Z值管理向规范化方向推进,暂时通过小数偏移进行排序控制,避免硬编码绝对值。

但根本上,想要彻底解决这个问题,我们仍然需要对整个Z排序系统进行一次全面的清理和重构,建立一个统一、清晰、可控的排序体系。否则,随着资源和动画增多,问题只会进一步放大。

目前这种混乱的排序状态,也反映出我们在开发过程中,由于时间有限,常常无法系统性地解决复杂问题,而只能依靠零碎的、临时性的调整。这种开发方式虽然可以快速推进进度,但也会积累大量技术债,最终可能影响项目的稳定性和可维护性。未来必须预留专门时间,彻底清理并重构渲染系统中的Z排序逻辑。
在这里插入图片描述

在这里插入图片描述

game_world_mode.cpp:限制剪切

当前我们对角色的整体视觉表现进行了调整,目标是将角色视觉上缩小,使其更符合俯视视角的设计需求。以下是当前主要的处理过程和观察结果的详细总结:


角色缩放与视觉布局调整:

  • 我们将角色的尺寸进行了进一步缩放,使其整体更紧凑,以适应未来的“从上往下看的视角”(top-down 视角)需求。
  • 披风(Cape)也同样进行了Y轴方向的下移处理,确保整体布局协调。
  • 这些调整后的视觉更接近最终期望的效果,也为后续的动画表现留出空间。

Shear(倾斜变换)调整与测试:

  • 原本角色在移动或跳跃时存在较明显的 shear(斜切变换),用于模拟动作,但会造成身体与头部的视觉错位。
  • 我们尝试了完全关闭 shear 来观察其对分离错位的影响,结果发现虽然减少了错位,但视觉表现缺乏动感。
  • 进一步尝试保留较小的 shear 幅度,在视觉和错位之间做平衡。结果显示,轻微 shear 的效果可以接受,不会造成明显错位。
  • 同时也考虑未来是否可以改用“旋转”来代替部分 shear,实现更自然的动画效果。

跳跃(Hop)行为同步性优化:

  • 当前的跳跃动画存在角色部件(如头部与身体)同步性差的问题,即跳跃过程中,头部与其他部位有“脱节”现象。
  • 为了优化这一问题,我们将角色跳跃逻辑中延迟时间(delay)设为零,实现即时跳跃,从而测试同步性改善的效果。
  • 实验发现,即使使用瞬时跳跃逻辑,部件之间仍存在一些脱节情况。

播放速度调试以观察细节:

  • 为更精确观察跳跃过程中的视觉表现,我们将整体动画播放速度减慢至原来的四分之一。
  • 注意到此模式下输入并未减速,导致原有的 loop 播放机制不生效,因此我们改为手动重复动作录制进行测试。
  • 慢速下的观察结果揭示了跳跃过程中的视觉分离位置和 shearing 效果的详细动态表现。

接下来的优化方向建议:

  1. 改进组件之间的同步逻辑:尤其是头部、身体和披风在跳跃中的跟随响应速度,应在动画更新逻辑中更严密地绑定。
  2. 引入更自然的变换形式:尝试使用旋转(rotation)替代部分 shear,以更真实模拟角色运动时的身体扭动。
  3. 整理并固化动画顺序机制:将跳跃时的过渡变换行为明确控制在时间线上,避免因延迟配置造成部件错位。
  4. 为 top-down 视觉重构资源:后续美术资源需按照更紧凑、更俯视的角度进行设计,使整体视觉协调。

总结来看,我们在角色缩放、shear 变换和跳跃行为上取得了一定的改进,但仍需从底层动画系统和视觉层级控制上进行更加系统化的优化,以彻底消除跳跃中的视觉分离和层级错位问题。

game_world_mode.cpp:缓解分离问题

我们目前正在对角色的跳跃动画及其位置偏移进行深入调整,目标是提升视觉一致性,解决角色在跳跃过程中的错位和形变问题。以下是本阶段调试和分析的详细总结:


问题定位:

  • 在角色跳跃过程中,头部在 Y 轴上的弹跳效果与身体的主动画存在明显不同步问题,导致头部“脱节”感强。
  • 原本希望通过一定比例(例如10%)的插值方式来平滑地过渡头部位置,但效果并不理想。
  • 弹跳动作中的“弹性”(springiness)也未达到预期,且还可能带来不自然的错位。

尝试的优化措施:

1. 移除头部下移的弹跳位移:
  • 暂时取消了头部在跳跃过程中的下移动画,从而测试是否可以缓解与身体之间的分离感。
  • 结果表明,这种方式下头部位置与身体之间的距离更自然了,视觉上也更协调。
2. 调整角色整体比例:
  • 增大角色尺寸,使其在一个地图格子中占据更多空间(更接近方格尺寸)。
  • 实验中发现,角色越大,错位感越小,因为身体本身的存在感增强,视觉错位的相对程度降低。
3. 调整头部锚点位置:
  • 将头部在模型中的位置向下偏移,让其更贴近身体,使整体更为紧凑。
  • 配合适当的 shear 角度与弹跳幅度(例如将 shear delta 增加为原来的两倍),视觉表现变得更加自然。
4. 恢复头部的弹跳效果:
  • 在优化后的位置调整基础上,重新启用头部的弹跳逻辑,测试视觉表现。
  • 整体表现更加协调,跳跃动画不再显得生硬或断裂。

进一步发现的问题:

1. 对角线移动引发的问题:
  • 在角色以对角线方向移动时,仍会出现轻微的形变不同步问题。
  • 同时如果在移动路径上找不到可行走区域,角色仍然会继续移动,这是一个逻辑漏洞。
2. 地图格子可达性逻辑错误:
  • 当找不到“最近的可通行格子”时,角色仍然会被允许移动,这是不合理的。
  • 应该在路径不可通时直接阻止跳跃或移动行为。
3. 摄像机平移导致的坐标偏移问题:
  • 当前角色的移动起点(movement from)和终点(movement to)是以“原始世界坐标”存储的。
  • 当摄像机发生移动时,这些坐标将产生错位,导致逻辑与渲染不一致。
  • 需要改用相对于世界或逻辑地图的坐标系统来存储这些位置,避免摄像机平移影响角色行为。

当前阶段的收获:

  • 通过对角色尺寸、头部锚点位置、shear 幅度和弹跳逻辑的调整,跳跃动画的整体表现已有显著改善。
  • 一些深层问题(如摄像机移动引发的位置错乱)已被识别,待在后续重构实体系统时修复。
  • 整体上角色的动作与视觉表现更趋协调,尤其是在考虑更宽更紧凑的美术造型下。

后续优化方向:

  1. 完善跳跃目标判定逻辑,确保跳跃路径始终落在可通区域;
  2. 调整位置记录方式,以相对坐标系统取代绝对坐标,避免摄像机偏移影响;
  3. 美术资源联动,确保头部、身体、披风等元素尺寸和锚点匹配新逻辑;
  4. shear 与弹跳细化控制,结合帧数和角色运动状态动态调整幅度,实现更细腻的动作表现。

整体而言,角色跳跃系统已逐步趋于稳定,但为确保从不同视角和速度下都能保持一致视觉效果,仍需在逻辑层和美术层之间进行更紧密的联动与优化。
在这里插入图片描述

改成100 跳的很严重

在这里插入图片描述

检查一下什么原因导致的

在这里插入图片描述

在这里插入图片描述

运行游戏并考虑禁止对角线移动

我们目前正在思考并测试一个关键设计点:是否要禁止角色进行对角线方向的移动。这一决策关系到动画表现的稳定性、美术资源的处理难度,以及游戏的整体操控感和设计方向。


当前问题

在对角线方向移动时,角色在跳跃过程中会出现不自然的“抖动”或“错位”,具体表现为跳跃路径在两个方向之间切换时出现的视觉不连续或形变异常。这种现象在实际运行中较为明显,尤其在采用 tile-based(基于格子)地图的设定中会带来困扰。


潜在解决方案:禁止对角线移动

我们提出了一种可能的解决方式:完全禁止角色进行对角线方向的移动,仅允许上下左右四个主方向移动。

优点:
  • 可以大大简化动画的插值与位置计算,避免错位与形变异常。
  • 减少对美术资源的要求,例如不必额外绘制对角线方向的动画。
  • 符合某些经典游戏的设计方式,例如《塞尔达传说》中角色就无法进行对角线移动。
  • 与目前设计中“只能朝上下左右四个方向攻击”的限制保持一致,有助于保持整体风格统一。
  • 对于基于网格的系统来说,强制正交(rectilinear)移动有利于路径规划与行为逻辑的简化。
潜在缺点:
  • 有可能损失一部分流畅感,尤其是在自由度更高的动作游戏中,玩家可能习惯了对角线移动的方式。
  • 部分玩家可能会觉得操控略显生硬或受限。
  • 《以撒的结合》(Binding of Isaac)等游戏允许对角线移动,可能让我们在操作体验上略显落后。

实际测试反馈

我们已经尝试在代码中强行限制对角线输入,模拟纯正交移动的游戏状态,以便从第一手体验中判断其可行性与合理性。

测试目标包括:

  • 感受移动过程中的流畅性与自然程度;
  • 判断是否影响整体操控体验;
  • 检视跳跃动画在纯正交移动下是否变得更加自然、稳定;
  • 对比“允许对角线”与“只允许正交”两种状态在视觉与交互上的差异。

参考经典案例

我们也回顾了一些经典游戏的设计方式:

  • 《塞尔达传说》:禁止对角线移动,仅支持上下左右四方向。
  • 《以撒的结合》:允许对角线移动,具有更高的动作自由度。
  • 当前我们设计中已经限制攻击方向仅为四个主方向,因此若移动方向也限制为四方向,会使整体设计风格更加统一。

结论与思考

我们还未最终决定是否禁用对角线移动,但可以初步得出几点判断:

  • 从技术与美术层面,禁用对角线可以简化问题并提升稳定性;
  • 从游戏性角度,仍需实际测试手感是否自然,是否影响流畅性;
  • 如果禁用后操控体验明显变差,可能需要回头权衡动画复杂性与用户体验之间的平衡。

我们接下来的工作将围绕对角线移动的最终取舍展开,包括进一步测试操控手感、检视动画表现以及制定更统一的行为逻辑策略。

game_world_mode.cpp:禁止对角线移动

我们当前正在优化角色的移动控制逻辑,核心目标是让角色在任意时刻只沿一个轴向移动(即仅限水平或垂直),避免同时进行对角线移动。这项改动不仅有助于解决跳跃时出现的错位、形变等视觉问题,也可以进一步统一操作体验,使其更加清晰、可控。


主要改动目标

我们要调整的是输入处理逻辑,使得:

  • 当用户按下某个方向键时,仅允许角色在该方向轴上移动;
  • 禁止同时存在水平与垂直方向的移动输入,从而杜绝对角线移动的可能性;
  • 如果所有方向键都松开,角色则静止不动;
  • 移动的判定方式改为“按键是否刚刚被按下”(即半跳变次数判断),而非“按键是否持续按下”。

实现方式详解

  1. 使用半跳变(half transition count)作为判定条件
    我们不再检查按钮是否持续按下(is_down),而是使用“was_pressed”来判断某个按钮是否刚刚被按下,这样可以更明确地限制每一次输入的响应,减少因多个方向同时被识别而产生的异常行为。

  2. 只设置一个方向上的移动值
    每当检测到某个方向的按键被按下,就只设置该方向的运动值(比如 ddP.xddP.y),并且立即将另一方向的值清空。

    • 例如:如果检测到“向上”按键刚刚被按下,就只设置 y 轴上的正方向速度,清空 x 轴上的移动。
  3. 自动清空未被按下的方向输入
    如果在当前帧中没有任何方向按键被触发,就将两个方向的输入都清空,确保角色在玩家未进行输入时处于静止状态。


实现中的具体注意点

  • 我们通过添加判断逻辑,确保每次只有一个方向的输入被响应,其它方向被“排他性地”清除。
  • 判断逻辑使用“was_pressed”函数进行按钮判定,该函数基于半跳变次数(half transition count)判断是否刚刚触发过一次按键,这样可以捕捉到键入动作的瞬间而非长按状态。
  • 增加了“没有方向键按下时清空移动”的逻辑,防止角色因为旧的残留输入而继续移动。
  • 为了实现这些功能,我们略微整理了一下现有代码结构,同时扩大了编辑区域以方便查看全局逻辑。

目标效果

  • 角色每次只能沿一个轴移动:要么水平、要么垂直;
  • 输入响应更加干净明确,不会发生多个方向同时触发的问题;
  • 为后续基于格子的 tile-based 移动逻辑打下良好基础;
  • 更加符合我们希望呈现出的“类塞尔达式操作体验”;
  • 减少动画系统或物理模拟中由于输入混杂造成的异常偏移或变形。

通过这次调整,我们在角色控制上迈出了一大步:输入响应更清晰、运动行为更确定、系统逻辑更简洁,也让后续动画与美术的配合空间更加清晰可控。
在这里插入图片描述

好奇怪为什么没反应呢
在这里插入图片描述

设置一下如果按键没按下清一下ddP的值

在这里插入图片描述

运行游戏并尝试使用基准移动

我们在进一步处理角色的移动逻辑时,确认当前的移动方式——即角色只能沿一个轴向(水平或垂直)进行移动,已经基本达到了理想中的控制效果。从测试来看,这种限制不会带来太大的问题,角色在方向控制上的反馈也相对清晰自然。


核心逻辑进一步完善

我们进一步调整了控制器的判断逻辑:

  1. 当同一轴上的两个方向键都没有被按下时,清除该轴的输入

    • 比如:如果“上”和“下”都没有被按下,那么 y 轴的速度输入就会被清零;
    • 同理,x 轴方向也是如此。
  2. 虽然这项调整不是绝对必要,但可以让输入状态更加稳定
    即便不加这一点,原本的逻辑也能运行,但为了提高健壮性与一致性,仍然加以补充。


对当前方案的感受

我们对目前的移动逻辑并不感到困扰,甚至可以说已经达到了一个较为满意的状态:

  • 虽然不能确认这是否是最终理想的行为方式,但整体上来看,它已经足够接近预期;
  • 参考初代《塞尔达传说》,我们记得那款游戏确实并不支持对角线移动,只能上下左右四个方向进行控制;
  • 当前的系统行为更像是在向那种经典的“只支持正交方向移动”的风格靠近,这也是我们目前所希望探索的路线。

当前成果概括

  • 控制逻辑更加严谨,确保了只在水平方向或垂直方向移动;
  • 移动响应清晰,玩家输入后不会造成奇怪的多向运动或视觉偏移;
  • 保持了复古动作类游戏的一贯操作方式;
  • 为之后美术、动画和格子系统的精确对齐提供了更稳固的基础。

后续计划

当前的实现效果已经基本令人满意,我们会在剩余时间里继续推进其它细节优化。由于本次开发起步较晚,仍有10到20分钟左右可用于接下来的工作安排,因此我们打算继续处理其它关键模块,为后续集成奠定基础。

game_world_mode.cpp:清理控制器代码

我们目前主要对角色键盘输入的处理逻辑进行了优化和补强,目的是提升玩家操控角色时的响应连贯性和逻辑合理性,特别是解决在快速或同时多方向操作时产生的不一致行为。


角色输入行为优化核心内容如下:

1. 输入优先级改进:
  • 当玩家同时按下两个方向键(例如左和右)时,以最后被按下的按键为当前移动方向;
  • 如果玩家放开了其中一个方向键,但另一个方向键仍然处于按下状态,角色将自动沿剩余按下的方向继续移动;
  • 这意味着“最新有效输入”始终优先,防止角色在操作时“卡壳”或原地停顿。
2. 修复输入释放后的移动丢失问题:
  • 原先如果玩家同时按住两个方向键,然后松开其中一个,有时角色不会继续移动,哪怕另一个方向键仍然处于按下状态;
  • 为此,逻辑上补充了当“当前活动方向键被释放”时,检查另一个方向键是否仍然按下,若是则切换方向继续移动;
  • 这样可以提升键盘输入的容错率,改善键盘操作中“转向不灵”或“角色瞬停”的体验。

关于“吸附至路径”的思考:

  • 曾经实现过一版“吸附进路径中心线”的功能,让角色自动对齐至网格轴线中心(例如:行走时逐步偏移到所在行或列的中心);
  • 实测后发现该机制在操作上感觉不够自然或有些别扭,所以目前暂时没有启用该功能;
  • 当前没有完全排除未来再引入“吸附机制”的可能,但目前的判断是,保留玩家原始方向控制的自由度更符合直觉操作体验。

👁 关于艺术资源对实际效果的影响:

  • 当前的大多数视觉问题,如角色在路径边缘出现偏离感,或动作不连贯,预计将在美术资源最终就绪后自然解决
  • 例如:角色贴图调整、更精细的动画、人物在不同方向的视觉补偿等,都能缓解当前的一些不完美。

当前状态总结:

  • 键盘输入逻辑更接近最终游戏行为,输入更连贯且合理;
  • 操作行为更具容错性,能正确处理按键组合与释放的复杂情况;
  • 避免了输入状态卡住或角色原地停顿的状况;
  • 对未来整合美术资源及进一步优化动作系统打下坚实基础;
  • “吸附机制”目前搁置,以维持操作自然性为优先。

整体来说,我们对当前控制系统的状态感到满意,后续将继续在此基础上进行美术集成、碰撞检测等方面的进一步开发。

运行游戏并尝试控制器代码

我们进一步验证了输入控制逻辑的细节,尤其是关于同时按下多个方向键时的优先级判断按键释放后的行为响应,确保在实际操作中角色能按预期做出反应。


当前输入控制行为的测试与确认:

1. 测试场景示例:
  • 持续按住右方向键的同时,轻点一下上方向键
  • 我们预期角色只在按下上方向键的瞬间有一个“向上”的小移动,但随后仍应保持向右移动
  • 该场景是对“输入优先级”与“键盘状态恢复”的一次验证。
2. 行为符合预期:
  • 角色会在上方向键被短暂按下时响应移动,然后继续执行原本按住的右方向键动作;
  • 表明当前输入系统正确处理了短时优先输入持续输入状态的衔接
  • 说明系统能在多方向混合输入中有效管理按键状态,并做出预期合理的反应

背后机制说明:

  • 系统会记录所有方向键当前的“按下”与“释放”状态;
  • 每次输入更新时,会优先响应“最近被按下的有效方向”;
  • 若某个方向键被释放,系统会自动查找是否有其它仍在按下的方向,并恢复执行剩余的方向输入
  • 避免了角色在某个键释放时进入停滞状态,确保连续性与稳定性

重要性:

  • 这种输入处理策略对于动作类游戏尤其关键,确保角色响应灵敏,不会因为复杂操作组合而“卡住”或做出错误动作;
  • 同时也让玩家可以通过快速敲击方向键做出精准控制,提升游戏的操作体验与手感质量。

目前我们对这部分逻辑实现感到满意,功能已符合设计意图,后续可以安心将更多精力投入到碰撞系统、动画整合和地图逻辑等更高层的系统构建中。
在这里插入图片描述

在这里插入图片描述

game_world_mode.cpp:重新启用头部的重新定位代码

我们重新回到了角色“居中吸附”逻辑的问题上,进行了一些新的尝试与优化思考,目标是让角色在贴近网格中心时的表现更加自然、不突兀,尤其是在出现对角线偏移时提升体验。


问题背景回顾

  • 当前系统中存在一种“吸附回格子中心”的机制(居中吸附),用以避免角色偏离网格中心过多;
  • 该机制原本在“无方向输入”时立即触发,使角色自动平滑回到网格中心;
  • 但在实际操作中,当角色刚好处于格子之间、并试图对角线运动时,这种机制显得突兀,会打断移动的流畅性,体验不佳。

解决策略:延迟吸附机制(基于定时器)

我们提出了一种改进方案 —— 引入计时器来延迟触发“吸附中心”的逻辑,以避免立即拉回导致的视觉或控制突兀:

实现步骤:
  1. 定义计时器变量:

    • 为每个实体(如角色)添加一个 recenter_timer
    • 该变量用于记录剩余时间,表示多久后才允许触发居中吸附逻辑。
  2. 判断吸附条件:

    • 仅在满足以下任一条件时才触发吸附:

      • 当前处于“无方向输入”状态;
      • recenter_timer 值为 0,表示计时已到。
  3. 每帧更新计时器:

    • 在主逻辑循环中,每一帧对 recenter_timer 执行:

      recenter_timer = max(0, recenter_timer - delta_time)
      
    • 即:不断减去经过时间,但不会低于 0;

    • 这样可以控制吸附触发的节奏,避免刚松开按键就立即被吸回中心。

  4. 辅助数学函数:

    • 使用 clamp 工具函数来保证 timer 不会小于 0:

      float Clamp(float value, float min, float max) {return (value < min) ? min : (value > max) ? max : value;
      }
      
    • 确保逻辑安全稳定。


效果与意义

  • 手感更加平滑自然:当角色刚松开一个方向键,系统不会立刻将其拉回中心,而是给予一点“缓冲时间”;
  • 对角移动时更可控:避免一松手就被系统强制吸附打断了流畅移动;
  • 易于调参:通过调整 recenter_timer 初始值可以灵活控制吸附延迟长度,便于后期微调体验;
  • 更贴近玩家预期:不会对输入行为作出“过度反应”,保持操作逻辑一致性。

当前状态

此方案逻辑已清晰,并已着手添加相关代码结构与数学支持函数,后续将进一步测试实际体验表现,确认吸附延迟是否能显著提升用户体验,尤其是在复杂地形与快速移动时的表现。整体对该思路感到满意,认为是朝着正确方向优化的一步。

game_math.h:引入ClampAboveZero

我们在实现居中吸附逻辑时,为了提升移动流畅性,引入了一个新的机制:定时器控制的“延迟居中吸附”功能。该功能允许在玩家输入操作后的短暂时间内,暂时抑制自动居中逻辑,从而避免突兀的“吸附回格子中心”效果。


核心实现细节

1. clamp_above_zero 函数

我们先实现了一个简洁的实用函数:

float ClampAboveZero(float value) {return value < 0 ? 0 : value;
}

这个函数的作用是确保一个数值不能低于 0。它被用来处理定时器的倒计时逻辑,避免计时器进入负数。


2. 添加 recenter_timer

我们为玩家控制结构添加了一个新字段:

  • recenter_timer

    • 这是一个计时器,表示下一次允许触发居中吸附之前的剩余时间
    • 初始值为 0,意味着如果没有其他输入,就允许吸附逻辑立即触发。

3. 控制定时器更新逻辑

每一帧更新过程中,加入如下逻辑:

recenter_timer = ClampAboveZero(recenter_timer - delta_time);
  • delta_time 表示每一帧的时间增量;
  • 每帧减少计时器值,倒计时完成后(变为 0)即允许再次吸附。

4. 在输入事件中重置定时器

当玩家执行任何方向键输入(如向上、向左、向下、向右)时:

recenter_timer = recenter_delay;
  • 其中 recenter_delay 是一个设定值(如 0.5 秒),表示延迟吸附的时间长度;
  • 每次新输入发生时就会刷新该计时器,从而“延缓”居中吸附的发生。

5. 属性位置设计
  • recenter_timer 最终被放置在了控制器结构体中(例如 hero_control),而不是实体对象本身;
  • 理由是这个字段本质上属于玩家控制行为的一部分,而非角色物理或逻辑状态;
  • 因此,适合在 handmade 模块中定义而非 sim_region 中。

功能意义与效果

  • 避免过早吸附:玩家松开方向键之后不会立即被系统强行吸附,而是给予一定反应缓冲;
  • 提升控制流畅性:特别是在网格交界处或斜向移动时,角色不会突然被拽向中心;
  • 易于调节体验:通过修改 recenter_delay,可以自由调整吸附“惰性”程度;
  • 保持整洁性:逻辑清晰地分布在输入处理和控制器更新中,不影响其他模块结构。

当前状态总结

  • 居中吸附延迟机制已完成基本实现;
  • 输入触发、定时器更新和逻辑判断等流程已整合完毕;
  • 后续可进一步测试实际手感、调整吸附延迟时长,或根据美术资源再做微调。

这一机制为角色运动增加了更多控制的柔性,使整体操作更自然、更符合玩家期望。
在这里插入图片描述

运行游戏并尝试延迟重新定位

我们对角色在网格中的“自动居中吸附”逻辑进行了测试和微调,以下是详细的调整过程与当前实现状态总结:


居中吸附机制运行效果测试

运行程序后,居中吸附功能可以正常生效,表现为:

  • 角色在接近网格中心时,会被“慢慢地吸附”回到格子中心;
  • 这种吸附是在延迟计时器结束后才会开始生效;
  • 通过这种方式,即使玩家在两个格子间边缘来回移动,角色也会在松开按键之后被缓慢修正到对齐的位置。

系数调整与手感评估

我们尝试了不同的“吸附强度”参数设置,感受其对玩家操作流畅性的影响:

  1. 强吸附(高系数)

    • 吸附效果明显加快;
    • 玩家在移动过程中被快速拉向中心;
    • 手感非常不自然,甚至有些生硬;
    • 结论:不可取。
  2. 弱吸附(低系数)

    • 吸附效果非常缓慢;
    • 几乎察觉不到吸附发生;
    • 角色仍可“漂浮”在两个格子的边缘;
    • 结论:虽然吸附不明显,但至少没有打扰玩家操作,手感尚可接受。

当前选择与理由

我们决定使用非常微弱的吸附系数,理由如下:

  • 吸附发生得足够慢,不干扰玩家原意;
  • 在操作空隙期能“悄悄修正”位置,提升美观性和规范性;
  • 不会引起突兀的拉动或错觉;
  • 在不经意间提升整体角色运动的整洁度;
  • 保持系统扩展性,后续仍可通过参数快速调整吸附策略。

关于边缘行为与玩法合理性

尽管目前仍然存在个别“边缘跳动”的情况(即角色在两个格子中间“跳动”或不完全对齐),我们认为这在实际游戏中问题不大:

  • 玩家在普通游玩时,通常会有意识地对齐至特定格子;
  • 玩家多数时间关注的是具体踩在哪个格子上,避免碰触危险地形或敌人;
  • 没有动机去故意停留在模糊区域;
  • 因此这种偶发的中间状态不会对游戏流程或体验造成实质性影响。

当前进度总结

  • 居中吸附逻辑功能完整;
  • 加入延迟机制,提升操作流畅性;
  • 参数调整到手感合适的范围;
  • 可以应对绝大多数正常游玩情况;
  • 后续若需优化仍有空间,例如:不同速度下的自适应吸附、不同场景吸附力度自定义等。

我们决定暂时保留当前实现方式,作为初步版本继续使用,等待进一步测试与美术资源整合后再评估是否需要进一步改动。

问答环节

你认为像基于节奏的移动(例如英雄需要等一会儿才能再次移动,假设他准备跳跃,而不是不停地跳跃)会帮助解决这个问题吗?意识到这是一个设计决策,可能不是你想要的,但或许你没有考虑过这个想法

我们曾考虑过一种节奏型的移动机制,即角色每次移动之间需要等待片刻,比如模拟“蓄力跳跃”的感觉,而不是无休止地连跳不停。这种方式在某些游戏中是合理的,比如以战术节奏为核心设计的游戏,但在当前的系统中,我们认为它并不特别适用。


移动节奏机制的潜在设计意图

  • 通过引入节奏,限制角色的连续快速移动;
  • 可以让每次移动看起来更有权重、更具“准备”感;
  • 避免角色在格子间“胡乱跳动”;
  • 在某些风格或题材下(如战术策略、回合制或精密动作类)是非常合适的。

为什么我们没有采纳这种方式

  1. 与当前玩法目标冲突

    • 当前系统追求的是即时响应的动作体验
    • 玩家一旦输入方向指令,就应立刻反馈;
    • 强节奏限制会让移动变得拖沓、间断,不符合整体手感。
  2. 操作节奏不自然

    • 游戏不是基于节奏或蓄力的风格;
    • 强制节奏限制可能引起玩家挫败感,尤其在需要躲避、穿越敌人或解谜机关时;
    • 节奏型移动会破坏直觉性。
  3. 已有机制可以缓解移动混乱

    • 当前系统通过“居中吸附”“禁止对角移动”等机制,已经大幅减少了格子间模糊跳跃的情况;
    • 手感相对稳定,无需再加入额外约束。

结论

虽然节奏型移动机制在某些游戏类型中是合适的(如《Crypt of the NecroDancer》或某些战棋类作品),但我们当前的系统需要更自由、立即、响应迅速的移动方式。我们认为这种方式不适合目前的设计方向,因此并未采用。

这种探索是合理的,也说明了在系统设计中,我们不断在响应速度与控制精准之间寻找平衡。当前的实现通过其他方式已解决了主要问题,无需加入强节奏限制。

你认为旋转躯干会有所帮助吗?

目前来看,旋转躯干的方式并不会真正帮助我们解决问题。我们观察了一些移动表现不理想的案例,发现大多数问题并不是发生在角色左右移动的过程中,而是在上下方向移动时出现较明显的视觉错位。因此,从设计角度来说,即使实现了角色的身体旋转,似乎也无法有效改善这种特定的移动问题。


问题的核心集中在上下移动时的视觉错位

  • 当角色向上或向下移动时,图像位置会出现明显的“滞后”或“错位”感;
  • 这种视觉上的不自然不是因为缺少方向朝向,而是源于图像投射角度的问题;
  • 左右移动中,这种错位感较轻微,几乎不会造成困扰。

更合适的解决方式

  1. 采用更垂直的俯视视角

    • 将角色美术资源从更“上方”的角度进行绘制,减少视觉偏移;
    • 俯视角更适合基于格子系统的动作游戏,减少位置不明确的问题;
    • 可以避免由于头身比例与透视带来的偏移现象。
  2. 尽量减少图像在不同方向上的共用

    • 不同方向的移动应当尽可能使用单独绘制的图像;
    • 特别是上下方向,应使用专门的上下移动帧来避免“后脑勺移动”的错觉;
    • 减少“镜像翻转”代替方向表现的做法,有助于保持视觉一致性。
  3. 配合已有的吸附回正机制

    • 利用吸附到格子中心的机制进一步避免角色“漂移”到视觉上的奇怪位置;
    • 这一机制已经实现基础功能,可以缓解因图像错位导致的误判感。

小结

目前的问题更偏向视觉表现与动画视角的问题,而非控制逻辑或方向处理的问题。因此,旋转角色躯干来匹配方向并不能真正解决症结所在。我们更倾向于通过优化美术资源、视角设计和吸附机制的配合,来根本上提升移动过程中的视觉自然度与游戏手感。

尝试使用贝塞尔曲线包围身体,而不是只是线性拉伸?

对于将角色的身体使用贝塞尔曲线进行包裹的建议,当前并不觉得这是一个有效的解决方案。问题的关键并不是我们要选择将身体某一部分(例如脖子)进行伸展,而其他部分保持不变。实际上,当前并没有明确的部分需要单独伸展或不伸展。


当前问题的核心

  • 角色的身体并不具备可以单独伸展或不伸展的明确部分,整体的动画效果并不需要在局部进行调整;
  • 贝塞尔曲线通常用于处理平滑的曲线形状,常见于形状插值等应用,但在当前这种情况下,不认为其能够有效解决角色动作过程中的视觉错位问题;

结论

在这个问题中,贝塞尔曲线并没有直接的应用场景,无法有效解决我们遇到的视觉错位或不自然移动的问题。因此,更应关注优化视角设计美术资源动画的整体协调性,而非通过局部的曲线包裹来处理角色动作。

对于上下运动,是否可以放弃拉伸,而让每个部件进行跳跃?

对于上下运动的问题,考虑到可以放弃拉伸,而让每个部分单独跳跃。这种做法可能意味着每个身体部分(如头部、躯干、四肢)在跳跃时独立运动,而不是整个身体一起拉伸。这样做可以避免身体的不自然弯曲或者拉伸,保持每个部位的独立运动性。

至于为什么不进行剪切(shear)操作,剪切通常意味着在移动过程中,物体的各个部分会沿着某个方向发生变形,导致不自然的外观,尤其是在人物角色的运动过程中,剪切可能使角色看起来失衡或者过度拉伸。因此,在这个上下运动的场景下,避免剪切有助于让角色保持更自然的动作表现。

为什么不让脚部顶部的剪切保持在移动的身体下方?

关于保持脚部在移动身体下方的问题,因为角色没有脚部,所以这里并不是在讨论脚部,而是在谈论躯干的底部。即使角色是没有肢体的,躯干的底部(如果是指“底部”)也需要保持固定在原地,不会随着上半身的移动而改变位置。因此,不能用“剪切”这种方式来保证底部跟随身体移动。

如果是讨论如何保持角色的底部(例如躯干的下部)与地面接触并保持稳定,确保角色在运动时,底部的定位位置应该是固定的,只有上半身或其他部分在移动。这样可以避免角色出现不自然的变形或者失衡的感觉。

跳跃前后身体进行小范围平移如何?比如10%-20%的相邻点间距离

关于在跳跃前后加入身体的小幅过渡(比如跳跃距离的10%到20%),这是一个有趣的想法。虽然目前不确定是否适用,因为不希望角色的动作感觉不稳定或“脱离地面”,但如果过渡的幅度足够小,也许可以帮助提升跳跃的流畅性,而又不会让它感觉不接地气。因此,确实可以尝试这种方法,看看它是否能带来某种有益的效果。

如果做出位移的调整,或许可以在跳跃过程中加入一点过渡,让动作变得更自然,同时保持角色的稳定感。

game_world_mode.cpp:根据头部距离最近可行点的距离移动身体

为了测试跳跃中的位移效果,可以通过在头部的位移基础上添加一个系数来实现。例如,当角色站在地面上时,可以通过计算头部的位移(head Delta)来产生跳跃时的位移。通过简单地在原位置基础上加上系数乘以头部的位移,尝试改变角色跳跃时的行为。

然而,测试中发现这种方法可能会导致额外的反弹效果,原因可能是在计算过程中头部位移的方向出现了预期之外的变化。这种问题通常发生在对位移计算的处理不够精准或理解上的差异。因此,需要检查并调整跳跃时位移的处理逻辑,确保它与其他部分的计算不冲突。

为了避免这个问题,可以考虑在跳跃的处理过程中对位移进行合理的约束。比如,设置位移的值不能小于0,或者对位移的变化施加一个衰减效果,使得跳跃后的位移逐渐恢复到零,这样就可以避免突兀的跳跃效果。

通过这种方法,角色的跳跃效果将变得更加自然且连贯,同时避免了跳跃时产生过多不必要的位移反应,确保角色的控制和动作流畅。

在这里插入图片描述

运行游戏并查看位移效果

通过调整位移的计算方法,能够观察到跳跃时角色的位移效果发生了变化,但这种变化不太显眼,可能并没有明显改善跳跃的感觉。考虑到这一点,可以尝试增加位移的值来测试是否能够获得更好的效果。尽管目前的调整并不十分显著,但可以进一步尝试调整这些参数,看看是否能够找到更加理想的效果。

总体来说,尽管效果不够明显,但这种调整已经开始起到作用,可能需要进一步细化参数来提高其表现。

效果不行

在这里插入图片描述

game_world_mode.cpp:只对斗篷应用地面位移

只对披风应用地面位移,而不对其他部分应用这个偏移量,似乎是一个合理的思路。也就是说,可以选择仅对披风进行偏移调整,而不影响角色的其他部分。这样可以保持角色的主体不受影响,同时让披风在跳跃或移动时呈现出自然的位移效果。
在这里插入图片描述

在这里插入图片描述

运行游戏并查看斗篷位移效果

可以考虑通过调整角色的身体宽度来避免出现躯干穿透的情况。通过将躯干缩小或改变其形状,可能有助于消除这一问题,避免不自然的视觉效果。这样做可能会让角色的外观更加协调,避免在某些动作中出现不符合预期的表现。

@我看得越多,我越喜欢这个。我想知道是否轻微的头部晃动会增加可信度。只是个想法

关于游戏中的美感,确实在设计时要考虑细节,比如角色的头部是否应该有微妙的上下摆动(head bob)。虽然这样做可能会让游戏看起来更有动感,提升真实感,但问题在于,角色的头部在游戏中非常重要,必须保持玩家放置的位置不变。因此,目前不希望游戏自动移动头部,除非玩家主动进行控制。尽管我完全同意如果加上头部摆动可能会让游戏更美观,但在当前的开发阶段,希望确保头部的位置完全由玩家控制,避免干扰玩家的操作体验。等到游戏玩法更加完成后,可能会重新评估这个问题,看是否需要加入头部的微小运动。

如果身体保持在瓷砖上,但斗篷位于身体和头部之间,是否有帮助?

我们在之前的讨论中达到了相似的结论。现在,关于我们正在做的工作,问题似乎都已经解决了。接下来,我们主要需要关注的是进一步完善当前的开发任务。

考虑向杨天请求更符合顶视角的艺术资源

为了进一步优化设计,计划让艺术团队提供一些接近当前风格的艺术素材,要求图形更为堆叠且以俯视角度呈现,尽量减少身体角度的变化,保持上身的简洁和宽大。这样可以观察效果并判断是否适合当前的需求。总的来说,这样的调整是合理的,可以尝试并看看效果如何。

或许可以设置一个最小拉伸长度,以防止向下移动时比特图消失?

对于下移时出现消失的位图问题,提出了设定最小拉伸长度的建议,这样可以避免这种情况的发生。对此表示认同,但决定等到实际的艺术素材导入后再进一步评估效果。认为这是一个不错的建议,等到测试之后再决定是否实施。

相关文章:

游戏引擎学习第276天:调整身体动画

运行游戏&#xff0c;演示我们遇到的拉伸问题&#xff0c;看起来不太好&#xff0c;并考虑切换到更顶视角的视角 我们开始讨论游戏开发中的一些美学决策&#xff0c;特别是在处理动画方面。虽然我们是游戏程序员&#xff0c;通常不负责设计或艺术部分&#xff0c;但因为这是一…...

Java线程池性能优化全解析:从配置到实践

一、线程池配置原则 1.1 核心参数设定 线程池的性能优化始于合理配置,关键参数包括: 核心线程数(corePoolSize) CPU密集型任务:设为Runtime.getRuntime().availableProcessors()(通常为CPU核心数)IO密集型任务:设为CPU核心数 * 2(或更高,根据IO等待时间调整)最大线…...

【入门】歌德巴赫猜想

描述 任一个大于等于4的偶数都可以拆分为两个素数之和。 输入描述 一个整数n( 4 < n < 200 &#xff09; 输出描述 将小于等于n的偶数拆分为2个质数之和&#xff0c;列出所有方案&#xff01; 用例输入 1 10 用例输出 1 422 633 835 1037 1055 #include<b…...

kafka----初步安装与配置

目录标题 ⭐kafka 与 zookeeper间的关系一.集群部署二.修改配置文件三.分发安装包四.启动与关闭 kafka 与 zookeeper 相同&#xff0c;是以集群的形式使用 ⭐kafka 与 zookeeper间的关系 kafka 的使用 要在 zookeeper 集群配置好的基础上 使用要想启动kafka 要先启动 zookeep…...

如何通过 Windows 图形界面找到 WSL 主目录

WSL(Windows Subsystem for Linux)是微软开发的一个软件层,用于在 Windows 11 或 10 上原生运行 Linux 二进制可执行文件。当你在 WSL 上安装一个 Linux 发行版时,它会在 Windows 内创建一个 Linux 环境,包括自己的文件系统和主目录。但是,如何通过 Windows 的图形文件资…...

Cursor 编辑器 的 高级使用技巧与创意玩法

以下是针对 Cursor 编辑器 的 高级使用技巧与创意玩法 深度解析,涵盖代码生成优化、工作流定制、隐藏功能等层面,助你将 AI 辅助编程效率提升至新高度: 一、代码生成进阶技巧 1. 精准控制生成粒度 行级控制: 在代码行内用 // > 指定生成方向(替代模糊注释)def merge_…...

element-ui 源码调用接口跨域问题

今天在看 upload 组件源码时&#xff0c;在组件源码当中调用的本地启动的 nodejs 服务写的上传接口&#xff0c;遇到跨域问题&#xff1a; 问题一、在 upload.md 中调用 nodejs 服务中的 上传接口&#xff0c;控制台报跨域报错。 解决方法1&#xff1a;在根目录增加 vue.conf…...

Docker与PostgreSQL

1. 背景介绍 Docker是一种开源的容器化技术&#xff0c;它通过使用容器来隔离应用程序及其运行环境&#xff0c;使得开发人员能够快速、可靠地构建、部署和运行应用程序。Docker容器是轻量级的虚拟化单元&#xff0c;能够在任何支持Docker的操作系统上运行&#xff0c;从而消除…...

iVX 研发基座:大型系统开发的协作与安全架构实践

通过图形化开发、组件化封装和多厂商协作机制&#xff0c;iVX 解决了传统开发模式在效率、安全和扩展性上的痛点。文章结合政务、教育、企业等行业案例&#xff0c;展示其在数据治理、权限控制和 DevOps 等方面的创新实践&#xff0c;为大型系统开发提供完整的技术参考。 一、…...

Vxe UI vue vxe-table 实现表格数据分组功能,不是使用树结构,直接数据分组

Vxe UI vue vxe-table 实现表格数据分组功能&#xff0c;不是使用树结构&#xff0c;直接数据分组 查看官网&#xff1a;https://vxetable.cn gitbub&#xff1a;https://github.com/x-extends/vxe-table gitee&#xff1a;https://gitee.com/x-extends/vxe-table 代码 通过…...

基于TI AM6442+FPGA解决方案,支持6网口,4路CAN,8个串口

TI AM6442FPGA解决方案具有以下技术优势及适用领域&#xff1a; 一、技术优势 ‌异构多核架构‌&#xff1a;AM6442处理器集成7个内核&#xff08;2xCortex-A534xCortex-R5F1xCortex-M4F&#xff09;&#xff0c;可实现应用处理、实时控制和独立任务分核协同&#xff0c;满足…...

6. 多列布局/用户界面 - 杂志风格文章布局

6. 多列布局/用户界面 - 杂志风格文章布局 案例&#xff1a;多栏杂志排版 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title></head><style type"text/css">body {font-family: "…...

计算机系统----软考中级软件设计师(自用学习笔记)

目录 1、计算机的基本硬件系统 2、CPU的功能 3、运算器的组成 4、控制器 5、计算机的基本单位 6、进制转换问题 7、原码、反码、补码、移码 8、浮点数 9、寻址方式 10、奇偶校验码 11、海明码 12、循环冗余校验码 13、RISC和CISC 14、指令的处理方式 15、存储器…...

FPGA图像处理(六)------ 图像腐蚀and图像膨胀

默认迭代次数为1&#xff0c;只进行一次腐蚀、膨胀 一、图像腐蚀 1.相关定义 2.图像腐蚀效果图 3.fpga实现 彩色图像灰度化&#xff0c;灰度图像二值化&#xff0c;图像缓存生成滤波模块&#xff08;3*3&#xff09;&#xff0c;图像腐蚀算法 timescale 1ns / 1ps // // Des…...

2025年RIS SCI2区,改进白鲸优化算法+复杂非线性方程组求解,深度解析+性能实测

目录 1.摘要2.白鲸优化算法BWO原理3.改进策略4.结果展示5.参考文献6.代码获取7.读者交流 1.摘要 本文提出了一种改进白鲸优化算法&#xff08;ABWOA&#xff09;用来解决非线性方程组&#xff08;SNLEs&#xff09;求解问题。ABWOA引入了平衡因子和非线性自适应参数&#xff0…...

【论信息系统项目的资源管理】

论信息系统项目的资源管理 前言一、规划好资源管理&#xff0c;为保证项目完成做好人员规划二、估算活动资源&#xff0c;为制订项目进度计划提供资源需求三、获取项目资源&#xff0c;组建一个完备的项目团队四、建设项目团队&#xff0c;提高工作能力&#xff0c;促进团队成员…...

开发与AI融合的Windsurf编辑器

Windsurf编辑器是开发人员和人工智能真正融合在一起的地方&#xff0c;提供了一种感觉像文字魔术的编码体验。 手册&#xff1a;Windsurf - Getting Started 下载链接&#xff1a;Download Windsurf Editor for Windows | Windsurf (formerly Codeium) 下载安装 从上面的下载…...

maven工程跳过@SpringTest

每次跑springboot都比较费劲&#xff0c;会自动测试所有的SpringBootTest的类&#xff0c;这里对根pom添加这个插件&#xff0c;即可跳过测试&#xff0c;实测节省时间2分钟以上 <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>ma…...

算法竞赛相关 Java 二分模版

目录 找和目标值相关 方法 Arrays.binarySearch(); 二分答案模版 找和目标值相关 public class BinarySearchTemplate {// 查找大于 x 的最小值&#xff08;即严格上界&#xff09;public static int upperBound(int[] arr, int x) {int left 0, right arr.length;while (…...

如何使用远程桌面控制电脑

目的&#xff1a; 通过路由器使用pc控制台式机&#xff0c;实现了有线/无线pc与台式机的双向远程桌面控制 最核心就两条&#xff1a;get ip地址与被控制机器的账户与密码。 现象挺神奇&#xff1a;被控制电脑的电脑桌面处于休眠模式&#xff0c;此时强行唤醒被控电脑会导致中断…...

运行Spark程序-在shell中运行1

&#xff08;一&#xff09;分布式计算要处理的问题 【老师提问&#xff1a;分布式计算要面临什么问题&#xff1f;】 【老师总结】 分布式计算需要做到&#xff1a; 1.分区控制。把大的数据拆成一小份一小份的&#xff08;分区&#xff0c;分片&#xff09;让多台设备同时计算…...

多边形,矩形,长方体设置

在cesium中,我们可以通过既有的库来进行对地图的构建 // 向场景中添加一个几何体&#xff08;立方体&#xff09; scene.primitives.add(new Cesium.Primitive({// 定义几何体实例geometryInstances: new Cesium.GeometryInstance({// 使用BoxGeometry.fromDimensions方法创建…...

3.3 阶数的作用

第一步&#xff1a;引入背景与动机 在数学中&#xff0c;特别是在使用泰勒公式进行函数近似时&#xff0c;阶数的选择对结果的精度和适用范围有着重要影响。阶数越高&#xff0c;近似的精度通常也越高&#xff0c;但计算复杂度也会增加。因此&#xff0c;理解不同阶数的作用及…...

OAuth安全架构深度剖析:协议机制与攻防实践

目录 一、OAuth协议核心架构解析 1. 协议框架与核心组件 2. 授权流程类型对比 二、OAuth安全漏洞技术原理与攻击向量 1. 重定向URI劫持攻击 2. 令牌注入与滥用 3. 跨站请求伪造&#xff08;CSRF&#xff09; 三、纵深防御体系构建指南 1. 协议层加固 2. 工程化防护 3…...

关于网站提交搜索引擎

发布于Eucalyptus-blog 一、前言 将网站提交给搜索引擎是为了让搜索引擎更早地了解、索引和显示您的网站内容。以下是一些提交网站给搜索引擎的理由&#xff1a; 提高可见性&#xff1a;通过将您的网站提交给搜索引擎&#xff0c;可以提高您的网站在搜索结果中出现的机会。当用…...

一文理清人工智能,机器学习,深度学习的概念

目录 一、人工智能的起源与核心范畴&#xff08;1950-1980&#xff09; 1.1 智能机器的最初构想 1.2 核心范畴的初步分化 二、机器学习的兴起与技术分化&#xff08;1980-2010&#xff09; 2.1 统计学习的黄金时代 2.2 神经网络的复兴与子集定位 2.3 技术生态的形成与AI…...

MySQL 数据库:创建新数据库和数据表全攻略

MySQL 数据库&#xff1a;创建新数据库和数据表全攻略 在 MySQL 数据库管理中&#xff0c;创建新的数据库和数据表是基础且关键的操作。无论是开发新的应用程序&#xff0c;还是对现有数据进行整理和存储&#xff0c;都离不开这些操作。本文将详细介绍如何在 MySQL 中创建新数…...

React Native 与 Expo

&#x1f9e9; Expo 和 React Native 的关系 项目定义React Native一个由 Meta&#xff08;Facebook&#xff09;开发的原生移动端开发框架&#xff0c;使用 JavaScript React 来构建 iOS 和 Android 应用Expo一个构建在 React Native 之上的开发工具链&#xff0c;封装了很多…...

【RabbitMQ】七种工作模式介绍

文章目录 1. 简单模式2. 工作队列模式3. 发布订阅模式交换机类型 Publish/Subscribe 模式 4. Routing&#xff08;路由模式&#xff09;5. Topics&#xff08;通配符模式&#xff09;6. RPC&#xff08;RPC 通信&#xff09;7. Publisher Confirms&#xff08;发布确认&#xf…...

【C++进阶篇】二叉搜索树的实现(赋源码)

掌握二叉搜索树&#xff1a;从基础知识到实际应用的全貌 一. 二叉搜索树简介1.1 基本概念1.2 意义与价值1.3 典型应用场景1.4 性能分析1.5 总结与展望 二. 搜索二叉树实现2.1 插入2.2 查找2.3 删除2.3.1 单或无孩型2.3.2 双孩型2.3.4 整合代码 三. ⼆叉搜索树key和key/value使⽤…...

LLMs 其他 Trick

huggingface 下载不了模型问题&#xff1f; from modelscope.hub.snapshot_download import snapshot_download model_dir snapshot_download(damo/nlp_xlmr_named-entity-recognition_viet- ecommerce-title, cache_dirpath/to/local/dir, revisionv1.0.1) 方法一&#xff1…...

2025年金融创新、区块链与信息技术国际会议(FRCIT 2025 2025)

2025 International Conference on Financial Innovation, Regional Chains, and Information Technology &#xff08;一&#xff09;会议信息 会议简称&#xff1a;FRCIT 2025 大会地点&#xff1a;中国郑州 收录检索&#xff1a;提交Ei Compendex,CPCI,CNKI,Google Schola…...

rtty操作记录说明

rtty操作记录说明 前言 整理资料发现了几年前做的操作记录&#xff0c;分享出来&#xff0c;希望对大家有用。 rtty-master&#xff1a;rtty客户端程序&#xff0c;其中buffer\log\ssl为源码的子目录&#xff0c;从git上下载https://github.com/zhaojh329&#xff0c; rtty…...

股指期货是什么?有啥特点?怎么用?

股指期货&#xff0c;英文简称SPIF&#xff0c;全称是股票价格指数期货&#xff0c;也叫股价指数期货、期指。简单来说&#xff0c;它就是以股价指数为“赌注”的一种期货合约。想象一下&#xff0c;你和朋友打了个赌&#xff0c;约定在未来的某个日子&#xff0c;按照事先说好…...

提示词设计模板(基于最佳实践)

1. 任务清晰化 模糊指令 ➜ 明确指令 ❌ "写一篇关于环保的文章" ✅ *"列出5种城市环保措施&#xff0c;并分别说明其对减少碳排放的影响&#xff08;要求&#xff1a;数据支持案例&#xff09;"* 2. 任务步骤化 案例&#xff1a;策划线上营销活动 1.…...

涌现理论:连接万物的神秘力量

一、理论起源与概述 现象引介&#xff1a;通过蜂群“风浪”&#xff08;蜜蜂抖动翅膀呈波浪式扩散&#xff09;、鱿鱼变色捕猎等生物现象&#xff0c;引出涌现理论。理论定义&#xff1a;涌现理论可有效介入复杂问题&#xff0c;解释事物起源&#xff0c;适用于物理、化学、生…...

9.9 Ollama私有化部署Mistral 7B全指南:命令行交互到API集成全流程解析

Ollama私有化部署Mistral 7B全指南:命令行交互到API集成全流程解析 关键词:Ollama 私有化部署, Mistral 7B 运行, 本地大模型管理, 命令行交互, REST API 集成 一、Mistral 7B 模型特性解析 Mistral 7B 是由 Mistral AI 团队开发的高性能开源大语言模型,在同等参数量级模型…...

【Redis 进阶】缓存

思维导图&#xff1a; 1. 缓存的基本概念 1.1 缓存的实例化解释 以火车站刷身份证为例&#xff0c;身份证存放在皮箱中虽安全&#xff0c;但取用不便&#xff1b;而将其置于衣袋&#xff0c;则显著提高了访问效率。这一过程恰似计算机系统中缓存的运作机制——将常用数据暂存于…...

游戏资源传输服务器

目录 项目简介项目实现nginx配置服务器逻辑图 项目代码简介reactor 模型部分文件传输部分 项目演示视频演示演示分析 项目简介 使用C开发&#xff0c;其中资源存储在fastdfs 中&#xff0c;用户通过http上传或下载资源文件&#xff0c;此项目需要开启nginx中的nginx-upload-mod…...

dockerdesktop 重新安装

1、卸载 dockerdesktop 卸载时&#xff0c;最后一步删除镜像文件 会卡住 取消 2、在资源管理器中将镜像文件路径改名 如&#xff1a;e:\docker 修改 e:\docker1 3、重新安装wsl wsl --shutdown 以管理员身份运行hy.bat pushd "%~dp0" dir /b %SystemRoot%\servic…...

免费实用的远程办公方案​

假如你需要快速检索出远程电脑文件并下载&#xff1f; 假如你需要访问远程电脑的共享文件夹&#xff1f; 假如你需要访问远程电脑的USB设备&#xff0c;例如软件加密狗、调试器、固件烧录器、U盘等&#xff1f; 本篇文章能够解决以上痛点。 这个方案非常实用&#xff0c;也很…...

论文知识总结

参考1 一 Intelligent reflecting surface (IRS)跟RIS区别是什么 Intelligent Reflecting Surface (IRS) 和 Reconfigurable Intelligent Surface (RIS) 在很多情况下所指相同或相近&#xff0c;常被视为同一类技术的不同表述&#xff0c;但在一些特定语境下也有细微区别&…...

WebGIS 开发黑科技:解锁地理信息的新视界

你能想象吗&#xff1f;在我们生活的这个广袤星球上&#xff0c;每一处角落的地理信息&#xff0c;竟能通过网页&#xff0c;以超乎想象的方式呈现在眼前。WebGIS&#xff0c;这个看似神秘的词汇&#xff0c;实则是当下地理信息领域的 “黑科技”。它究竟有何神奇魔力&#xff…...

Postman启动时检测到版本不匹配错误

Postman启动时检测到版本不匹配错误&#xff0c;提示&#xff1a;Version mismatch detected. Looks like youve used a newer version of the Postman app on this system. 找到 C:\Users\AppData\Local\Postman C:\Users\AppData\Roaming\Postman 并删除现有的 postman 文件夹…...

Java Spring MVC -01

SpringMVC 是一种基于 的实现 MVC 设计模式的请求驱动类型的轻量级 Web 框架&#xff0c;属于 Spring FrameWork 的后续产品&#xff0c;已经融合在 Spring Web Flow 中。 First:SpringMVC-01-SpringMVC 概述 SpringMVC 是 Spring 框架的一个模块&#xff0c;用于构建 Web 应…...

遨游5G-A防爆手机:赋能工业通信更快、更安全

在工业数字化转型与5G-A商用进程加速的双重驱动下&#xff0c;中国防爆手机市场正迎来历史性发展机遇。作为“危、急、特”场景通信解决方案服务商&#xff0c;遨游通讯深刻洞察到&#xff1a;当5G-A网络以超高速率、海量连接和毫秒级时延重塑行业生态时&#xff0c;防爆手机这…...

MySQL 8.0 OCP 1Z0-908 51-60题

Q51.Examine this parameter setting: audit_logFORCE_LOG_PERMAENT What effect does this have on auditing? A)It will force the load of the audit plugin even in case of errors at server start.//插件在之前就必须加载完成&#xff0c;只有当插件之前通过 INSTALL PL…...

javax.servlet.Filter 介绍-笔记

1.javax.servlet.Filter 简介 javax.servlet.Filter 是 Java Servlet API 中的一个核心接口&#xff0c;用于在请求到达目标资源&#xff08;如 Servlet 或 JSP&#xff09;之前或响应返回给客户端之前执行预处理或后处理操作。它常用于实现与业务逻辑无关的通用功能&#xff…...

【2025年前端高频场景题系列】使用同一个链接,如何实现PC打开是web应用、手机打是-个H5 应用?

面试情境与问题引入 哈喽大家伙,我是布鲁伊。在前端开发面试中,面试官经常会抛出一些看似简单却能考察多方面能力的问题。"如何实现同一个链接在PC端和移动端展示不同应用?"就是这样一个典型问题。为什么面试官喜欢问这个问题?因为它能同时考察候选人的设备适配…...

GPT 经验

GPT 经验篇 一、gpt源码past_key_value是干啥的&#xff1f;二、gpt onebyone 每一层怎么输入输出&#xff1f;三、bert和gpt有什么区别四、文本生成的几大预训练任务&#xff1f;五、讲讲T5和Bart的区别&#xff0c;讲讲bart的DAE任务&#xff1f;六、讲讲Bart和Bert的区别&am…...