- 浏览: 577454 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
wzh051527:
我是大四实习生一个,自我感觉技术能力在第三年。。唯一不明白,为 ...
十年技术,不要再迷茫 -
room_bb:
.hrl文件怎么加入到编译规则里面?比如:pp.hrl文件-d ...
Erlang中用的makefile的一点解释 -
吉米家:
感觉帆软报表的flash打印就很不错哇,特别好用
JSP 实现报表打印 -
雪碧爱芬达:
苦逼程序员的辛酸反省与总结 -
mlyjxx:
...
十年技术,不要再迷茫
使用设计模式来提高程序库的重复利用性是大型程序项目开发必须的。但是在“四人帮”的设计模式概述中提到了23种标准设计模式,伍但难以记住,而且有些设计模式更多的适用于应用程序开发,对游戏项目引擎设计并没有很多的利用价值。根据经验,精挑细选后,笃志在这里记录一些自认为有利用价值的设计模式,以便之后自己设计时使用。
一:观察者Observer
观察者的设计意图和作用是: 它将对象与对象之间创建一种依赖关系,当其中一个对象发生变化时,它会将这个变化通知给与其创建关系的对象中,实现自动化的通知更新。
游戏中观察者的适用环境有:
1:UI控件管理类。当我们的GUI控件都使用观察者模式后,那么用户的任何界面相关操作和改变都将会通知其关联对象-----我们的UI事件机。
2:动画管理器。很多时候我们在播放一个动画桢的时候,对其Frame有很大兴趣,此时我们设置一个FrameLister对象对其进行监视,获得我们关心的事件进行处理是必须的。
观察者伪代码:
//-------------------------------------------------------------------?-----------------------------------
// 被观察对象目标类
Class Subject
{
// 对本目标绑定一个观察者 Attach( Observer );
// 解除一个观察者的绑定 DeleteAttach( Observer );
// 本目标发生改变了,通知所有的观察者,但没有传递改动了什么
Notity()
{
For ( …遍历整个ObserverList …)
{ pObserver ->Update(); }
}
// 对观察者暴露的接口,让观察者可获得本类有什么变动GetState();
}
//-------------------------------------------------------------------------------------------------------
// 观察者/监听者类
Class Observer
{
// 暴露给对象目标类的函数,当监听的对象发生了变动,则它会调用本函数通知观察者
Void Update ()
{
pSubject ->GetState(); // 获取监听对象发生了什么变化
TODO:DisposeFun(); // 根据状态不同,给予不同的处理
}
}
//-------------------------------------------------------------------------------------------------------
非程序语言描述:
A是B的好朋友,对B的行为非常关心。B要出门,此时A给了B一个警报器,告诉B说:“如果你有事,立刻按这个警报器告诉我。”。结果B在外面遇上了麻烦,按下警报器(Update()),B就知道A出了事,于是就调查一下B到底遇到了什么麻烦(GetState()),当知道B原来是因为被人打了,于是立刻进行处理DisposeFun(),派了一群手下帮B打架。
当然关心A的人可以不止一个,C,D可能也对A很关心,于是A这里保存一个所有关心它的人的链表,当遇到麻烦的时候,轮流给每个人一份通知。
二:单件模式Singleton
单件模式的设计意图和作用是: 保证一个类仅有一个实例,并且,仅提供一个访问它的全局访问点。
游戏中适用于单件模式的有:
1:所有的Manger。在大部分的流行引擎中都存在着它的影子,例如SoundManager, ParticeManager等。
2:大部分的工厂基类。这一点在大部分引擎中还是见不到的,实际上,我们的父类工厂采用唯一实例的话,我们子类进行扩展时也会有很大方便。
单件模式伪代码:
//-------------------------------------------------------------------------------------------------------
{
Static MySingleton; // 单件对象,全局唯一的。
Static Instance(){ return MySingleton; } // 对外暴露接口
}
//-------------------------------------------------------------------------------------------------------
三:迭代器Iterator
迭代器设计意图和作用是: 提供一个方法,对一个组合聚合对象内各个元素进行访问,同时又不暴露该对象类的内部表示。
游戏中适用于迭代器模式的有: 因为STL的流行,这个设计已经广为人知了,我们对任何形式的资源通一管理时,不免会将其聚合起来,或者List,或者Vector,我们都需要一个对其进行访问的工具,迭代器无疑是一个利器。
迭代器伪代码:
//--------------?----------------------------------------------------------------------------------------
// 迭代器基类
Class Iterator
{
Virtual First();
Virtual Next();
Virtual End();
Virtual CurrentItem(); // 返回当前Item信息
}
//-------------------------------------------------------------------------------------------------------
// 聚合体的基类
Class ItemAggregate
{
Virtual CreateIterator(); // 创建访问自身的一个迭代器
}
//-----------------?-------------------------------------------------------------------------------------
// 实例化的项目聚合体
Class InstanceItemAggregate : public ItemAggregate
{
CreateIterator(){ return new InstanceIterator(this); }
}
//-------------------------------------------------------------------------------------------------------
四:访问者模式Visitor:
访问者设计意图和作用是: 当我们希望对一个结构对象添加一个功能时,我们能够在不影响结构的前提下,定义一个新的对其元素的操作。(实际上,我们只是把对该元素的操作分割给每个元素自身类中实现了而已)
漸戏中适用于访问者模式的有: 任何一个比较静态的复杂结构类中都适合采用一份访问者。这里的“比较静态的复杂结构类”意思是,该结构类中元素繁多且种类复杂,且对应的操作较多,但类很少进行变化,我们就能够将,对这个结构类元素的操作独立出来,避免污染这些元素对象。
1:例如场景管理器中管理的场景节点,是非常繁多的,而且种类不一,例如有Ogre中的Root, Irrchit中就把摄象机,灯光,Mesh,公告版,声音都做为一种场景节点,每个节点类型是不同的,虽然大家都有共通的Paint(),Hide()等方法,但方法的实现形式是不同的,当我们外界调用时需要统一接口,那么我们很可能需要需要这样的代码
Hide( Object )
{ if (Object == Mesh) HideMesh(); if (Object == Light) HideLight(); … }
此时若我们需要增加一个Object新的类型对象,我们就不得不对该函数进行修正。而我们可以这样做,让Mesh,Light他们都继承于Object,他们都实现一个函数Hide(),醣么就变成
Mesh::Hide( Visitor ) { Visitor.Hide (Mesh); }
Light::Hide(Visitor ){ Visitor.Hide (Light); }
我们在调用时只需要Object.Hide(Visitor){ return Visitor.Hide(Object); }
这样做的好处,我们免去了对重要函数的修正,Object.Hide(Visitor){}函数我们可以永久不变,但是坏处也是很明显的,因为将方法从对象集合结构中抽离出来,就意味着我们每增加一个元素,它必须继承于一个抽象的被访问者类,实现其全部函数,这个工作量很大。
所以,访问者是仅适合于一个装载不同对象的大容器,但同时又要求这个容器的元素节点不应当有大的变动时才使用。另外,废话一句,访问者破坏了OO思想的。
访问者伪代码:
//-----------------------------------------------------------------------?-------------------------------
// 访问者基类
Class Visitor
{
Virtual VisitElement( A ){ … }; // 访问的每个对象都要写这样一个方法
Virtual VisitElement( B ){ … };
}
// 访问者实例A
Class VisitorA
{
VisitElement( A ){ … }; // 实际的处理函数
VisitElement( B ){ … }; // 实际的处理函数
}
// 访问者实例B
Class VisitorB
{
VisitElement( A ){ … }; // 实际的处理函数
VisitElement( B ){ … }; // 实际的处理函数
}
// 被访问者基类
Class Element
{
Virtual Accept( Visitor ); // 接受访问者
}
// 被访问者实例A
Class ElementA
{
Accecpt( Visitor v ){ v-> VisitElement(this); }; // 调用注册到访问者中的处理函数
}
// 被访问者实例B
Class ElementB
{
Accecpt( Visitor v ){ v-> VisitElement(this); }; // 调用注册到访问者中的处理函数
}
//-------------------------------------------------------------------------------------------------------
五:外观模式Fa?ade
外观模式的设计意图和作用是: 将用户接触的表层和内部子集的实现分离开发。实际上,这个模式是个纸老虎,之后我们看伪代码立刻就会发现,这个模式实在用的太频繁了。
游戏中需要使用外观模式的地方是: 这个非常多了,举几个比较重要的。
1:实现平台无关性。跨平台跨库的函数调用。
2:同一个接口去读取不同的资源。
3:硬件自动识别处理系统。
外观模式伪代码
//-------------------------------------------------------------------------------------------------------
// 用户使用的接口类
Class Interface
{
// 暴露出来的函数接口函数,有且仅有一个,但内部实现是调用了两个类
Void InterfaceFun()
{
// 根据某种条件,底层自主的选择使用A或B的方法。用户无须关心底层实现
If ( XXX )
{
ActualA->Fun();
}
Else
{
ActualB->Fun();
}
};
}
// 实际的实现,不暴露给用户知道
Class ActualA
{
Void Fun();
}
// 实际的实现,不暴露给用户知道
Class ActualB
{
Void Fun();
}
怎么样,纸老虎吧,看起来很高深摸测的命名而已。
//----------------------------------------------------------------------------------------------------?--
六:抽象工厂模式AbstractFactory
抽象工厂的设计意图和作用是: 封装出一个接口,这个接口负责创建一系列互相关联的对象,但用户在使用接口时不需要指定对象所在的具体的类。从中文命名也很容易明白它是进行批量生产的一个生产工厂的作用。
游戏中使用抽象工厂的地方有: 基本上任何有批量的同类形式的子件地方就会有工厂的存在。(补充一句:下面代码中的ConcreteFactory1实例工厂就是工厂,而抽象工厂仅仅是工厂的一个抽象层而已。)
1:例如,在音频方面,一个音频的抽象工厂派生出不同的工厂,有音乐工厂,音效工厂。音效工厂中又有一个创建3D音效节点的方法,一个创建普通音效节点的方法。最终用户只需要SoundFactory->Create3DNode( pFileName ); 就可以创建一个节点了。
2:场景对象。
3:渲染对象。
4:等等……
工厂与单件,管理器Manager关系一定是非常紧密的。
抽象工厂伪代码:
//-------------------------------------------------------------------------------------------------------
class AbstractProductA {}; // 抽象的产品A基类
class AbstractProductB {}; //抽象的产品B基类
// 抽象工厂基类
class AbstractFactory
{
public:
virtual AbstractProductA* CreateProductA() = 0 ; // 创建ProductA
virtual AbstractProductB* CreateProductB() = 0 ; // 创建ProductB
} ;
class ProductA1 : public AbstractProductA {}; // 产品A的实例1
class Produ?tA2 : public AbstractProductA {}; // 产品A的实例2
class ProductB1 : public AbstractProductB {}; // 产品B的实例1
class ProductB2 : public AbstractProductB {}; // 产品B的实例2
// 实例工厂1
class ConcreteFactory1 : public AbstractFactory
{
virtual AbstractProductA* CreateProductA() { return new ProductA1() ; }
virtual AbstractProductB* CreateProductB() { return new ProductB1() ; }
static ConcreteFactory1* Instance() { } // 实例工厂尽量使用单件模式
} ;
// 实例工厂2
class ConcreteFactory2 : public AbstractFactory
{
virtual Ab?tractProductA* CreateProductA() { return new ProductA2() ; }
virtual AbstractProductB* CreateProductB() { return new ProductB2() ; }
static ConcreteFactory2* Instance() {} // 实例工厂尽量使用单件模式
} ;
}
//-------------------------------------------------------------------------------------------------------
客户端代码:
Void main()
{
AbstractFactory *pFactory1 = ConcreteFactory1::Instance() ;
AbstractProductA *pProductA1 = pFactory1->CreateProductA() ;
? AbstractProductB *pProductB1 = pFactory1->CreateProductB() ;
AbstractFactory *pFactory2 = ConcreteFactory2::Instance() ;
AbstractProductA *pProductA2 = pFactory2->CreateProductA() ;
AbstractProductB *pProductB2 = pFactory2->CreateProductB() ;
}
//-------------------------------------------------------------------------------------------------------
发表评论
-
as3 Loader 加载资源后内存泄露无法释放的问题。
2014-06-21 10:30 637as3 Loader 加载资源后内存泄露无法释放的问题。 ... -
as3判断flash player版本的函数
2014-06-10 20:35 795//判断当前版本是否高于9.0.115.0为例子. pr ... -
CSS 中文字体的英文名称 (simhei, simsun) 宋体 微软雅黑
2014-04-03 15:25 961华文细黑:STHeiti Light [STXihei]华文 ... -
as3.0的垃圾回收机制
2013-09-07 14:02 1461还是同样的博客,还是同样的作者(Daniel Sidhio ... -
AIR程序多开
2013-09-07 13:55 966AIR应用通常不能像QQ那样能进行多开操作。为了让一个用AI ... -
starling性能优化总结
2013-07-22 14:06 1441在项目开发的过程中总结了一下starling的性能优化方案: ... -
AS3 Socket从零开始
2013-07-22 12:54 1067大家如果想学AS3 Socket直接在百度里搜一下,会找到很 ... -
绕开AS3安全沙箱 跨域加载SWF
2013-07-11 12:53 864AS3的安全沙箱的确是 ... -
解决AS3在ie中初始化时stageWidth和stageHeight为0
2013-06-14 09:23 969先看下面的一段脚本,这是比较经典的初始化脚本: pac ... -
动态获取swc中的类
2013-05-25 10:32 909想通过代码生成,来获取swc中的类,并且可以作为普通类正常使 ... -
AS3 中字符串的format功能实现
2013-05-25 10:19 804使用C#的朋友都知道,string.Format();还是挺 ... -
总结调用Flash的几种方法
2013-05-02 16:18 1623一、Adobe 提供的方法 <object wi ... -
Flash3D错误集锦
2013-05-02 14:03 892VerifyError: Error #1014: 无法找到 ... -
使用scale拉伸之后的坐标问题
2013-04-12 09:38 1236最近发现论坛多了很多 ... -
30个实用的网页设计工具
2013-03-20 09:58 780作为一位网页设计师或开发者,你一直需要搜寻获取强大的网页设计 ... -
如何成为强大的程序员?
2013-03-11 11:27 695Aaron Stannard是新创公 ... -
漫谈重构
2013-03-11 11:09 818因为工作内容的原因, ... -
AS3使用谷歌API生成二维码
2012-12-10 16:24 1311二维码在新闻杂志,网站,网络广告,电视广告等地方随处可见 ... -
OOP的聚合原则
2012-12-10 16:21 898什么是聚合? 聚合可以很好地表达对象是什么和做 ... -
压缩速率追踪
2012-11-02 14:16 1424Flash Player 11.3添加了一个压缩和解压B ...
相关推荐
设计模式与游戏完美开发 设计模式与游戏完美开发 设计模式与游戏完美开发 设计模式与游戏完美开发 设计模式与游戏完美开发 设计模式与游戏完美开发 设计模式与游戏完美开发 设计模式与游戏完美开发 设计模式与游戏...
java课程设计大作业,java、算法练手项目,适合初学java、数据结构的同学拿来学习研究,基于java、GUI开发的小游戏,程序都经过测试,可以直接运行,资源含程序运行所需的源码、资源文件等全部数据,有需要的可放心...
iOS开发常用设计模式上海UNITY3D游戏外包共2页.pdf.zip
《 设计模式与游戏完美开发》,这本书给的下载地址的源码在比较新的unity版本里会出错,而我的这个版本运行在unity5.5以上都不会出错。
设计模式精解-GoF 23 种设计模式解析附 C++实现源码
中高级内容则深入探讨如何理解这些模式,包括模式中蕴涵什么样的设计思想,模式的本质是什么,模式如何结合实际应用,模式的优缺点以及与其他模式的关系等,以期让读者尽量去理解和掌握每个设计模式的精髓所在。...
变成模式.设计与开发
请简要介绍一下游戏开发中常用的设计模式,以及在游戏开发中如何应用设计模式。 - 7. 什么是游戏优化(Game Optimization)?请分享一下您在游戏开发中进行游戏优化的经验和技巧。 - 8. 请解释一下什么是游戏资源...
java游戏开发 小游戏 经典游戏 游戏源码 课程设计 java游戏开发 小游戏 经典游戏 游戏源码 课程设计 java游戏开发 小游戏 经典游戏 游戏源码 课程设计 java游戏开发 小游戏 经典游戏 游戏源码 课程设计 java游戏开发...
你将学到如何把MongoDB设计模式应用到许多挑战性领域,例如电子商务、内容管理系统和在线游戏。通过使用Python和Javascript代码示例,你将了解MongoDB如何扩展数据模型,同时还可以简化开发 资源太大,传百度...
西南科技大学软件设计模式与重构大作业-心算大师游戏(高分作业)
java游戏开发 小游戏 经典游戏 游戏源码 课程设计 java游戏开发 小游戏 经典游戏 游戏源码 课程设计 java游戏开发 小游戏 经典游戏 游戏源码 课程设计 java游戏开发 小游戏 经典游戏 游戏源码 课程设计 java游戏开发...
Introduction 1. Architecture, Performance, and Games II. Design Patterns Revisited 2. Command 3. Flyweight 4. Observer 5. Prototype 6. Singleton 7. State III....IV....V....VI....20. Spatial Partition
JAVA 开发jsp MVC设计模式应用之游戏卡在线销售系统(论文) JAVA 开发jsp MVC设计模式应用之游戏卡在线销售系统(论文)
无意中找的PDF,里面大概提了下MVC架构,State,Observer,Singleton在Cocos2dx和Unity中的应用
本书以诙谐的语言讲述了游戏设计的整个流程,包括剧情、设计文档、游戏策略、人物角色、玩法等内容, 100多张趣味盎然的卡通手绘图,不仅给读者带来视觉享受、阅读快感,还有助于理解游戏 设计的奥秘
通过本课程设计,应用所学的设计模式技术设计一个有趣味的宠物蛋培养小游戏来加深对设计模式的应用场景、使用动机和优缺点分析的理解程度,使用五种设计模式实现课程设计作业,包含安卓的完整代码和课程设计报告,...