RPG游戏 01-人物行走和地图图块

要开发一个游戏,地图是首先应该考虑的,我这里使用的是tiled来编辑地图。tiled对于一般的游戏开发还行,相对通用,不过也没有那么强的针对性。所以在开发游戏时要对从tiled解析的内容里再在程序中进行相应的处理。

今天考虑的是图块,对于图块,如果简单地分的话可以分为两种属性:1.priority属性 2.pass_down  pass_left pass_right pass_up

priprity,顾名思义,就是优先级的意思,这里可以规定为0角色不可通过 1角色可通过,并且主角覆盖改图块 2角色可通过,图块在角色之上。

对于pass_%s 则是指的是对于一些特殊图块而言。比如这种


这种图块主角是可以在上面的,只不过某些方向不可通过,这就需要在程序中特殊处理。上图,主角向右是无法通行的。

关于寻路算法,大家可以参考A*算法,然后加上这种判断即可,比如我在代码中就是每次只能移动一格。以上图为例,下一个可以通过,但是从本图块到下一图块的pass_right 为false,这就无法过去了。反之亦然。

另外一个就是遮挡问题。这个问题虽然对于游戏性没什么关系,但是却相当重要。我的思路如下:把能和角色放生碰撞的层称之为碰撞层,然后角色也要加到碰撞层中。对于priprity为0的,因为无法通过,自然不存在什么遮挡问题,这时需要考虑和其他图块的遮挡问题。如果为1的主角的要在这些图块之后渲染,对应为2 的,则相反。

实现大致如下。

这里的tmx是我自己解析的,所以我就规定,从左至右 从上至下图块的localZOrder依次增大。这样能实现图块之间的遮挡关系。然后对于priority为2的单独处理。代码大致如下。

	//保存所有优先级为2的图块
	vector<int> tileIds;
	auto tilesets = m_pTiledMap->getTilesets();

	for (auto tileset : tilesets)
	{
		auto& properties = tileset->getProperties();
		
		for(auto itMap = properties.cbegin();itMap != properties.cend();itMap++)
		{
			auto id = itMap->first;
			auto& valueMap= itMap->second;

			auto it = valueMap.find("priority");

			if (it != valueMap.cend() && it->second.asInt() == 2)
				tileIds.push_back(id + tileset->firstGrid);
		}
	}
	//设置优先级为2的图块localZOrder
	auto& children = this->getCollisionLayer()->getChildren();

	for (auto child : children)
	{
		//获取精灵的名字
		auto name = child->getName();

		if (name.empty()) continue;
		
		int id = SDL_atoi(name.c_str());
		//设置localZOrder
		if (find(tileIds.begin(),tileIds.end(),id) != tileIds.end())
		{
			child->setLocalZOrder(child->getLocalZOrder() + GameScene::CHARACTER_LOCAL_Z_ORDER);
		}
	}
<tileset name="Outside_A5" tilewidth="48" tileheight="48" tilecount="128" columns="8">
 <image source="Outside_A5.png" width="384" height="768"/>
 <tile id="0">
  <properties>
   <property name="pass" type="bool" value="false"/>
  </properties>
 </tile>
 <tile id="88">
  <properties>
   <property name="pass_left" type="bool" value="false"/>
   <property name="pass_up" type="bool" value="false"/>
  </properties>
 </tile>

注意上面的m_pTiledMap->getTilesets()获取的是tmx地图所使用的全部tileset。而下面的 auto& properties = tileset->getProperties()则是获取所有属性,其返回值是std::unordered_map<int,ValueMap>。

而接下开的则是获取tileset的图块属性来找出符合的图块。上面还有就是tileset对应的属性。


这样,在每次加载一个地图时,都需要一次设置即可,其他的就不需要处理了。当然,另外一个解决办法就是再有一个装饰层,使之在碰撞层后渲染,不过这样需要细心,也挺麻烦的。这个可以参考这个http://blog.csdn.net/lufy_Legend/article/details/17748629


发一张遮挡的图片。


  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值