摩登城市的斜45度地图处理及物件图片展示方案

发表于2016-03-04
评论6 2.9k浏览

在2D游戏中,通常会采用斜45度地图的处理方案(也称为2.5D)来展现整个游戏世界,相对于正面俯视的2D游戏,斜45度地图可以更好地展示游戏世界的立体感和真实感,给玩家更好的游戏体验。

本方案主要是针对摩登城市的斜45度地图需求的处理方案的整理,对摩登城市中使用的斜45度地图tile坐标系、物件(例如建筑)的绑定和显示以及物件的深度排序三个方面所用到的一些技术点和细节进行总结。

摩登城市游戏世界一览图

 

一、斜45度地图的tile坐标系

1.1 Tile坐标系

  我们将整个游戏世界地图划为斜45度的格子,如图1.1所示,所得到的坐标系称为Tile坐标系,其中每一个格子称为一个Tile,是地图上物件的最小单位。在摩登城市里,这个tile的大小被设置为40*20像素。

Tile坐标中,可以方便地定位物件、记录物件在地图上的占位情况、以及处理后续的深度排序。

图1.1 tile坐标示意图

 

  关于Tile坐标,还要说明一点,由于游戏中的世界地图和游戏屏幕都是矩形,而Tile地图是斜45度的菱形,因此并不是所有的Tile坐标都是游戏中可用的,真正可用的部分是世界地图和Tile坐标重合的部分,如图1.1所示,只有世界地图的矩形内的Tile坐标才是有效的,而其他区域是游戏中可用的。

 

1.2 Tile坐标系下的建筑位置信息同步

利用Tile坐标来记录物件,可以方便地与服务端通信,获取或记录物件在世界地图上的位置信息。在摩登城市中,客户端与服务端预先约定,通过物件的Tile坐标,按约定的公式

Index = WIDHT * tielY + tileX

计算索引值index与服务端进行建筑位置信息的同步,其中WIDTH是客户端和服务器约定的最大tileX坐标。

当玩家操作建筑改变建筑位置信息时(例如移动、新建、删除等),客户端会根据上述公式计算索引值index发送给服务端,服务端会根据这个值来记录物件在地图上的位置;当玩家登陆游戏时,服务器会将建筑物件的索引值index下发,客户端按照约定的公式可以解析出物件的tileXtileY,从而计算物件在地图上的位置信息并显示建筑。

 

二、物件的展示

在斜45度地图的tile坐标中,每个物件的占位都是以tile为单位。

为了更清晰地处理物件的展示,我们将物件的逻辑处理和图片展示分离开来,由单独的类将所有需要展示的元素都加入到一个容器中(如sprite),独立地进行对图片展示的管理和操作。

 

2.1普通静态图片的展示

在摩登城市中,物件如建筑具有最多4个方向,为此我们做以下的名称约定:物件id和方向组合成图片名称id_direction.png,方向取值为0-3

在将物件添加到场景时,都是以物件底座的左下角为绑定点。因此我们需要获取每张物件图片的绑定点相对于图片左上角的偏移像素值(biasX,biasY) ,如图2.1所示。这套数值预先由策划在配置表中配置,展示时由程序从配置表读取。

图2.1 绑定点偏移值示意图


   在加载图片后,首先将图片加入到之前所述的图片管理容器中,之后根据物件的占位信息,通过坐标变换公式计算出物件左下角所对应的世界坐标,并将图片容器的坐标值设置为物件左下角的世界坐标值,如图2.2所示。黑色的3*3的范围是该物件对应的tile占位信息,红色的tile是物件左下角对应的tile

图2.2 物件占位与初始加入场景示意图

 

  为了将图片中物件的底座与其占位的tile重合,将图片容器的位置移动(-biasX,-biasY)即可,如图2.3所示。

图2.3 物件展示示意图

 

2.2动画

除了普通的静态图片,游戏中还需要增加动画类的物件。目前摩登城市中支持的动画格式有两种,swf动画和rsc动画。这两种动画的名称约定分别是:Swf动画B(id)_(direction)rsc动画E(id)_(direction),其中iddirection分别是物件的id和方向,方向取值0-3

 根据物件带有动画的类型,可以分为无动画、swf动画、rsc动画、纯swf动画和纯rsc动画五种,动画类型可以由策划按需求在配置表中配置。

 需要注意的是,在出两种动画资源的时候,已经调整好动画相对于静态底图的相对位置。程序在处理时,对于swf类型的动画,加载并生成约定导出类的对象,添加到图片容器中;对于rsc类型的动画,加载资源并添加到图片容器中,并按每帧播放。注意添加的顺序是先添加静态底图,再添加动画,确保动画显示在静态底图之上。

 

2.3可拼接的静态图片

普通的静态图片物件只需要一张png图片即可展示,但是有一些物件是需要由程序根据其属性动态处理其显示内容,对于这类需求,我们选择的处理方式时切割大图,由程序按需求控制拼接。

 

2.3.1 可增高图片

对于某些特殊的建筑,会根据建筑的等级变动层高,为了节省资源,可以将固定的部分和动态变化的部分分割成几张小图,由程序控制图片的合成。

2.4是一种可以随层级增加而升高的建筑切割示意图。对于图中所示的建筑,我们首先加载三张分割图片,并且计算三张图片的高度,根据层级的数量计算出需要显示的动态增高部分(b图),之后按照顺序将顶、层级数量对应的动态增高部分和底座依次加入容器,每添加一张,需要重新计算一下当前组合图片的总高度,并将下一张需要加入的图片的坐标设置为总高度,确保分割图的各个部分可以无缝拼接。实际的效果可以参看图2.5

a.底座

b.动态增高部分

c.顶

图2.4 可增高的建筑切割示意图

 

图2.5 不同层高的建筑实际效果图

 

2.3.2围栏

另一类动态拼接的图片是围栏类型的图片,这类图片会根据当前物件底座大小的不同而不同。如图2.6所示,分别是剪彩和市政缺人的两类围栏。

为了实现这样的效果,我们需要对围栏素材进行剪切,以市政缺人的围栏为例(只是素材不同,处理方法完全一致),根据围栏的组成,我们可以将其分为以下四个不同的部分,如图2.7所示。

图2.6 围栏效果示意图

图2.7 围栏素材与对应于成品图的位置示意图

 

素材中的四个素材分别对应于图2.7中四个红框圈出的位置。

  我们假设物件的tile占位是tileLengthtileWidth(分别对应于tile坐标系的xy轴),那么可以看出,为了将四个小素材合成一个完整的围栏,我们需要

1a

2* tileWidth -1b

2* tileLength -1c

1d

tileLengh=3tileWidth=3的物件围栏为例,其排列位置如图2.8所示。

图2.8 tileLengh=3,tileWidth=3的围栏素材位置示意图


如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引