Point destination=e.GetPosition(scene);
hero.RunTo(destination, scene.TerrainMatrix, scene.TerrainGridSize);
}
7.2基于2.5D斜视角之场景与寻径实现(交叉参考:斜度α地图的构造及算法游戏中斜视角的原理与分析场景编辑器让游戏开发更美好场景编辑器之开源畅想)
斜视角平面游戏我们又称之为2.5D游戏,它拥有一定程度上的3D透视效果,然而却不能任意的旋转角度。斜视角场景通过最简单的设定实现逼真的空间感,这让它成为目前大多数2D-RPG游戏的首选。
同样,如能为本课程的示例游戏也插上个斜视角的翅膀,无论是玩家的操控体验还是游戏趣味性都将提高很大一个档次;于是乎又得有劳于第二部教程中已开源的2D游戏场景编辑器。
打开场景编辑器,同样的首先载入场景中的地图背景图片,然后调整坐标系偏移量等参数使之与地图背景相吻合,然后对照背景在相应的位置上设置好障碍物后即可点击导出场景配置信息:
在导出的信息中我们只需选取部分数据复制到本课程场景Info.xml配置文件中即可:
<Scene FullName="龙门镇"MapWidth="3200"MapHeight="1320"OffsetX="1600"OffsetY="-1600"TerrainGridSize="30"TerrainGradient="60"TerrainMatrixDimension="128"Terrain="36_97_0,36_98_0,37_95_0,37_96_0,37_97_0,37_98_0,37_99_0,38_94_0,38_95_0,38_99_0,38_100_0,39_94_0,39_100_0,39_101_0,40_92_0,40_93_0,40_94_0,40_101_0,40_102_0,41_92_0,41_102_0,41_103_0,42_91_0,42_92_0,42_103_0,42_104_0,43_90_0,43_91_0,43_104_0,43_105_0,44_87_0,44_88_0,44_89_0,44_90_0,44_100_0,44_101_0,44_102_0,44_103_0,44_104_0,44_105_0,44_106_0,45_83_0,45_84_0,45_85_0,45_86_0,45_87_0,45_100_0,45_106_0,45_107_0,46_83_0,46_100_0,46_107_0,46_108_0,47_82_0,47_83_0,47_98_0,47_99_0,47_100_0,47_103_0,47_104_0,......">
<Masks>
<Mask Code="0"Opacity="0.5"X="155"Y="462"Z="630"/>
<Mask Code="1"Opacity="0.5"X="499"Y="618"Z="919"/>
<Mask Code="2"Opacity="0.5"X="1331"Y="175"Z="470"/>
<Mask Code="3"Opacity="0.5"X="1923"Y="411"Z="838"/>
</Masks>
</Scene>
针对斜视角,场景类中我们还得新增Offset及TerrainGradient属性,同时3个主要属性需要静态化(场景的核心参数,场景中的其他类都可能会用到):
另外修改相应的解析逻辑:
遮挡物的坐标也需要相应的减去场景的偏移量,否则会导致位置出错:
斜视角场景中的坐标以菱形方格为单位,于是我们需要为场景添加两个静态方法用于窗口像素坐标系与游戏菱形斜视角坐标系之间的坐标转换:
///将窗口坐标系中的坐标换算成游戏坐标系中的坐标
///</summary>
publicstaticPoint GetGameCoordinate(Point p) {
doubleradian=Global.GetRadian(TerrainGradient);
returnnewPoint(
(int)((p.Y/(2*Math.Cos(radian))+p.X/(2*Math.Sin(radian)))/TerrainGridSize),
(int)((p.Y/(2*Math.Cos(radian))-p.X/(2*Math.Sin(radian)))/TerrainGridSize)
);
}
///<summary>
///将游戏坐标系中的坐标换算成窗口坐标系中的坐标
///</summary>
publicstaticPoint GetWindowCoordinate(Point p) {
doubleradian=Global.GetRadian(TerrainGradient);
returnnewPoint(
(p.X-p.Y)*Math.Sin(radian)*TerrainGridSize,
(p.X+p.Y)*Math.Cos(radian)*TerrainGridSize
);
}
根据斜视角原理,为了匹配上斜视角地形移动,此时的精灵坐标属性Cooridinate非同以往,它代表的是基于斜视角的新场景坐标(以菱形方格为单位,Point类型,在移动过程中同样会存在小数情况以平滑):
当然,RunTo及其相关方法也避免不了重写:
注意了,本节我去掉了关键帧动画,取而代之的是用简单队列移动的形式实现A*寻路,同时精灵朝向的变化也改放到了每次直线移动方法中;不仅逻辑代码得到优化,精灵的整个移动过程更显优美而均匀。
另外还有一些需要重视的细节,比如为场景添加一个ConfigReady事件以实现配置文件加载完毕后进行相应的逻辑处理;以及注册游戏窗体尺寸改变事件以适应浏览器或窗口模式时窗体尺寸无论如何变化主角将永远居中效果: