开场和欢迎
首先,我们的游戏是从零开始编写的,没有使用任何第三方库或引擎,因此我们从最基础的低层次编码做起。这种方式不仅适合那些对编程有兴趣的开发者,还对教育有很大帮助,因为许多开发者在学习过程中没有机会深入了解底层编程。通过这次项目,我们能够学习到很多低级编程技术,甚至连高层的编程技巧也是在解决这些低层次问题时才逐渐掌握的。
现在,我们已经完成了很多基础工作,包括精灵的加载和显示、简单的阿尔法混合技术的使用,以及构建瓷砖地图并让角色在其中移动等。为了进一步推进项目,我们将开始引入一些数学运算,特别是涉及到向量数学的部分,这对于后续的开发至关重要。
今天的目标是将精灵加载和显示的代码整理成一个相对简洁和高效的形式,并且使角色能够根据玩家的移动方向进行面朝调整。为了实现这一点,我们会加载角色的不同图像,确保其可以根据四个不同的面向方向进行切换,并且在游戏中能正常显示。
此外,我们也会做一些关于资源管理的思考。目前,游戏中的资产管理还没有深入讨论,我们暂时采用的是简单的加载方式,但一旦渲染工作进一步推进,我们将需要更高效的资源管理系统,尤其是在游戏正式上线时,资产的流式加载将成为一个重要问题。
总结来说,今天的工作将主要集中在代码整理和精灵渲染方面,以便为接下来的数学运算做准备。我们将逐步进入更复杂的渲染技术和数学运算,这将是开发过程中的一个重要阶段。
HeroBitmaps 结构
目前,我们有了一个基本的英雄模型,地图的结构也初步搭建完成。英雄的图像(位图)包含了多个部分,比如头部、披风和躯干,每个部分都有不同的图像版本,用于表示英雄的不同面向方向。为了实现这些,我们需要将这些图像数据整理并加载进来。
具体来说,每个方向的英雄图像已经准备好,接下来需要进行适当的映射和加载。英雄的不同面向将对应四个方向,这些方向的图像会存储为不同的位图。接下来,代码中将涉及到如何将这些位图加载并显示在屏幕上,确保英雄的方向能够根据游戏中的动作正确切换。
虽然已经有了一些加载这些图像的基础代码,接下来的步骤是确保这些图像能够正确地显示和切换。将这些图像作为基础,为每个方向做出相应的处理。
加载所有英雄位图
在开发过程中,已写好的代码能够加载英雄的四个面向方向的位图。虽然加载代码已经存在,但目前仍然在进行一些调整。通过简单的方法,将这四个方向的位图对应加载,面向方向如前、后、左、右等都会按照预定的顺序进行。
起初,加载的方式并没有特别考虑如何映射这些位图,暂时采取了一个简单的方式,按照从右到左的顺序进行处理。通过这种方式,每个方向的位图就依次对应到不同的索引位置,从而完成位图的加载。最终,四个方向的位图将在内存中按顺序排列,并在游戏中调用。
这种做法虽然看似简单,但其实是为了暂时避开更复杂的加载与管理机制,以便集中精力处理其他功能。在实际开发过程中,避免直接使用大规模的字符串表来管理这些资源。当前阶段,直接通过手动映射并加载四个方向的位图是一种合理的暂时方案。
这段代码实现的目标是让英雄的图像能够根据其朝向正确显示,而暂时忽略更高效的资源管理方式。虽然这种处理方法并不高效,但由于此时游戏开发还处于初期阶段,这样做能够避免过早地涉及到复杂的资源管理或数学问题。未来,当代码进一步完善时,可能会回过头来重新设计资产加载与位图管理机制。
总结来说,目前的实现方法依赖手动映射四个方向的位图,在内存中按顺序加载和使用,暂时不考虑更多优化方案。
按正确顺序绘制加载的位图
在这段描述中,主要探讨了如何通过顺序渲染不同的角色部件(如头部、斗篷和躯干)来重建一个角色的显示状态。具体而言,角色的显示是分层的,类似于 Photoshop 中的图层处理,每一层都被依次叠加:
-
层叠顺序:首先加载并绘制角色的躯干,因为它是最底层的内容。接着,披肩(斗篷)被放置在躯干之上,而头部则是最上面的一层。这是为了确保角色的各部分按预期的顺序显示出来,形成完整的角色形象。
-
角色朝向:角色朝向是一个重要的属性,尤其是在游戏中控制角色的方向。通过设置一个“朝向方向”的变量,可以使角色朝向正确的方向。例如,当角色朝向右侧时,会显示正确的图像,类似于 Photoshop 中图层的叠加方式。这里提到通过修改“朝向方向”变量来改变角色的朝向,如果值为0,角色会面朝右;如果值为1,角色会朝向另一个方向,依此类推。
-
角色的运动方向:角色的运动方向与它的朝向方向密切相关。为了使角色能够朝着实际移动的方向显示,代码需要某种方式来追踪并指定角色最近的运动方向,进而调整其朝向。这种方法允许角色根据实际运动方向灵活调整视角。
-
总结:通过这种分层渲染和方向控制,角色的显示可以实现动态变化,确保游戏中角色的表现与实际动作一致。整体思路是通过简单的方向值控制(如0、1、2、3等)来调整角色的显示状态,使得每次角色的动作都能够正确映射到其对应的视觉效果。
这个过程主要集中在角色显示和朝向管理上,确保了角色的形象在不同的状态下都能准确反映玩家的控制。
根据运动更新英雄的面朝方向
朝向参数的引入与操作
- 将角色的朝向(
FacingDirection
)作为参数引入,用于确定角色的绘制方向。 - 在代码中通过访问
GameState->HeroBitmaps[FacingDirection]
,动态选择正确的位图资源。 - 通过这种方式,可以轻松地从游戏状态结构中提取特定朝向的位图。
数据操作与绘制的准备
- 修改了现有代码,使其操作基于
FacingDirection
参数,从而实现根据朝向动态获取角色的位图。 - 角色的朝向被存储在游戏状态的严格结构中(
GameState
),并通过相应的索引访问位图。 - 此改进使得代码具备灵活性,能够适应角色不同的朝向并加载对应的图像。
输入处理逻辑的改进
- 根据玩家的按键输入,动态设置角色的朝向:
- 如果玩家按下“向上”键,则设置
FacingDirection
为向上的值。 - 如果按下“向下”键,则更新为向下方向。
- 同理处理向左与向右的情况。
- 如果玩家按下“向上”键,则设置
- 通过这种映射机制,可以简单高效地根据最新的输入更新角色的朝向。
实现与问题排查
- 编译代码后,验证角色是否能根据输入正确改变朝向。
- 修复了初始实现中的一个问题:方向索引未正确匹配预期值。原本的映射中,朝左(
Left
)的索引应该为0
,但在实现时未遵守此设定,导致不一致。 - 调整后,角色的方向能够准确响应输入,并且在视觉上切换至正确的朝向。
当前状态与改进方向
- 角色现在能够根据玩家的输入切换朝向,并且动态绘制对应的位图。
- 后续还需进一步完善角色移动代码,以实现更多复杂的逻辑,比如基于向量计算的移动或方向的平滑过渡。
总结而言,这段代码通过清晰的逻辑和合理的抽象,将角色的朝向动态映射到输入操作,为游戏角色的动态表现提供了基础。
将英雄居中到他的矩形上
在当前的实现中,角色图像(如头部、躯干和披风)的绘制遇到了一些问题,主要是关于如何对齐角色与其所在矩形的显示位置。以下是详细的复述与总结:
图像绘制的初步问题
- 角色的位图当前是以图像的左上角为起点进行绘制的,这导致角色的位置未能正确对齐到矩形的预期位置。
- 尽管期望角色站立时脚部位于矩形底部,但实际上,角色图像的起点(即左上角)并未与矩形的实际位置一致,造成了角色与矩形的位置偏差。
图像和资产加载的挑战
- 角色图像的资产尚未进行完备的处理和规范化。当前加载的图像是原始资产,图像周围存在大量的空白区域,这并不符合最终使用的需求。
- 这些空白区域实际上是开发过程中期望的格式,但尚未经过进一步的处理。最终,处理过的艺术资产应该去除这些多余的空白,缩小成实际需要的尺寸。
热点和对齐
- 在处理这些资产时,存在一个隐式的“热点”定义。这个“热点”类似于游戏开发中用于定义对齐点的位置。传统上,这个点通常用于设置精确的对齐或偏移。
- 热点的作用是帮助确定角色或图像的实际位置,在开发过程中,这个对齐点非常关键,它确保图像以正确的方式渲染到屏幕上。
临时解决方案与修复
- 由于当前没有完成对艺术资产的处理,作为一种临时解决方案,角色图像被直接加载并绘制,但由于对齐问题,角色的绘制位置未能精确匹配矩形。
- 这种问题的解决需要进行进一步的资产处理,去除空白区域,并确保图像按预定的对齐点正确绘制。
未来的改进方向
- 接下来需要对艺术资产进行处理,确保加载时图像的对齐方式正确,去除不必要的空白区域。
- 应该明确角色绘制时的对齐规则,并基于该规则调整图像的加载和绘制逻辑。
- 还需要在代码中引入更加精确的控制点,确保角色图像能够准确对齐到矩形的预期位置。
寻找对齐的中心
角色位置的确定
- 角色的立足点,即角色的“脚部”位置,应该与其在世界中的位置对齐。当前的目的是确保角色在游戏世界中的位置与图像的绘制位置一致。
- 角色的定位不仅仅是将图像放在某个位置,还需要确保图像的特定部分(如脚部)对齐到游戏世界中的地面位置。
缺乏定位信息
- 当前系统并没有获取到角色图像的正确对齐点或注册标记。为了使角色准确地在世界中定位,需要这些信息(例如,角色图像中脚部的位置)。
- 在实际的艺术文件中,必须包含这些注册标记或者通过手动方法确定角色图像的对齐点。
使用工具来获取位置信息
- 通过工具(如 GIMP)可以查看角色图像的坐标。例如,通过查看坐标为(72, 182)的像素点,可以确定角色图像的关键位置。
- 这些坐标代表角色图像中某一特定位置的偏移量,并帮助确定该点如何与游戏世界中的位置对齐。
位置调整
- 根据图像的像素坐标(如(72, 182)),可以将角色的实际位置调整到正确的世界坐标上。对于面对前方的角色,这些坐标将用于将角色正确绘制在屏幕上的位置。
未来的调整
- 为了实现精确的定位,需要将图像的注册标记(或热点)嵌入到艺术文件中,并确保这些标记与游戏世界的坐标系统一致。
- 最终,所有这些信息将有助于在不同的方向下绘制角色,并确保角色在世界中的站立位置与图像的位置完全匹配。
将 DrawBitmap() 修改为基于顶部和左侧对齐
在这个过程中,考虑到如何调整和优化角色位图的位置和对齐点,首先需要了解几个核心概念。
-
对齐点:
- 每个角色位图都有一个对齐点,这个对齐点决定了角色的位置相对于位图的其他部分。最常见的对齐点是角色的底部或中心点。
- 对齐点通常通过
AlignX
和AlignY
来表示,它们是相对于位图左上角的偏移量。
-
手动对齐:
- 最开始需要手动调整对齐点。通过工具(如 GIMP)查看位图,记录下每个方向下角色的对齐点坐标(例如
72, 82
)。这些坐标通常用于确定角色在游戏中的准确位置。
- 最开始需要手动调整对齐点。通过工具(如 GIMP)查看位图,记录下每个方向下角色的对齐点坐标(例如
-
简化和自动化:
- 手动调整虽然可以解决当前问题,但在游戏开发中效率和自动化是关键。因此,需要考虑如何通过工具(例如 Photoshop)标记对齐点,或者通过编程自动加载这些信息。
- 目前,简单的手动编码可能是最直接的解决办法,但未来可以通过改进资产导出和加载流程,自动获取对齐点。
-
调整位置:
- 调整位置时,核心目标是让角色的“地面点”(即角色站立的脚底)对齐到正确的位置。为了做到这一点,需要通过程序计算角色的位置和对齐点。
- 这个过程包括从传入的
AlignX
和AlignY
获取对齐点,然后通过计算将角色位置调整到正确的地面位置。这里涉及到数学运算,确保角色图像能够正确显示。
-
动态调整和优化:
- 当游戏的图像和资产增多时,手动调整对齐点变得不可持续,因此需要寻找更好的方法来动态处理这些对齐信息。例如,可能需要通过函数来动态调整位置,或使用注册坐标来存储对齐信息。
总结来说,在当前的工作中,核心任务是确保角色位图能够按照预定的对齐点准确渲染,同时为未来的扩展和自动化做好准备。这包括手动调整、算法计算、以及通过程序处理对齐点。最终目标是让角色在游戏世界中的位置与其视觉表现对得上,从而实现良好的用户体验。
添加相机位置
在这个过程中,核心目标是调整游戏中的摄像头视角,使其能够适应玩家位置的变化,并且重新组织地图的呈现方式。原来,玩家的位置是固定在屏幕的中央,而现在,地图的渲染需要根据摄像头的位置动态调整。
最初的设定是,在地图渲染时,玩家的角色会被置于屏幕的中心,然后从这个中心开始向四周展开,展示周围的地图瓦片。这个过程在原始设计中过于夸张,可能会有多余的瓦片显示在屏幕外面。为了让渲染更加精准,现在的目标是将这一过程重新设定,调整为根据摄像头位置来渲染,而不是仅仅根据玩家的位置。
接着,当游戏开始时,摄像头的位置会根据一个逻辑规则进行初始化,而不是再依赖于玩家的位置。这个摄像头的位置应该位于第一张地图的某个逻辑点上,通常是在地图的某个角落。摄像头的渲染范围应该是一个固定的视野,而这个视野的大小将根据游戏设计进行设定,例如17x9的瓦片系统。通过计算摄像头位置的相对值,可以动态地确定视野范围和渲染内容。
最后,开发者调整了代码,将摄像头视角固定,避免了之前的“作弊”行为——即直接将玩家位置固定在屏幕中央。现在,通过计算玩家的位置,地图和玩家都可以根据摄像头的实际位置动态渲染,从而使得整个视图的呈现更加符合预期的游戏状态。
总结来说,主要的变化是将原本固定的玩家视角转换为动态的摄像头视角,使得游戏地图的渲染更加真实和灵活。
计算玩家的实际位置
这个过程的主要目的是计算玩家相对于摄像头的位置,以便在屏幕上正确地绘制玩家的位置。首先,摄像头在屏幕上的位置是固定的,可以视为屏幕中心,而我们需要将玩家的位置转换为相对于这个摄像头的位置。
在计算玩家与摄像头之间的相对位置时,我们需要做一个减法运算。这个减法的目的是获取玩家与摄像头之间的距离,即玩家与摄像头在瓦片地图上的差异。具体来说,玩家的位置和摄像头的位置是基于地图的瓦片坐标进行计算的,而减法操作可以帮助确定两者之间的偏移量。
接下来,考虑到目前没有引入向量运算的情况下,可以通过简单的减法来得到玩家和摄像头之间的差异。这种方法虽然简化了问题,但会在后续引入向量计算时变得更加清晰和高效。在当前阶段,这种减法操作可以帮助我们理解玩家和摄像头之间的关系,并为后续的改进做好铺垫。
另外,考虑到不希望为每个小操作创建多个函数,开发者选择通过一个统一的函数来处理这个减法计算,使得代码更加简洁和高效。这个函数将返回玩家与摄像头之间的差异,作为一个位置上的调整,从而决定在屏幕上如何绘制玩家。
总之,核心思想是通过计算玩家和摄像头之间的相对位置来动态调整玩家的位置绘制,避免了固定位置的局限性,为之后引入更复杂的向量计算提供了基础。
瓦片地图差异
在这个过程中,核心目的是计算玩家相对于摄像头的位置差异。首先,假设已经有了摄像头和玩家在瓦片地图上的位置。为了确定玩家相对于摄像头的偏移量,需要通过减法运算来计算两者之间的差异。
减法操作的关键是计算“玩家”和“摄像头”在瓦片坐标系中的差异。通过对比这两个位置,能够得到它们之间的偏移量。这个偏移量反映了玩家与摄像头在地图上的位置差异,能够告诉我们玩家相对于摄像头在屏幕上的位置。
一旦得到了这个差异,就可以根据这个信息将玩家的实际位置绘制到屏幕上。这些计算本质上是通过处理浮点数来表示不同的距离,计算过程相对简单,关键在于如何减去这两个位置的偏移量,得到实际的差异值。
此外,当前的实现中,偏移量被视作一个浮动值,并且通过直接计算这两个位置的差异来得出结果。这个操作非常直观和简单,但仍然需要确保能够正确处理这些偏移量,并考虑到所有可能的坐标计算。
总的来说,主要目标是通过减法计算玩家和摄像头之间的相对位置,从而确定如何在屏幕上正确显示玩家的位置。
考虑 AbsTile
整个过程的目标是通过计算玩家与摄像头之间的距离差异,并将其转换为屏幕上的像素坐标。在这个过程中,首先计算玩家和摄像头在瓦片坐标系中的差异。这是通过对比两个位置的坐标,使用减法得到它们的差距。这个差异反映了玩家与摄像头之间的相对位置。
接下来,计算出的差异需要转换为实际的度量单位,通常是米。瓦片的边长和实际的米数需要知道才能进行转换,因为瓦片地图中的坐标是以瓦片为单位的,而在实际世界中,距离是以米来衡量的。因此,需要将瓦片坐标转换为物理单位,并进一步转换成屏幕像素,以便正确绘制玩家位置。
为了完成这个转换,首先需要知道每个瓦片的实际物理尺寸,这样才能将瓦片差异转化为米的差异。然后,将该差异乘以一个常数(例如,米与像素的比例)来将其转换为像素值。这样就可以将玩家的位置绘制到屏幕上。
在此过程中,涉及到将多个计算步骤组合在一起,包括从瓦片差异到米差异的转换,再到米差异到像素的转换。所有这些计算的结果是得到一个可以准确表示玩家在屏幕上位置的像素值。
然而,值得注意的是,虽然这些步骤在理论上看起来是正确的,但仍然存在一些未明确处理的细节,例如如何精确计算每个瓦片的实际物理尺寸,以及如何在实际代码中实现这些转换。这些问题可能需要在后续的实现过程中进一步调整和优化。
最后,通过计算这些差异并将它们转换为像素后,可以将结果返回,以便后续的渲染操作使用这个信息来绘制玩家的位置。这个过程整体上依赖于瓦片与实际物理单位之间的关系,转换的准确性决定了玩家在屏幕上的位置是否正确。
使相机保持锁定在玩家上
在这个过程的讨论中,主要关注的是如何处理玩家与摄像机的互动,尤其是在屏幕上的移动和位置计算。首先,玩家和摄像机的位置差异会导致一些需要调整的细节,例如坐标系统的翻转和处理相对位置的方式。
玩家的运动与摄像机的跟随关系是非常重要的。玩家和摄像机的坐标系统并不完全匹配,导致了需要通过调整和处理坐标系来确保游戏运行的平稳。这些调整不仅涉及到位置的计算,也需要考虑屏幕上的显示效果。例如,当玩家从屏幕的顶部出现时,摄像机必须跟随,并且要计算何时触发屏幕切换。
这段过程中提到的关键部分是如何通过调整玩家的相对位置来改变摄像机的位置,特别是在玩家靠近屏幕边缘时,摄像机应当向前或向后移动以保持适当的视角。如果玩家超出了一个屏幕的范围,就需要翻转到下一个屏幕。
另外,还涉及到如何处理一些细节,比如玩家离开屏幕时,摄像机是否继续跟随。这部分的核心思想是通过计算玩家与摄像机之间的差异来判断何时进行屏幕切换,并且通过判断相对距离来决定摄像机的移动方向。
尽管过程中出现了一些问题,如摄像机不能正确跟随玩家或屏幕切换时的滞后,但这些问题最终可以通过调整位置计算和控制逻辑来修复。最终目标是确保摄像机能正确地跟随玩家,无论玩家如何移动,都能使得视角和画面始终处于正确的状态。
修复左侧和顶部裁剪
这段文字解释了如何解决一个由图形裁剪和像素复制错误引起的图形故障问题,涉及位图处理和图形编程中的一些关键概念。
关键概念:
-
裁剪和源行指针的推进:
- 一个矩形区域被裁剪,这意味着位图中不可见的部分会被丢弃。
- 在裁剪后,源行指针(即开始复制像素的位置)没有正确推进,导致图形错误。像素被错误地复制到屏幕上,出现了不正确的图像显示。
-
问题的识别:
- 问题出在裁剪了位图的左边和顶部时。
- 如果不调整复制的起始位置,错误的起始点会导致图形位置错乱,比如人物的头部和身体分开显示。
-
解决问题:
- 为了解决这个问题,必须根据裁剪的左边和顶部的距离来推进源行指针。
- 复制的起始位置需要调整,以确保像素正确地显示,从而避免图形错误。
-
位图方向的处理:
- 需要注意的是,位图可能是从底部向上存储的,这种情况需要通过减法来正确访问和复制像素。
-
后续步骤:
- 为了测试,当前的代码进行了简化,但在最终的渲染代码中会进行更详细的注释和整理。
- 结果是裁剪后的位图图像正确显示,避免了图形问题。
-
性能检查:
- 建议检查帧率,确保性能没有受到修改的影响,尽管当前的测试代码表现良好。
关键要点:
- 主要问题是裁剪后没有正确推进源行指针,导致了像素复制错误。
- 解决方法是根据裁剪的边缘调整指针位置,确保正确的像素复制。
- 最终目标是确保渲染正确,并检查性能。
检查帧率
60Hz下面是33ms
修复实时代码加载
这段内容讨论了在实时代码加载过程中遇到的一些问题,并介绍了一种解决方案,即创建一个锁文件来确保正确的加载顺序。问题主要集中在微软 Visual Studio 的编译和 pdb 文件的写入上。编译器有时在写出可执行文件时先写出 pdb,这会导致可执行文件无法加载,进而影响调试和热加载过程。创建锁文件可以防止这个问题,确保 pdb 完全写入后才进行加载,从而避免因 pdb 文件未完全写入导致的问题。