游戏引擎学习第70天
这一节没讲什么主要是关于接下来要干的任务
开发过程概览
我们正在进行最后的总结,并计划接下来的步骤。目前的目标是创建一个包含所有必要组件的游戏引擎原型版本,目的是让这些部分能够协同工作并展现预期效果。通过这一过程,可以实验和探索各部分如何运作,从而明确需求,并为后续实现更强健的系统打下基础。
我们需要一个完整的框架版本,其中所有预期功能都得以体现,这样便可以开始编写实际游戏。如果需要后续添加功能或优化部分代码,也能够在明确需求后进行调整。
通过这一灵活的开发方式,可以快速验证核心概念和设计是否合理。例如,在渲染部分,需要先了解渲染如何在实际中被使用,再优化实现。否则,很可能创建一个无法满足需求或效率低下的系统。同样地,碰撞检测、路径规划等核心系统,也需要通过实验探索明确需求后,再进行系统化优化。
这一过程的核心思想是确保每个模块的初版具备基础功能,并在整体框架中完成测试和验证。只有在了解实际需求后,才开始优化和扩展,避免浪费时间在不必要或不实用的设计上。
目前,我们正在继续完善原型框架,确保各模块之间的协调运行。今天的任务包括检查和整理之前完成的部分,同时探索下一步的改进方向和关键任务。
碰撞规则哈希表的回顾
我们今天的任务是讨论和回顾碰撞规则列表的实现。之前提到,当某个物体与另一个物体发生碰撞时,我们希望能够让物体继续通过而不受阻碍,同时记录下这次碰撞事件。然而,碰撞系统并不需要处理所有的细节,只需要知道碰撞发生的事实。
为了实现这一点,我们创建了一个哈希表,用来添加碰撞规则。具体来说,当两个物体相互接触时,如果碰撞的反应是“不再关心”,那么就将这个规则添加到哈希表中,这样就不会再收到关于这个碰撞的通知。这种方法是否是最佳的,我们还不确定,但目前我们决定尝试这种方式。
这一过程的核心是简化碰撞检测系统,只在碰撞开始时记录事件,而不需要每次都重新处理整个碰撞细节。这种做法让系统能够更高效地运行,尤其是在不需要频繁更新的情况下。
从哈希表中移除碰撞规则的问题
在哈希表的应用中,我们遇到了处理碰撞规则的挑战。具体来说,当我们处理碰撞时,需要考虑到多个碰撞规则的管理。例如,在一个游戏中,像剑这样的物体可能会与不同的实体发生碰撞。每当剑与怪物发生碰撞时,就需要添加一个新的碰撞规则。这导致了一个问题:随着游戏的进行,规则会不断增加,可能会达到成千上万条规则。
因此,问题就在于如何有效地删除这些规则。我们意识到,哈希表本身并不提供直接的机制来清除特定实体的碰撞规则。哈希表的查找操作是基于两个索引和一个实体的,但如果碰撞规则存储在哈希表中,并且需要清除这些规则,就会遇到一个难题:如何在不遍历整个哈希表的情况下找到并移除这些规则。
这个问题的根本在于,哈希表无法有效地处理那些需要删除的碰撞规则,因为我们没有合适的数据结构来支持删除操作。虽然可以通过查找某个实体并逐步删除规则,但这种方法在实际应用中效率低下,因此我们需要改进现有的数据结构,确保能够高效地删除碰撞规则,而不需要每次都搜索整个哈希表。
总结来说,为了更好地管理碰撞规则,需要设计一种新的数据结构,允许在不遍历整个哈希表的情况下,快速删除与特定实体相关的碰撞规则。
一个简单的解决方案,用于快速在哈希表中找到实体的碰撞规则,但目前还没有实现
问题背景:
在哈希表中,如果键是由多个元素(例如a
和b
)组成,那么删除涉及这些元素的条目会变得更加复杂。我们无法单独通过a
或b
来直接定位并删除相关条目。
解决方案:
为了简化删除操作,可以采用以下策略:
存储索引对的两种顺序
- 假设有两个实体
A
和B
,它们分别对应索引i
和j
。我们不仅存储索引对(i, j)
,还存储索引对(j, i)
。 - 这样,无论我们查询的是
(i, j)
还是(j, i)
,都能从哈希表中找到相关的条目,从而简化删除操作。
优势:
- 删除简便:通过存储两个顺序的索引对,可以直接删除
A
和B
相关的所有条目,而不需要考虑它们在哈希表中的顺序。 - 提高查找效率:不管
A
和B
在哈希表中的存储顺序是(i, j)
还是(j, i)
,都能确保我们能够找到并删除相关条目。
挑战与权衡:
- 内存开销:每个条目需要存储两个索引对,这会导致额外的内存消耗。对于大量数据,这可能成为问题。
- 性能和存储的平衡:为了减少内存消耗,可以减少指针存储,但这可能会影响删除操作的效率。因此,需要在内存使用和性能之间找到合适的平衡。
优化方法:
- 双向存储索引:为每对元素存储两个顺序(
(i, j)
和(j, i)
),确保可以在删除时快速找到所有相关条目。 - 空闲列表更新:在删除时,记住空闲列表的顶部位置,并在删除操作完成后,遍历空闲列表,将删除的索引对反向删除,确保所有相关条目都被移除。
示例:
假设我们有哈希表存储两个实体A
和B
,它们分别对应的索引为i
和j
:
-
存储索引对:
- 哈希表中存储:
(i, j)
和(j, i)
。 - 这样,无论
A
和B
是按照(i, j)
顺序还是(j, i)
顺序插入,都能确保哈希表能找到这两个实体。
- 哈希表中存储:
-
删除操作:
- 假设我们要删除
A
和B
。首先记住空闲列表的顶部位置(例如k
)。然后遍历哈希表,找到(i, j)
和(j, i)
,并删除它们。
- 假设我们要删除
-
更新空闲列表:
- 删除
(i, j)
和(j, i)
后,将它们插入空闲列表。 - 遍历空闲列表,并反向删除这些索引对,确保从哈希表中删除所有相关条目。
- 删除
总结:
通过存储索引对的两种顺序,哈希表能高效执行删除操作。即使条目顺序不同,只要存储了这两个顺序,就能确保删除时不会遗漏任何相关条目。尽管这种方法会增加内存消耗,但可以在性能和内存之间找到平衡,简化删除操作。
AddRadiusTo
函数中的一个Bug
在开发过程中,遇到了一个bug,这个问题最初没有引起注意,但幸好有人报告了这个问题。我们当时并没有意识到它,直到它被指出,因为它是一个看起来很不起眼但可能会带来很大影响的错误。
问题出在了我们代码中的一个矩形扩展的逻辑。原本的意图是增加矩形的宽度和高度,但在实现时,由于打字错误,错误地进行了减法运算,而不是加法。虽然在当前使用的场景中,这个错误不会导致问题,因为我们传递的是相同的宽度和高度值,但如果在未来的某些情况下,我们传递了不同的值,这个错误就会导致程序不能正常工作。
幸运的是,检查代码的人发现了这一点,并指出了错误,这避免了在后续开发过程中遇到更严重的影响。虽然这个问题看起来只是一个小小的打字错误,但它确实提醒了我们在编程时,即使是看似简单的细节也要格外注意。
此外,当我们在代码中出现错误时,尤其是在调试过程中,能有人提醒我们是非常有帮助的。虽然调试是一个个人的过程,自己调试时能从错误中学习,但他人的指正能帮助我们更快地发现问题,节省调试时间。这种帮助非常宝贵,特别是在复杂的问题中。
总之,在编程中,错误是不可避免的,即便是最细微的打字错误也可能引发问题。通过及时的沟通与帮助,可以大大提高工作效率,避免错过一些潜在的错误。
关于接下来开发内容的头脑风暴
首先,我们需要处理当前存在的排序问题。现在,物体的绘制顺序没有经过排序,导致某些对象(比如角色)被错误地绘制在树木后面,这显然是没有意义的。虽然这个问题暂时没有对开发进程造成太大影响,但它确实需要在渲染时得到修正。
此外,我们还需要解决关于怪物行为的问题,特别是当怪物死亡时应该触发的行为。这是我们目前需要考虑的一项任务。除了怪物行为外,我们也必须开始规划如何处理更复杂的系统,例如路径发现,碰撞检测等。
在碰撞检测方面,我们目前使用的是碰撞规则,但这些规则是否足够有效呢?比如,在处理压力板等交互物时,是否需要特定的规则来确保只有在第一次踩上去时触发相应的行为?这类问题让我们思考是否应该依赖现有的碰撞规则,还是考虑实现更复杂的几何碰撞检测系统。
此外,我们还需要考虑是否需要为这些规则添加时间窗口,来确保它们能正确地应用和移除。我们可能还需要考虑在不同的碰撞检测场景中采取不同的方式,尤其是在处理物体进入或退出某些区域时。
同时,我们也在思考如何在更复杂的场景中使用这些系统,例如让角色穿越复杂的环境,避免障碍物或其他干扰。这个问题涉及到的路径发现系统可能需要更多的工作和调试,但它可能是我们接下来要解决的一个难题。
最后,我们还需要考虑动画的实现。虽然我们一直将动画放在待办事项的末尾,但它是项目中不可忽视的一部分,我们应该为其分配时间并开始着手处理。
综上所述,我们的任务列表包括修复排序问题、规划怪物行为、改进碰撞检测、实现更复杂的路径发现系统,以及开始进行动画的实现。
待办事项:动画/渲染
我们决定开始处理动画,因为动画会直接影响渲染的过程。动画涉及到多个方面,首先是粒子系统的实现,另外还包括骨骼动画。这些图形效果将为渲染提供动力,因此我们需要先实现动画部分。
在动画的实现过程中,我们需要考虑如何对角色的不同部分进行旋转。当前的位图绘制代码无法支持这一功能,因此我们需要更新绘制代码来适应旋转操作。动画的实现将产生一系列需求,这些需求直接影响渲染工作。
在渲染阶段,我们将面临一些要求,比如缩放和旋转操作。渲染代码必须能够处理这些需求,因此我们计划在渲染前进行最后的动画设置,将动画的实现推迟到接近渲染开始时。这样,我们就可以确保动画和渲染的协调进行,避免过早开始动画造成不必要的处理。
待办事项:游戏逻辑
在实际的编码过程中,游戏的开发将进入一个重要阶段。在这个阶段,可能需要推迟开发实体系统,因为与游戏同时出现的将是能源系统。因此,在这之前,关于实体系统,我们可能只需要关注可扩展性和如何处理它的增长。
在这个过程中,暂时会将一些不太复杂或不执行任何实际操作的实体(比如“小猪”实体)暂时搁置。重点放在能源系统的实现上,因为它将与游戏的其他部分同步发展。
能源系统将在游戏构建过程中逐步出现并演化,成为构建游戏的一部分。在游戏开发的过程中,随着时间的推移,这些系统将不断进化,以满足游戏的需求。
待办事项:基础世界生成
在世界生成中,首先要关注的是创建一个基础的世界框架。当前,生成世界的能力是非常有限的,仅仅能够创建一堆连接的房间。接下来的目标是建立一个基础的世界生成系统,能够生成具有地面覆盖的树木、岩石等元素,而不是将树木排成一条奇怪的线。
这个生成系统的核心目标是让世界看起来更符合实际,尽管我们不会使用复杂的算法,而是以基本的方式放置一些树木、岩石和草地,确保这些元素有合理的布局。这将帮助我们更好地理解世界的构建方式,虽然是粗略的,但至少能确保系统能正常运作。
对于世界生成的代码支持,重点将放在如何实现生成算法以及如何确保不同元素(如树木和岩石)不会重叠,确保背景元素和其他结构能够合理地放置。这些基本的步骤对于确保世界生成系统的有效性和支持其他系统的功能非常重要。
待办事项:AI系统
在世界生成和系统设计中,我们需要处理不同类型的查询和管理相关事物的方式。首先,系统需要支持对物体的发现和代理管理。这包括为那些在世界中有某种代理的物体提供一个概念,帮助理解它们在任何时刻的行为和目标。这些物体可能有一些目标需要完成,或者有其他标准的任务。
为此,我们可能需要设计一个机制,用于管理这些目标和行为,例如通过链表或其他数据结构来存储这些信息。同时,我们还需要考虑在没有特别计划的情况下如何确保这些行为可以正常进行,避免出现不符合预期的情况。需要明确的是,在处理这些行为时要避免任何异常情况,确保系统运作顺畅。
这些设计的核心在于理解物体如何在系统中进行交互和变化,确保我们能够有效地管理每个物体的状态和行为。
待办事项:碰撞检测?
在系统设计中,碰撞检测是一个关键的问题。需要考虑如何有效地处理碰撞事件,确保系统能够在检测到碰撞时进行恰当的反应。与此同时,考虑到健壮性,系统设计必须避免陷入一些复杂的情况或异常,确保在各种条件下都能够稳定运行。
为了实现这一目标,可能需要对碰撞检测的具体实现进行规划,包括如何定义碰撞的条件和处理逻辑。在这一过程中,虽然具体的方法可能尚不明确,但已经认识到这是一个需要关注的重要部分。最终,确保所有要做的事情能够按计划进行,并在列表中明确列出所有关键任务,是设计过程中的重要步骤。
待办事项:每帧实现多个模拟区域
在多路模拟的设计中,每个区域的更新非常重要。通过每单位时间的更新,能够跟踪实体的状态并决定它们是否需要进一步的更新。这个过程包括为每个单独的步骤设置合适的更新机制,确保实体在每个区域内按预期进行模拟。
当玩家靠近时,可能会将多个玩家合并到一个区域中进行模拟。这样可以更加高效地进行处理,尤其是当玩家位于世界的不同地方并逐渐靠近时。合并区域的操作相对简单,能够快速地识别并管理不同区域内的玩家。
此外,需要定期检查和测量这些合并区域的效果,确保模拟过程的准确性和效率。在游戏开发过程中,可能会遗漏一些细节,需要通过不断思考和检查来补充完整,确保系统的设计是完善和高效的。
待办事项:元游戏/存档系统
在游戏设计中,关于是否允许保存游戏的决策非常重要。虽然我们可能不希望玩家在游戏中随时保存进度,但我们可能希望玩家能在某些时候暂时中断游戏,并能够在以后继续游戏。这要求我们考虑如何平衡游戏的流畅性和玩家的需求。
另一个重要因素是崩溃恢复。即使我们在开发过程中消除了所有已知的bug,系统仍然可能因外部因素(如图形驱动程序问题)而崩溃。因此,设计一个能够在游戏崩溃后恢复进度的机制是非常重要的,这样玩家即使在突发情况下也能继续游戏,而不会丢失大量进度。
为了应对这些问题,定期保存游戏进度是一种很好的解决方案。特别是在长时间的游戏过程中,例如扩展到几十小时的游戏时间时,玩家可以避免因为崩溃或错误导致的进度丢失。通过周期性保存,我们能让玩家从最近的保存点恢复,而不是从头开始。
然而,保存游戏时可能会遇到一些挑战,尤其是当游戏世界非常庞大时。保存大规模的游戏世界可能会导致保存文件过大,影响存储和加载速度。因此,增量保存成为一种有用的技术,允许我们只保存更改过的数据,而不是每次保存整个世界。这样可以有效减少数据的存储需求,提升性能。
另外,还需考虑持久数据(如解锁内容、玩家成就等)与游戏进度保存的分离。这样可以确保保存文件的大小得到控制,同时避免每次上传大量数据,特别是在云存储中。通过将持久数据与游戏进度分开存储,我们可以优化游戏的保存和加载过程。
待办事项:AI - 基础怪物行为示例
游戏设计中涉及了初步的行为模型,此模型旨在展现如何通过简单的行为示例来推动游戏角色的行为。在游戏中,可能会通过这些示例来设定角色的动作或互动方式,帮助模拟真实的医疗场景或处理医疗任务。
待办事项:Z轴实现!
在游戏开发中,需要考虑如何实现角色在不同高度上的移动,例如上下楼梯。通过使用向量3来处理角色的上升和下降,可以解决渲染和动画的问题。像《以撒的结合》这类游戏,虽然处理了类似的上下运动,但它们并没有真正展示角色上下楼梯的过程,而是通过跳跃动画或直接切换级别来简化这一问题。对于渲染,我们可以选择一些简单的解决方案,例如一触即发的屏幕切换,但也可能考虑更复杂的渲染方式,比如更精致的动画地图,或者模仿一些做得特别好的游戏。
因此,虽然处理“z轴”方向的运动不难,但需要明确的实现方法和细节,以便将其整合进游戏的整体结构中。这是游戏开发中一个值得探索的方面。
审查待办事项列表 - 什么内容是困难的,什么内容是简单的?
在开发过程中,涉及到许多复杂的方面,包括建筑、探索和生产等内容。这些领域可能带来不同的挑战,有些可能是常见的问题,而有些则比较独特和困难。尽管我们有一些明确的方向和想法,仍然需要不断地回顾和检查是否遗漏了什么关键的任务或问题。特别是像建筑和探索这类复杂的系统,它们可能会在开发中引发更大的难题。因此,虽然我们已经知道一些困难的工作需要完成,但有些部分的解决方案仍不确定,需要进一步深入思考。
待办事项:音频系统
在音频方面,开发团队不需要进行过于复杂的工作。尽管音效、环境音和音乐对游戏体验非常重要,但考虑到预算有限,不必打造一个复杂的音效编辑系统。所需的音效可以通过购买现成的素材来完成,例如流水声或其他背景环境音。当游戏需要这些音效时,就简单地将它们引入。虽然将来可能会对音效做一些调整或改进,但目前的目标是实现音效的基础支持,确保音效和音乐能够适应游戏的需要,而不会投入过多的资源。
在整个开发过程中,需要确认是否遗漏了任何重要的部分,并确保所有的要素都已涵盖。除了奖牌游戏等额外的元素,其他重要内容基本上都已经梳理完毕。
待办事项:元游戏 - 存档槽
在游戏设计中,存在着如何处理多个保存槽(save slots)的问题。尤其是当多人共享同一台设备时,比如家里的客厅电脑,两个玩家可能会希望各自保存自己的游戏进度,而不需要互相干扰。这个问题涉及到如何在游戏中有效地分开不同玩家的保存文件,确保每个人都可以解锁自己的内容,而不会覆盖或混淆其他人的进度。
为了解决这个问题,可能需要设计一种机制,使得每个玩家都能选择自己的保存槽,并且在游戏中保持这种分离。一个简单的方式是,在游戏开始时,让玩家通过类似空间选择的方式来选择他们想玩的“世界”,而不是通过传统的菜单选择保存槽。玩家可以通过类似走楼梯或选择通道的方式来选择自己想要的游戏进度。
然而,这种设计会引入一定的代码复杂性,因为游戏需要确保每个玩家的进度保持独立并且无误地加载正确的存档。因此,必须在开发过程中确保这一点能正确实现,避免出现保存文件混乱或数据覆盖的问题。在进一步开发之前,团队需要对这个机制进行充分的思考和规划。
游戏内UI是否有必要?
在设计游戏的最终阶段时,目标是避免过于复杂的“结局”设计。希望游戏在结局部分能够避免冗余的、让玩家感到不必要的复杂元素。理想情况下,希望能够省略掉一些“最后的结局”设定,保持游戏的简洁性。
有一种想法是可以通过“漂浮的元素”来处理,这可能是一种简单的动态设计,类似于悬浮物体的机制,但这并不是强制性的要求。设计者希望能够尽量避免复杂的结局设定,保持游戏体验的流畅与简洁,而是看看是否能在没有这种复杂性的情况下完成设计。
总之,最终希望能够通过去除复杂的结局机制,创造一个更简洁、自然的游戏体验。
待办事项:调试代码
在开发过程中,调试工作非常重要,并且需要将日志记录(logging)纳入计划中,以便于问题跟踪和修复。调试代码和生成图解,像是用开关、滑块等元素,是工作的一部分。这些步骤有助于确保调试工作顺利进行。
尽管有这些工具,游戏界面(GUI)在设计上可能只是做一些简单的调整。虽然会做一些基础的图形用户界面(GUI)元素,但总体上并不会过度依赖图形界面,因为某些开发者并不喜欢复杂的GUI。虽然偶尔需要手工制作一些元素,比如在经典游戏《过山车大亨》-好像是叫《模拟乐园》等中看到的那种窗口风格,但仍然倾向于保持界面的简洁性,不让它看起来像是一个复杂的应用程序。
尽管如此,仍然有可能做一些简化版的图形界面,适应游戏的需求,尤其是为了调试和提供提示功能。
待办事项:基础世界生成 - 地图显示
关于地图的设计,虽然地图是一个很有趣的元素,但如何实现地图显示是一个技术上的问题。这个问题需要进一步的思考,以确定最佳的实现方式。考虑到这个问题的复杂性,有可能需要更多的规划和技术上的准备。在思考这个问题时,已经开始了一些初步的想法,并计划将其记录下来,作为未来开发的一部分。
玩家是否可以携带多个物品?
关于携带多个物品的问题,决定是尽量避免这种机制。在游戏中,计划保持物品数量较少,避免过于复杂的物品管理系统。尽管地图是一个有趣的元素,但它并不是当前设计中的重点。整体来说,游戏的设计思路已经基本完成,主要内容已经确定,并且接下来会对已经列出的内容进行排序和进一步规划。
对待办事项列表进行排序
计划中,首先要清理和完成一些已经开始但尚未完成的任务,如碰撞检测代码和调试工作。接下来,会按优先顺序完成这些任务,确保在做其他更复杂的工作之前,基础功能已经顺利运行。
在下周,准备开始新的内容,但不会进行过于复杂的开发,而是清理已完成的任务,这样可以避免在休假一周后留下未完成的工作。之后,可以逐步开展更多的工作,比如处理碰撞检测的完善、调试代码的优化、和动画系统的对接等。
这个计划的目标是,在完成所有任务后,拥有一个可玩的引擎,虽然某些部分可能还不完全成熟,但会为后续的工业化增强和真实化提供良好的基础。最终,目标是逐步将所有功能整合到一个稳定、强大的游戏引擎中,逐步改进、完善,最后达到工业级的质量标准。
这样列出待办事项是否过于超前或不符合压缩导向编程的理念?
计划不是严格的时间表,而是一个灵活的参考列表,包含了未来一段时间需要完成的任务。当不确定下一步该做什么时,可以回到这个列表,选择需要完成的任务。这个列表的目的是确保在开发过程中不会忘记任何重要的任务。虽然有很多内容可能随着工作进展而发生变化,但它为当前的工作提供了指导,并能帮助理清思路。我们不必强制按照列表的顺序执行,而是可以根据需要随时调整任务的优先级。
例如,处理某些任务时,如果我们发现需要做其他修改,可以随时加入新的内容或改变现有内容。最终目标是确保所有必要的任务得到完成,但没有必要对列表上的每一项任务都严格执行。
在GetHashFromStorageIndex
函数中,通过位操作将哈希值映射到哈希索引。为什么不直接通过hash index = hash value MOD array count
计算哈希索引?
在讨论哈希表索引的计算时,避免使用取模(mod)操作的原因是因为取模操作涉及整数除法,而整数除法在计算中是较为昂贵的操作。与此相比,按位运算(bitwise operations)通常更为高效,因为它们执行速度更快。整数除法的成本主要是由于它需要对数值进行更复杂的运算,通常需要更多的处理器周期,因此在性能敏感的程序中,尽量避免使用它。
此外,虽然取模操作可以简化哈希表索引的计算,但在实际应用中,特别是在需要优化性能的情况下,非2的幂次大小的哈希表可能会导致更高的开销。因此,这种权衡决策的最终选择取决于特定的使用场景和目标平台的性能。现代计算机的内存访问速度和处理器的高速运算能力已大大改善,取模操作的成本可能不如过去那么高,但仍需要根据具体情况进行测试。
总体来说,这类优化策略的决定是根据目标平台的性能特点来做出的。在一些情况下,取模可能不是性能瓶颈,而在其他情况下,使用按位运算等优化手段可能会显著提高程序的运行效率。因此,测试和了解目标平台的特点对于做出最佳决策非常重要。
目前伴随角色移动的熟悉角色(familiar)会有延迟,因为它的移动速度比玩家慢。在某些情况下,玩家和熟悉角色可能会分开。是否考虑过为其速度实现比例积分微分控制器?
目前,对于玩家的familiar问题,我们并没有专门尝试实现复杂的控制器。我们只是想要一些简单的机制,以便能够看到整个系统架构应该是什么样的。具体的实现,尤其是familiar系统的细节,会留到后面整个游戏开发过程中的进一步处理,特别是在对家庭成员系统的实现和如何让它们发挥作用时。
关于比例积分微分控制器(PID控制器),尽管它们在很多情况下都非常有趣,但也存在一些缺点。对于游戏来说,积分部分通常并不那么有趣,反而比例和微分部分更具吸引力。比例和微分控制器能带来一种更具弹性、略显不可预测的行为,这种行为通常更适合用来做游戏中的互动和反馈。与此相对,积分项可能并不适用于游戏中的许多场景,尤其是在控制行为上需要可预测性的情况下,PID控制器也许并不是最好的选择。
对于那些需要高度可预测行为的情况,PID控制器可能不是最佳选择。在这种情况下,可能更倾向于使用某种形式的盲插值(blind interpolation),来处理这些场景中的行为。因此,目前很难确定具体会使用哪种方法,但这一问题会在未来的开发中逐步明晰。
是否必须进行Z排序?对于这样的游戏,是否可以只基于Y轴排序,通过调整速度来模拟爬楼梯(例如当角色上楼梯时改变速度)?
对于这个游戏来说,z轴排序不能仅仅依赖于y轴的排序。虽然对y轴进行排序是常见的做法,一旦完成了y轴的排序,我们就可以轻松地通过排序比较来获得z轴的排序。通常,当我们进行排序时,排序比较会是复合的,不仅仅是对一个轴进行排序,这样一来,z轴的排序也能顺利得到实现。
不过,问题并不在于排序本身,而是在于角色上下楼梯时的表现。我们需要考虑的是,角色在楼梯上上下移动时,应该如何呈现,如何实现这种表现。这是一个展示的问题,而不是代码实现的问题。
至于代码的部分,我们相信能够实现所需的功能,但关键在于如何设计和表现角色在楼梯上的动作。当角色向上爬楼梯时,应该如何显示这一动作,如何流畅地过渡到下一个阶段,像是从楼梯的某一部分切换到另一部分,这些都是需要仔细考虑的地方。
听说正在讨论动画,看到你提到骨骼系统。是计划从现成的软件导入,还是为美术人员制作一个动画程序?
目前,程序正在开发一个供艺术家使用的动画工具。这个工具可能会主要依赖程序化动画,但也有考虑过使用预制工具来导入骨骼动画。某些工具提供了低成本的解决方案,并且有免费的版本,可以用于制作简单的骨骼动画。这种工具看起来是一个潜在的、合理的选择,可以用来导入动画数据,进而加载到游戏中。
然而,尽管这类工具可能会非常合适,但是否使用这种预制动画尚不确定。可能整个游戏中的动画信息都会通过程序化方式生成,而不需要通过创作的动画文件。如果决定使用的话,可能会考虑这种工具作为一种低成本的动画制作工具,特别是它能输出数据文件,适合用于游戏中。
总的来说,动画的实现方式还不完全确定,可能会更多依赖程序化的生成而非预制的动画。
待办事项列表中提到超级鱼(Superfish)!
在游戏设计中,已经有一个文本文件,里面包含了所有想要在游戏中实现的设计元素。这些内容目前只是表面上的设计。最近,有关于一个“肤浅的敌人”概念的讨论,想法是设计一种模拟敌人,其行为类似于模仿其他物体或存在。这种敌人就像“伪装者”,可以模仿不同的物体,比如箱子或者出租车等,类似于《地下城与龙》中的一些概念。
这种敌人可以在玩家接近时变身成怪物,形成一种潜在的威胁。简单来说,这个“肤浅的敌人”就是通过模仿的方式来欺骗玩家,玩家习惯性的行为可能导致他们遇到意想不到的危险。这一设计可以提供不一样的游戏体验,增加游戏的不可预测性。
待办事项列表中缺少资产加载管理。
资产加载管理的功能在列表中被遗漏了,这是一个很好的提醒。伤害的设计也被提到了,这是一个值得注意的例子。在讨论如何实施这些功能时,考虑到资产流管理,可能需要在当前的框架中加入这一部分,以便更好地管理和优化资源加载。
哪款2D游戏在Z轴移动方面做得很好?个人很喜欢《波斯王子》里爬台阶的表现。
在谈论图蒂游戏时,波斯王子的例子被提了出来,特别是角色在游戏中爬上台阶时的动作。这个动作设计得非常好,因为它让玩家直观地感受到角色的上升过程。波斯王子的设计方式也符合逻辑,因为游戏是从横向视角展示的,而角色的上升动作在屏幕上是垂直的,这让玩家更容易理解游戏中的物理运动。与此相比,其他等距或顶视角的游戏可能会让玩家对角色的上下移动产生困惑,因为这些游戏的视角变化较大。
对使用他人代码作为学习工具有什么看法?
使用现有代码作为学习工具是完全可以接受的,甚至是推荐的做法。很多人并不清楚如何编程,但通过使用现成的库或引擎,能够让他们快速实现想法和功能。然而,在此过程中,重要的是能理解这些代码背后的原理。如果只是依赖于现成的工具而不理解其工作机制,就容易犯一些常见的编程错误,这些错误可能会使游戏体验大打折扣。
尤其是当你自己做游戏时,有时候你会遇到明显的编程错误,这些错误如果修正,游戏的质量就会有显著提升。因此,理解如何编写基础代码是非常重要的,即便使用现成的引擎和库。这样不仅能避免常见的错误,还能让你在面对问题时更容易修复和调整。这是展示如何从头编写代码的原因之一,目的是让更多的人了解编程的基础,并且能在使用现有工具时理解它们的工作原理,避免因为不理解代码而导致的问题。
Spriter的文件格式是完全开放且有文档记录的。
考虑到使用创作的动画,如果决定采用这种方式,它可能是一件好事。但更倾向于使用过程性动画,因为过程性动画更侧重于代码的实现,这也正是系列内容的重点。因此,最终可能会选择让动画更具过程性,而不是依赖已创作的动画。
游戏中是否会有任务?如果有,如何规划和定义这些任务?
在构建游戏时,如何定义某些要素并不是一个架构问题。这个阶段更多的是关于构建和运行游戏,而不是在架构设计中考虑过多的细节。因此,当前的架构探索过程不需要考虑这些因素,它们并不会对整体架构产生重大影响。
上次在碰撞代码中,是否遗漏了检查Entity == HitEntity
的部分?
在处理碰撞检查时,发现可能遗漏了一个关键步骤。之前提到要在某个地方进行实体检查,但实际上没有把它实现。这个问题导致可能不必要地进行自我检查,浪费了时间。因此,确认只有当实体 A 和实体 B 不同的时候才进行碰撞检查,这样可以避免浪费资源。感谢指出这个问题,并且确认现在的逻辑应该是正确的。
是否会为怪物路径规划算法申请专利?
对于专利制度的看法,认为它非常荒谬,尤其是当有人试图用算法申请专利时,显得尤为不合理。即使有人创造了新的算法,认为应该让所有人都可以使用,而不是限制在某些人的专利权下。对专利制度的批评,认为它已经造成了很多不必要的限制和困扰。
关于Z轴移动,是否可以通过改变精灵大小实现?例如,当角色上升时增大精灵的大小,到达目标时再缩小,同时对墙面纹理做一些视差处理。
讨论了关于Z轴运动和精灵大小变化的可行性。提出了一个想法,即随着精灵向上移动时,可以增大精灵的大小,直到达到某一高度后再缩小。然而,这样做似乎没有太大意义,因为Z轴的运动并不会让精灵更接近摄像机。实际上,精灵向上的运动对玩家的视角影响较小,这意味着缩放精灵的大小可能不符合游戏的视觉逻辑。
如果游戏是从顶部俯视的视角(如《塞尔达传说》那种风格),也许会看起来更合适。因为玩家依然从侧面看到角色的变化,精灵大小的变化可能显得不太自然。整体来看,这种改变可能不符合我们想要的效果,尽管很难断定最终的呈现效果。
觉得《宝可梦》第三代/第一代在Z轴处理上表现不错。
讨论了《口袋妖怪》第三代在Z轴方面的表现,认为它在这一方面做得很好。然而,随着游戏的推进,这一设计在第三代被削弱。提到“珍”的意思可能是指“第一代”。在此过程中,提出了如果能分享一个视频链接或相关资源,将帮助更好地理解这个话题。虽然并不完全关注某些细节,但有些人对这些细节非常熟悉。
怪物遭遇战会是随机的(像《最终幻想》、《勇者斗恶龙》)还是更静态的(像《塞尔达传说》)?
讨论了怪物遇敌的方式,提出两种可能:一种是随机遇敌,类似《最终幻想》或《龙战士》那种方式,另一种则是更静态的,类似《塞尔达》的风格。在前者中,怪物会出现在地图上,你可以直接与它们进行战斗,而不是通过某种代表性的怪物触发战斗。最终,选择了前者,即让怪物在地图上出现,玩家与之互动,而不是进入单独的战斗场景。
剑的攻击是否需要加入时间和距离的限制?
讨论了是否在剑的功能上添加时间限制和距离限制。虽然添加这些限制是可能的,但实施起来相对简单,特别是在不涉及碰撞管理的情况下。如果决定添加这些功能,可以作为一个例子对象进行实验,目的是看看它们在游戏系统中的作用。对于时间限制,它可以通过检查剩余时间在更新调用中轻松实现,因此没有必要做过多的测试,未来也很容易加入这种功能。不过,目前来看,这些限制对系统的影响不大。
《网络创世纪》(Ultima Online)似乎也处理了Z轴问题,但不确定效果如何。
讨论了《Minish Cap》及其在处理额外内容时的表现。虽然没有直接玩过这个游戏,但观察到有些人玩过,甚至在一个游戏公司办公室中也有见过。提到了关于Z轴处理的问题,虽然游戏中有使用Z轴的内容,但不确定它的表现如何。此外,谈到游戏公司办公室的布局,员工需要上楼取东西。总体而言,尽管没有亲自体验,但依旧对一些细节保持了关注,并愿意进一步了解。
参与过的最大游戏项目是什么?
提到过一些参与过的较大游戏产品,其中虽然没有直接编写游戏代码,但有许多较大的游戏中使用了个人开发的角色动画系统。在工作中研究了这些系统的特性,并将角色接口授权给了其他游戏。讨论中提到的“目击者”游戏,是一款在其中直接编写代码的非授权游戏,这款游戏现如今变得非常庞大。尽管它不强迫玩家解决所有问题,但如果选择解决其中的所有难题,它将是一个巨大的挑战。
关于动画的评论有没有遗漏?
讨论中提到动画本身并不再被视为手工制作,因为已经有工具介入其中,动画的制作过程变得更加程序化。尽管加载动画本身是一个导入问题,涉及解析文件格式,但这一过程并不被视为创新或有趣的部分。动画的导入问题已经通过工具解决,并展示了如何处理文件格式。在处理大型资产时,可能会涉及到压缩文件以便运输,而解析新文件格式也未必是一个有趣的任务,除非真的有需要导入特定类型的动画。
在自己代码中写平台层时,是否发现受某些现有解决方案的影响太大,从而思路变得狭隘?如何突破这种困境?
在讨论中,提到了一种现象,即通过某种方法或解决方案的影响,可能会形成对解决问题的偏见。这样的偏见可能导致在解决新问题时,倾向于使用已经知道的解决方案,而不是从根本上重新思考问题的本质。作者认为这种偏见并非恶意,而是一种自然的倾向,因为已知的解决方案让人觉得更容易解决问题。
接着讨论如何突破这种偏见。作者提到,在面对问题时,重要的是要反思并识别自己解决方案中的潜在问题,而不是仅仅满足于已有的解决方法。通过重新审视问题,提出新的目标,并努力朝着这些目标去解决问题,可以帮助避免陷入思维定势。每个解决方案都可能会有不同的权衡,因此能够从多个角度去看待和解决问题是非常有价值的。
最终,作者的建议是:挑选不同的目标,并朝着这些目标努力,通过不断迭代来优化解决方案。这种方法比单纯追求不同的解决方案更有意义,因为目标的改变会直接影响解决方案的效果。
理想的游戏时长应该是多少?
在讨论游戏时长的问题时,观点指出,游戏的长度不应当是评判其好坏的标准。游戏的重点应当放在体验本身,而非单纯的时长。不同类型的游戏适合不同的时长,关键是游戏设计是否能够充分利用所需时间来提供丰富的内容与体验,而不仅仅是为了填充时长。
一些游戏,如《以撒的结合》,因其可以不断地进化和提供多次游玩体验而具有高可玩性,玩家能够在长时间内享受不断变化的内容。然而,如果是互动故事类游戏,20小时的时长可能显得过长,因为故事的推进可能不需要如此多的时间。比如,类似《行尸走肉》这类游戏,其核心体验可能更适合较短的时长。
与此同时,游戏不应单纯追求长度,而应根据设计目标来确定合适的时长。某些游戏的玩法可能需要更长时间(如《最终幻想》),但并不意味着长度本身带来了更好的游戏体验,过度拉长的游戏时间可能导致重复性战斗,消耗玩家的时间却并未增加乐趣。
因此,在游戏设计中,更应考虑的是:是否有足够有趣和有价值的内容支撑游戏时长,以及是否能够为玩家提供合适的游戏体验。游戏的时长应根据内容的丰富性与深度来调整,而不是盲目追求一个固定的数字。
相关文章:

游戏引擎学习第70天
这一节没讲什么主要是关于接下来要干的任务 开发过程概览 我们正在进行最后的总结,并计划接下来的步骤。目前的目标是创建一个包含所有必要组件的游戏引擎原型版本,目的是让这些部分能够协同工作并展现预期效果。通过这一过程,可以实验和探…...

深入理解 Spring Cloud 中的 Eureka、Ribbon 和 Feign
1.eureka自我保护机制是什么? Eureka的自我保护机制是一种针对网络异常情况的安全保护措施,旨在防止因为网络问题导致的服务注册中心(Eureka Server)与微服务实例之间的通信故障。当网络分区或其他形式的网络故障发生时,即使微服…...

DVWA靶场Brute Force (暴力破解) 漏洞low(低),medium(中等),high(高),impossible(不可能的)所有级别通关教程
目录 暴力破解low方法1方法2 mediumhighimpossible 暴力破解 暴力破解是一种尝试通过穷尽所有可能的选项来获取密码、密钥或其他安全凭证的攻击方法。它是一种简单但通常无效率的破解技术,适用于密码强度较弱的环境或当攻击者没有其他信息可供利用时。暴力破解的基…...

山高路陡,无人机代替滑轨吊运物资极大提高做作业效率降低成本
在山高路陡的地区,无人机代替传统的滑轨吊运物资,极大地提高了作业效率并降低了成本。以下是对这一现象的详细分析: 一、无人机吊运的优势 1. 提高作业效率: 无人机能够快速响应并执行吊运任务,尤其在高山、陡峭或交…...

数据的高级处理——pandas模块进阶——数据的统计运算
今天的学习用有好几处与书上的内容有出入,不只是因为pycharm中函数更新、弃用的问题,还是作者有些疏忽。不过影响不大,运行报错,GPT分析一下,原因很简单。这里不进行详细书名,在下边的代码上已经进行详细的…...

【Leetcode】3280. 将日期转换为二进制表示
文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接🔗 给你一个字符串 date,它的格式为 yyyy-mm-dd,表示一个公历日期。 date 可以重写为二进制表示,只需要将年、月、日分别转换为对应的二进制表示&a…...

Vue3 中自定义hook
什么是hook?—— 本质是一个函数,把setup函数中使用的Composition API进行了封装,类似于vue2.x中的mixin。 自定义hook的优势:复用代码, 让setup中的逻辑更清楚易懂。 场景需求:现在我需要获取当前鼠标所点击的地方的…...

嵌入式系统 第七讲 ARM-Linux内核
• 7.1 ARM-Linux内核简介 • 内核:是一个操作系统的核心。是基于硬件的第一层软件扩充, 提供操作系统的最基本的功能,是操作系统工作的基础,它负责管理系统的进程、内存、设备驱动程序、文件和网络系统, 决定着系统的…...

音视频入门基础:MPEG2-PS专题(2)——使用FFmpeg命令生成ps文件
一、错误的命令 通过FFmpeg命令可以将mp4文件转换为ps文件,PS文件中包含PS流数据。 由于PS流/PS文件对应的FFInputFormat结构为: const FFInputFormat ff_mpegps_demuxer {.p.name "mpeg",.p.long_name NULL_IF_CONFIG_SMALL…...

Embedding
Embedding 在机器学习中,Embedding 主要是指将离散的高维数据(如文字、图片、音频)映射到低纬度的连续向量空间。这个过程会生成由实数构成的向量,用于捕捉原始数据的潜在关系和结构。 Text Embedding工作原理 词向量化&#x…...

Android Studio学习笔记
01-课程前面的话 02-Android 发展历程 03-Android 开发机器配置要求 04-Android Studio与SDK下载安装 05-创建工程与创建模拟器...

Git的使用流程(详细教程)
目录 01.Git是什么? 1.1 Git简介 1.2 SVN与Git的最主要的区别 1.3 GIt主要特点 02.Git是干什么的? 2.1.Git概念汇总 2.2 工作区/暂存区/仓库 2.3 Git使用流程 03.Git的安装配置 3.1 Git的配置文件 3.2 配置-初始化用户 3.3 Git可视化…...

Keil中的gcc
文章目录 一、IDE背后的命令1.1 IDE是什么1.2 IDE的背后是命令1.3 有两套主要的编译器 二、准备工作2.1 arm-linux-gcc和gcc是类似的2.2 Code::Blocks2.2.1 设置windows环境变量2.2.2 命令行示例 三、gcc编译过程详解3.1 程序编译4步骤3.2 gcc的使用方法3.2.1 gcc使用示例3.2.2…...

bilibili 哔哩哔哩小游戏SDK接入
小游戏的文档 简介 bilibili小游戏bilibili小游戏具有便捷、轻量、免安装的特点。游戏包由云端托管,在哔哩哔哩APP内投放和运行,体验流畅,安全可靠。https://miniapp.bilibili.com/small-game-doc/guide/intro/ 没想过接入这个sdk比ios还难…...

springboot523基于Spring Boot的大学校园生活信息平台的设计与实现(论文+源码)_kaic
摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本大学校园生活信息平台就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理完毕庞大的数据…...

【YOLO算法改进】ALSS-YOLO:无人机热红外图像|野生动物小目标检测
目录 论文信息 论文创新点 1.自适应轻量通道分割和洗牌(ALSS)模块 2.轻量坐标注意力(LCA)模块 3.单通道聚焦模块 4.FineSIOU损失函数 摘要 架构设计 轻量高效网络架构 - ALSS模块 LCA模块 单通道聚焦模块 损失函数优…...

XML解析
一,XML概述 1.什么是XML XML即为可扩展的标记语言(eXtensible Markup Language) XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识 2.XML和HTML不同之处 XML主要用于说明文档的主题,而…...

PlasmidFinder:质粒复制子的鉴定和分型
质粒(Plasmid)是一种细菌染色体外的线性或环状DNA分子,也是一种重要的遗传元素,它们具有自主复制能力,可以在细菌之间传播,并携带多种重要的基因(如耐药基因与毒力基因等)功能。根据质粒传播的特性…...

PTA数据结构作业一
6-1 链表的插入算法 本题要求实现一个插入函数,实现在链表llist中的元素x之后插入一个元素y的操作。 函数接口定义: int InsertPost_link(LinkList llist, DataType x, DataType y); 其中 llist是操作的链表,x是待插入元素y的前驱节点元素…...

2024年总结【第五年了】
2024年总结 北国绕院扫雪,南方围炉烹茶,且饮一杯无? 执笔温暖不曾起舞日子里的点点滴滴,誊写一段回忆,还以光阴一段副本。 那么你要听一支新故事吗?第五年总结的片碎。 衣单天寒,走趟流星孤骑…...

java实现一个kmp算法
1、什么是KMP算法 Kmp 算法是由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,改进字符串匹配的算法; Kmp 算法的核心是利用匹配失败的信息,尽量减少模式串与主串的匹配次数,以达到 快速匹配的目的; Kmp 算法的时…...

强化学习方法分类详解
强化学习方法分类详解 引言 强化学习(Reinforcement Learning, RL)是一种通过智能体与环境互动来学习如何做出最佳决策的方法。根据不同的优化中心、策略特性、环境模型、奖励函数、动作空间类型以及行为策略和目标策略的一致性,RL可以分为…...

雅思真题短语(二十八)
真题短语收录在合辑。 541法律官员 work as a solicitor 542前卫 a radical and expensive scheme 543反对者们 objectors 544破坏 demolishing buildings 545蒸汽机车 steam locomotives 546冷凝 steam could be condensed 547烟雾 smoke and fumes 548通风井 ventilation sh…...

在Linux系统中使用字符图案和VNC运行Qt Widgets程序
大部分服务器并没有GUI,运行的是基础的Linux系统,甚至是容器。如果我们需要在这些系统中运行带有GUI功能的Qt程序,一般情况下就会报错,比如: $ ./collidingmice qt.qpa.xcb: could not connect to display qt.qpa.plu…...

Python基于EasyOCR进行路灯控制箱图像文本识别项目实战
说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后关注获取。 1.项目背景 随着城市化进程的加快,智能城市建设成为了现代社会发展的重要方向。路灯作为城市基础设…...

Github 2024-12-28 Rust开源项目日报 Top10
根据Github Trendings的统计,今日(2024-12-28统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Rust项目10TypeScript项目1Python项目1egui: 一个简单、快速且高度可移植的 Rust GUI 库 创建周期:1903 天开发语言:Rust协议类型:Apache Li…...

提升生产力工具
VSCODE插件 干货:用好这13款VSCode插件,工作效率提升10倍 - 程序员柠檬 - 博客园 Sourcetrail Sourcetrail 是一个开源且免费的源码阅读工具,以其强大的代码导航、可视化及跨平台支持特性,成为开发者理解复杂代码库的得力助手。…...

【蓝桥杯——物联网设计与开发】系列前言
前言 本系列博客是博主为准备2024年第十五届蓝桥杯大赛物联网设计与开发赛道而写,经过4个月学习备战,最终获得全国一等奖。 从第十六届蓝桥杯大赛开始,物联网赛道更换竞赛实训平台。之前的博客,可以借鉴代码思想,但引脚…...

【Java基础】02.Java数据类型
目录 Java 数据类型 3.1 java程序中 “” 号的使用 3.2 java中的数据类型 3.2.1 基本数据类型:数值型 (1)整数类型 (2)浮点(小数)类型 3.2.2 基本数据类型:字符型 3.2.3 基本…...

Python爬虫(一)- Requests 安装与基本使用教程
文章目录 前言一、简介及安装1. 简介2. 安装 Requests2.1 安装2.2 检查安装是否成功 二、使用 Requests 发送 HTTP 请求1. 发送 GET 请求2. 发送 POST 请求3. 发送 PUT 请求4. 发送 DELETE 请求5. 发送 HEAD 请求6. 发送 OPTIONS 请求 三、传递参数1. GET 请求传递 URL 参数1.1…...