`

一个基于组合模式的游戏地图系统

 
阅读更多

from: http://blog.csdn.net/popy007/article/details/8301133

 

一个基于组合模式的游戏地图系统

 

地图系统

 

地图系统是游戏开发永恒不变的一个主题。在大多数游戏开发中,我们都需要和地图打交道。不同的游戏可能采用不同的地图系统,比如对于2D游戏来说,可能的地图类型包括:

 

1)Rectangular tile,即矩形tile。

2)Isometric,即等测地图。

3)Hexagonal tile,即六边形tile。

 

等等。

 



 

而对于3D游戏来说,一般包括两种主要类型:

 

1)基于3D空间的2D地图

2)完全3D空间地图

 

对于第一种类型,实际上是2D地图系统的一种3D推广,游戏中的地图还是在一个2D平面上,但是在3D空间的一个平面上。场景中的游戏对象可以都是3D模型。但地图本身仍然通过2D地图的方式进行处理。

 

第二种一般在3D图形学中叫做场景管理(Scene Management)。这是对真3D场景的一种处理方式:地图信息不再处于某个平面上,而是具有任意的3D几何信息。对于处理这种非规则的3D几何地图系统,我们一般采用分类的方式进行单独处理,比如:

 

1)室外地形系统

2)室内地图系统

3)基于portal的系统

 

等等。针对不同的类型,3D场景系统一般采用不同的管理方法,比如quadtree、octree、bsp、portal等等场景管理方式。可以说这个领域很广泛、也很复杂。

 

我们当然不可能具体地讨论所有这些地图系统。那么我们讨论什么呢?我们将讨论一种思想,这种思想贯穿于所有的这些地图管理方法之中,以提供一种健壮、合理、便利的代码结构。而这种结构不论是在游戏产品还是在开发工具中,都扮演着举足轻重的作用。这就是层次体结构。

 

 

层次体结构

 

对于复杂的问题以及结构,我们都倾向于一种称为“分治法”的方式进行处理。层次体结构实际上就是一种分治法,它通过一种树形结构来表示“整体-部分”的层次概念。基于这种方法,开发者可以很容易地对系统进行不同等级的灵活控制,同时获得一种复用性优势。

 

我们来举一个简单例子,来让大家更好地理解这些抽象概念。对于最简单的2D矩形tile引擎来说,开发者们经常会把场景分成多个层(layer)和一个根(root),如下图所示:

 



这就是一个最简单的层次体结构。它表明了一种整体和局部的从属关系:root可以看作这个地图本身,它代表整体。而它的子结点,则看作是这个地图的每个层,他们代表局部,属于整体。我们再具体一点,假设我们把地图分成了3层:


Layer 1 - 地面层

Layer 2 - 中间层

Layer 3 - 天空层


地 面层是永远处于”最下面“的层,地图上的任何东西都会处于它的上面,这一层包括普通土地、草坪、沙土地、公路等类型的tile。中间层就是地图上的对象 层,它永远处于地面层之上,这一层包括:房子、树木、玩家角色、NPC等活动对象,这些对象之间的位置关系会随时变化,因此互相遮挡的关系也会变化,需要 实时进行排序。天空层包括天上飞的鸟、飘浮的云朵等对象,它们永远处于地面层之上。


更进一步地,我们可以在每个layer上再增加子layer——这可以根据具体游戏对象的类型,比如把所有沙土地对象,都放到一个layer上,当玩家走到上面的时候,会减慢速度。如下图所示:

 



如我们所看到的,对这些对象进行3个layer分类,我们获得了很多好处:

 

1)分区渲染-渲染的顺序可以通过layer自然的处理:地面、中间、天空,这样的顺序保证了渲染结果的可视关系的正确。

2)分区更新-只有中间层的对象需要实时排序,这避免了对无需排序对象进行排序的无效计算。另外,可以直接用沙土层和玩家做碰撞检测——避免了不必要的计算。

3)总体控制-在对地图进行编辑的时候,我们可以非常方便地显示、隐藏、移动、删除不同的层。被操作的每个层上的对象都得到统一的处理。

 

而 这些好处也不仅仅局限于矩形2D tile地图,任何地图系统都可以从中得到这样的好处。比如在3D的场景管理中,quadtree、octree、bsp本身就是一种层次体结构。它们通 过树形结构对场景进行划分,从而以一定的规则将场景中的多边形安排到树中。另外,对于3D的所谓保留模式(Retained Mode)渲染,实际上就是通过把场景安排成一颗场景树来进行处理。系统一般会提供一个类似这样的接口:

 

void GraphicsEngine::render( SceneNode& sceneTreeRoot );

 

sceneTreeRoot就是场景树的根结点,从该结点向下就可以遍历整个树形结构,并进行任何你希望的操作——这当然以渲染为主。

 

在一些支持保留模式渲染的引擎中,一般设计师或美工会通过一些所见即所得的工具进行场景编辑,放置模型,虚拟物体,架设相机等等。最后导出一个文件,供引擎使用。而导出的往往就是一颗场景树,连相机都会作为一个结点存在于该结构中。

 

复用性

 

层 次体结构的另一个巨大优势在于复用性,而这往往体现在设计和实现两个层面上。想象我们在地图里面将几块石头摆放成了一种特殊形状,这种形状暗示了某种游戏 中的宗教意义。而根据设计需求,该形状可能会摆在地图中的很多位置。由于整个地图通过组合模式被建立成了一棵场景树,我们则可以把这个形状的几个石头,单 独的做成一个子layer。然后在不同的地方(结点)放置这些子layer。而在代码级别上,这些layer中的石头实际上是通过类对象指针保存的,因此 存放开销完全可以接受。所以,我们每次给一个结点增加一个这样的layer,就添加了这些石头所组成的一个形状——我们实际上是通过一种组合的方式进行特 定结构的复用。请注意,这些复用是可以嵌套的!这意味着你可以用这些子layer再组合更复杂的层,然后服用这些更复杂的layer。这种复用带来的威力 是巨大的,在两方面提供优势:

 

1)设计开销 -通过定义一个子layer,我们可以反复使用该layer,还可以嵌套!

2)内存开销 -只通过指针存储对象,实际对象内存只有一份。

 



这种复用性带来的利益驱使我们开发了一套2D动画系统——用场景树的方式组织动画。允许对不同复杂组件(可以看作这里的layer)的嵌套。以后如果条件允许,我会写一篇关于该系统的文章,帮助一下初学游戏开发的朋友理解2D动画系统。

 

 

 

层次体的简单实现

 

层次体结构实际上是一种组合(Composite)模式。根据GoF的著作《设计模式》所描述:组合模式通过一种树形结构来体现一种“整体和部分”的观念,从而让处理单一对象和对象聚合存在一种统一的形式。下图所示即组合模式:

 



Leaf 是单一对象,composite是组合对象,也就是一个对象聚合体。它们都继承自component类,拥有相同的操作方式Operation——这是关 键,也是组合模式的核心思想:在客户(client)看来,操作一个leaf和一个composite没什么区别,都调用它的Operation,但 composite是个聚合体,它会在自己的Operation中调用每一个聚合对象的Operation。

 

这里单一对象就可以理解为地图中的一个具体对象(树木、房子、NPC等等),而组合对象则可以看成是地图的一个layer——它聚合其它对象(树木、房子、NPC,或者是另一个layer)。

 

下面我们实现一个简单的层次体结构,从代码级别来深入认识该系统:

 

class MapNode
{
public:
	virtual ~MapNode() {}

	virtual void cycle() = 0;
	virtual void draw( GraphicsContext& g ) = 0;
};

class Node_Layer : public MapNode
{
public:

	void addChild( SceneNode* child )
	{
		m_children.push_back( child );
	}

	void removeChild( SceneNode* child )
	{
		for( std::vector< SceneNode* >::iterator it = m_children.begin();
			it != m_children.end(); ++it )
		{
			if( *it == child )
			{
				m_children.erase( it );
				break;
			}
		}
	}

	virtual void cycle()
	{
		for( int i = 0; i < m_children.size(); ++i )
		{
			m_children[i]->cycle();
		}
	}

	virtual void draw( GraphicsContext& g )
	{
		for( int i = 0; i < m_children.size(); ++i )
		{
			m_children[i]->draw( g );
		}
	}


protected:
	std::vector< SceneNode* > m_children;
};

class Node_Tree : public MapNode
{
public:

	virtual void cycle()
	{
		Update the state of the tree...
	}

	virtual void draw( GraphicsContext& g )
	{
		Draw the tree via g...
	}
};

 

 

以上是一个非常简单的组合代码结构。 MapNode是地图结点基类,我们用它的指针或引用来操作整个系统。它提供两个抽象方法

 

void MapNode::cycle

void MapNode::draw

 

分 别用来进行帧更新和渲染,具体实现由子类决定。Node_Layer就是地图层类,它就是所谓的聚合体。Node_Tree是一个单一对象,它表示地图上 的树这种对象。可以看到它们对具体操作的实现清晰地表达了整体-部分的思路:Node_Layer把操作分散到各个子对象中,而Node_Tree则是老 老实实作自己的事情。这便是一个最简单的层次体结构实现。一个简单的游戏和可能会如此使用上述代码:

 

class Node_Root : public Node_Layer {};

class Node_Player : public MapNode
{
public:

	virtual void cycle()
	{
		Update the state of the player...
	}

	virtual void draw( GraphicsContext& g )
	{
		Draw the player via g...
	}
};

Node_Root root;
Node_Player player;
Node_Tree tree;

root.addChild( &player );
root.addChild( &tree );

for(;;)
{
	root.cycle();
	root.draw( g );
}

 

 

我们建立了一个root类作为世界的根结点。然后生成了一个玩家和一棵树,都放进了场景里,接着进入了我们的游戏循环。还有比这更简单的么?

 

以该结构作为一个开始,开发者可以进行扩展。包括加入MapNode的共性成员:

 

位置

可见性标志

 

等等。对于非聚合类型的MapNode子类的设计,那就和你的游戏相关了。比如对于Node_Player来说,可以增加移动控制、生命、动画等等。这里提供的只是一种设计上的思路,而经过开发者的细节设计和扩展,该系统将发挥实际功效。

 

 

总结

 

上 面我们介绍了层次体概念以及该结构的简单实现。它是一种优秀的地图系统、场景管理方法。不论是在2D还是3D中,都可以发挥巨大的威力。不论对于游戏开发 初学者还是专家,在实际的游戏代码中你都会看到它的影子。因此,独立地考察和分析该系统对于开发者来说都是有很必要的。

 

 

 

 

 

 

 

  • 大小: 86.8 KB
  • 大小: 25.7 KB
  • 大小: 56.1 KB
  • 大小: 123.7 KB
  • 大小: 8.2 KB
分享到:
评论

相关推荐

    软件设计模式实验2结构型模式源码

    组合模式:用组合模式显示其所选商品信息,并计算所选商品总价的功能。说明:假如王同学到万达生活用品店购物。用 1 个红色小袋子装了 2 包衡阳特产(单价 25 元)、1 张衡阳地图(单价5.8元).....5.享元模式:在...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    Sqlite 一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中 W3C 万维网联盟,创建于1994年,是Web技术领域最具权威和影响力的国际中立性技术标准机构。主要的工作是发展 Web 规范,...

    海洋CMS 影视管理系统

    海洋CMS 影视管理系统,海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的...

    数据库系统的一些专用词汇表.txt

    关键字( Primary Key ): 表中的一个属性或几个属性的组合、其值能唯一地标识关系中的一个元组。关键字属性不能取空值。 . 外部关键字(Forgien Key): 在一个关系中含有的与另一个关系的关键字相对应的属性组称为该...

    seacms海洋cms影视管理系统 v9.1.zip

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    海洋cms(海洋影视管理系统) 视频点播系统源码

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    UML和模式应用(架构师必备).part02.rar

    3.4 案例二:Monopoly游戏系统 第二部分 初 始 阶 段 第4章 初始不是需求阶段 4.1 什么是初始 4.2 初始阶段的持续时间 4.3 初始阶段会创建的制品 4.4 何时知道自己并不了解初始阶段 4.5 初始阶段中有多少UML...

    UML和模式应用(架构师必备).part06.rar

    3.4 案例二:Monopoly游戏系统 第二部分 初 始 阶 段 第4章 初始不是需求阶段 4.1 什么是初始 4.2 初始阶段的持续时间 4.3 初始阶段会创建的制品 4.4 何时知道自己并不了解初始阶段 4.5 初始阶段中有多少UML...

    yershop开源网店系统 v3.8.2.zip

    插件开发是一个系统必不可少的部分,一个很好的插件机制是非常重要的,TinyShop的插件开发设计的特别的简单易用,可以是只是视图的Widget,也可以是功能强大的逻辑处理,同样也可以是两都的完善结合,插件的设计在...

    海洋cms(海洋视频内容管理系统) v12.5 bulid220618

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    海洋cms(海洋视频内容管理系统) v12.6 bulid220921.zip

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    海洋cms影视管理系统v11.3 快速架设海量视频讯息网站+模板众多插件齐全

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    DbSite企业网站管理系统 1.5.0.rar

    DbSite企业网站管理系统采用.Net构架,根据需求可配置多种数据库,全站基于SEO核心开发,界面与数据完全分离,内置多个常用网站模块:企业基础信息模块,新闻资讯模块,产品模块,在线留言模块,下载模块,招聘模块...

    新酷CMS网站管理系统 10.018.78.rar

    本系统采用ASP FSO ACESS,建站成本低廉、快速,可以快速建立一个界面好、功能强、安全性高的中小型WEB站点。 3、功能强大: 本系统定位于中小型ASP网站程序,前后台操作方便,功能强大。 4、个性设置: 本系统...

    诚和道微电影CMS整站程序

    诚和道微电影CMS程序是基于织梦开发的一套HTML5自适应微电影程序,风格基本跟"V电影"相似,功能可以满足想要做一个大型微电影网站的用户需求。 诚和道科技为符合SEO要求开发大量功能,比如百度结构化数据生成,搜索...

    海洋cms(海洋视频内容管理系统) v12.5

    海洋影视管理系统(seacms,海洋cms)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需5分钟即可建立一个海量的视频讯息的行业网站。...

    MallBuilder 多用户商城管理系统 v1.0 简体中文版

    站主来说是B2B网站,对于会员来说相当于一个B2C模式,结合在线支付工具,会员 可以自主开设商铺,实现产品在线销售与订购,如淘宝类的购物一样, 拥有完整的产品 在线交易流程. 在线销售 完整的多用户商城...

    UML和模式应用(架构师必备).part01.rar

    3.4 案例二:Monopoly游戏系统 第二部分 初 始 阶 段 第4章 初始不是需求阶段 4.1 什么是初始 4.2 初始阶段的持续时间 4.3 初始阶段会创建的制品 4.4 何时知道自己并不了解初始阶段 4.5 初始阶段中有多少UML...

    UML和模式应用(架构师必备).part07.rar

    3.4 案例二:Monopoly游戏系统 第二部分 初 始 阶 段 第4章 初始不是需求阶段 4.1 什么是初始 4.2 初始阶段的持续时间 4.3 初始阶段会创建的制品 4.4 何时知道自己并不了解初始阶段 4.5 初始阶段中有多少UML...

    UML和模式应用(架构师必备).part03.rar

    3.4 案例二:Monopoly游戏系统 第二部分 初 始 阶 段 第4章 初始不是需求阶段 4.1 什么是初始 4.2 初始阶段的持续时间 4.3 初始阶段会创建的制品 4.4 何时知道自己并不了解初始阶段 4.5 初始阶段中有多少UML...

Global site tag (gtag.js) - Google Analytics