第11章 斜角瓦片地图
斜角瓦片地图使用2D图形来获得3D效果。由于它汲取了两者的优势,因此受到了广泛使用。
11.1 设计斜角瓦片地图图形
斜角瓦片地图使用轴测投影(axonometric projection)。这种投影让人以为是从一个角度在观察场景,从而产生视觉深度。轴测投影是一个技术术语,表示将一个旋转过的三维物体投影到二维平面上。得到的图像虽然斜了过来,但我们的大脑会以为它是一个三维物体。
11.2 使用Tiled编辑斜角瓦片地图
11.2.1 新建一个斜角瓦片地图
如果已经设置错误的瓦片大小,而又不想浪费了花几个小时设计好的瓦片地图,或者出于别的原因想修改瓦片地图大小或瓦片集的大小,有一个简单的方法可以做到。选择Xcode项目中的TMX文件,你就会看到它其实是纯文本的XML文件。在开头部分找到map节点,可以修改tilewidth和tileheight参数,直到觉得瓦片地图正确为止,同样,如果无法确定斜角瓦片集的大小,也可以修改瓦片集的tilewidth和tileheight参数。确保每次手工修改TMX文件后都在Tiled中重新加载,因为Tiled不会自动更新文件。
11.2.2 创建新的斜角瓦片集
注意,Tiled会默认Tile width和Tile height为前面在New Map对话框中设定的值,由于斜角瓦片的重叠,默认值总是要修改的,必须使用邪教瓦片的图像高度而不是菱形的高度。
11.2.3 设计斜角瓦片地图的基本规则
设计斜角瓦片地图最重要的规则是:至少要用两个层,这样游戏角色才能在某些物体的背后走动。一个层用来放置地面物体和地面瓦片,另一个层用来放置和其他瓦片重叠的物品或透明的物品。
11.3 将斜角瓦片地图应用到游戏编程中
11.3.1 在cocos2d中加载斜角瓦片地图
11.3.2 在cocos2d中设置斜角瓦片地图
默认情况下,为了初始化cocos2d,模版会在应用程序代理的applicationDidFinishLaunching方法中添加一个宏:
CC_DIRECTOR_INIT();
CC_DIRECTOR_INIT宏的定义保存在ccMacros.h中,它以一种标准的方式来初始化cocos2d。虽然这种初始化方法对于大多数游戏都是可以的,但对于斜角瓦片地图游戏就不行。
初始化cocos2d是需要修改EAGLView的某些参数。有两个地方需要修改:首先,启用OpenGL的深度缓冲区功能以更好地控制物体的z轴次序;其次,CCDirector必须使用2D投影才能和深度缓冲区协同工作。
深度缓冲区可以让OpenGL确定某个像素是在另一个像素之前还是之后,因而OpenGL可以决定是绘制这个新像素还是忽略它。这会带来额外的内存开销——24位的深度缓冲区差不多有500KB——但它让精灵和瓦片能正确地重叠在一起。
11.3.3 定位一个斜角瓦片
11.3.4 滚动斜角瓦片地图
11.3.5 斜角瓦片地图的边界问题
11.3.6 增加一个可移动的玩家角色
玩家角色是一个类,名为Player,它继承自CCSprite。
玩家角色的位置被故意设置为屏幕的中央。由于已经有一个方法可以将特定的瓦片移动到屏幕中央,因此将玩家角色放置在屏幕中央,可以让人感觉玩家角色在瓦片地图上行走。而实际上,玩家角色一直保持在统一位置。你完全不需要移动角色精灵。
1.使角色移动时被物体遮住
为了使角色可以被身前的物体(比如建筑、墙、树木等)部分遮住,随着角色的移动,你需要修改它的vertexZ值。
2.一块瓦片接一块哇哦地移动角色
4个CGRect变量——upperLeft、lowerLeft、upperRight和lowerRight,将屏幕分为4个象限。单击其中一个象限,角色就会朝这个方向移动。
3.碰撞检测
增加一个新的层并命名为Collisions,然后条件透明度滑块到差不多中间的位置。
在Tile Properties对话框中添加一个属性并取名为blocks_movement,再将它的值设为1。实际上,我在代码中会忽略这个值,关键是block_movement属性要有个值存在。
在Collisions层选中的情况下,将带有block_movement属性的瓦片画在地图上任何不可穿越的地方。
11.4 在游戏中加入更多内容
移动NPC(non-player character,非玩家角色)是需要NPC执行动作的,而且移动方向需要反转——因为这里不可以移动层,需要直接移动NPC。
一旦NPC可以移动,接下来要解决的就是如何使它们以最短路径从A移动到B,途中还要避开障碍物。解决的方法称为iA*路径算法。
斜角瓦片地图使用2D图形来获得3D效果。由于它汲取了两者的优势,因此受到了广泛使用。
11.1 设计斜角瓦片地图图形
斜角瓦片地图使用轴测投影(axonometric projection)。这种投影让人以为是从一个角度在观察场景,从而产生视觉深度。轴测投影是一个技术术语,表示将一个旋转过的三维物体投影到二维平面上。得到的图像虽然斜了过来,但我们的大脑会以为它是一个三维物体。
11.2 使用Tiled编辑斜角瓦片地图
11.2.1 新建一个斜角瓦片地图
如果已经设置错误的瓦片大小,而又不想浪费了花几个小时设计好的瓦片地图,或者出于别的原因想修改瓦片地图大小或瓦片集的大小,有一个简单的方法可以做到。选择Xcode项目中的TMX文件,你就会看到它其实是纯文本的XML文件。在开头部分找到map节点,可以修改tilewidth和tileheight参数,直到觉得瓦片地图正确为止,同样,如果无法确定斜角瓦片集的大小,也可以修改瓦片集的tilewidth和tileheight参数。确保每次手工修改TMX文件后都在Tiled中重新加载,因为Tiled不会自动更新文件。
11.2.2 创建新的斜角瓦片集
注意,Tiled会默认Tile width和Tile height为前面在New Map对话框中设定的值,由于斜角瓦片的重叠,默认值总是要修改的,必须使用邪教瓦片的图像高度而不是菱形的高度。
11.2.3 设计斜角瓦片地图的基本规则
设计斜角瓦片地图最重要的规则是:至少要用两个层,这样游戏角色才能在某些物体的背后走动。一个层用来放置地面物体和地面瓦片,另一个层用来放置和其他瓦片重叠的物品或透明的物品。
11.3 将斜角瓦片地图应用到游戏编程中
11.3.1 在cocos2d中加载斜角瓦片地图
11.3.2 在cocos2d中设置斜角瓦片地图
默认情况下,为了初始化cocos2d,模版会在应用程序代理的applicationDidFinishLaunching方法中添加一个宏:
CC_DIRECTOR_INIT();
CC_DIRECTOR_INIT宏的定义保存在ccMacros.h中,它以一种标准的方式来初始化cocos2d。虽然这种初始化方法对于大多数游戏都是可以的,但对于斜角瓦片地图游戏就不行。
初始化cocos2d是需要修改EAGLView的某些参数。有两个地方需要修改:首先,启用OpenGL的深度缓冲区功能以更好地控制物体的z轴次序;其次,CCDirector必须使用2D投影才能和深度缓冲区协同工作。
深度缓冲区可以让OpenGL确定某个像素是在另一个像素之前还是之后,因而OpenGL可以决定是绘制这个新像素还是忽略它。这会带来额外的内存开销——24位的深度缓冲区差不多有500KB——但它让精灵和瓦片能正确地重叠在一起。
11.3.3 定位一个斜角瓦片
11.3.4 滚动斜角瓦片地图
11.3.5 斜角瓦片地图的边界问题
11.3.6 增加一个可移动的玩家角色
玩家角色是一个类,名为Player,它继承自CCSprite。
玩家角色的位置被故意设置为屏幕的中央。由于已经有一个方法可以将特定的瓦片移动到屏幕中央,因此将玩家角色放置在屏幕中央,可以让人感觉玩家角色在瓦片地图上行走。而实际上,玩家角色一直保持在统一位置。你完全不需要移动角色精灵。
1.使角色移动时被物体遮住
为了使角色可以被身前的物体(比如建筑、墙、树木等)部分遮住,随着角色的移动,你需要修改它的vertexZ值。
2.一块瓦片接一块哇哦地移动角色
4个CGRect变量——upperLeft、lowerLeft、upperRight和lowerRight,将屏幕分为4个象限。单击其中一个象限,角色就会朝这个方向移动。
3.碰撞检测
增加一个新的层并命名为Collisions,然后条件透明度滑块到差不多中间的位置。
在Tile Properties对话框中添加一个属性并取名为blocks_movement,再将它的值设为1。实际上,我在代码中会忽略这个值,关键是block_movement属性要有个值存在。
在Collisions层选中的情况下,将带有block_movement属性的瓦片画在地图上任何不可穿越的地方。
11.4 在游戏中加入更多内容
移动NPC(non-player character,非玩家角色)是需要NPC执行动作的,而且移动方向需要反转——因为这里不可以移动层,需要直接移动NPC。
一旦NPC可以移动,接下来要解决的就是如何使它们以最短路径从A移动到B,途中还要避开障碍物。解决的方法称为iA*路径算法。