终于有了间茅草棚

——我走时,会否有随风飘散的痕迹?

外面的风好大,雨也淅淅沥沥的。

世间种种的诱惑不惊不扰我清梦,山高路远不绝我追踪你绝美的笑容,登高一呼时才懂始终在为你心痛,俯首对花影摇动都是东风在捉弄

世间种种的迷惑都是因你而猜错,水光月光又交融描述这朗朗的夜空,生死到头的相从似狂花落叶般从容,当一切泯灭如梦就在远山被绝
随笔 - 40, 文章 - 2, 评论 - 257, 引用 - 3

导航

<2008年11月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

留言簿(11)

随笔档案

文章档案

收藏夹

其它的我

友情连接

网页连接

搜索

最新评论

  • 1. re: 关于质数(素数)的算法
  • 1121=19*59
  • --李圆欢
  • 2. re: void *几用
  • 方法都不错
  • --员工生日礼物
  • 3. re: void *几用
  • to oshj:
    最近才悟道这个用法,没想到你都用了很多了。

    to brent:
    不是为了玩才玩,这里每种用法在特定的情况下,都有他相应的好处。不过,我是做为自己记录的,指不定什么时候就忘记了,还可以这么用。
    1. 可以使得头文件简单,而且出于实现保密的需要,还是很有用处的。
    2. 很多时候对象本身应该简洁,但往往应对不同的需要,通常需要数据对应。举个例子,比如玩家在哪个房间,在哪个房间最好不要直接记在玩家身上,用数据注入的方式,能够很快的获得该信息。
    3. 因为是做为库暴露头文件的,使用者并不关心void *的实际意义,而且能够加快编译速度。真正要关心时,就Graphics.h这个头文件是不够的,通常会需要了解整底层个实现,才能较好的扩充。
  • --清风雨
  • 4. re: void *几用
  • 还在玩C++语言,你这玩法, 又不是用在导弹导航上...
    别人看不懂的代码,都不是好代码,分数为0

    int sub(any) { any; return TRUE;}
    (void)sub(any);

  • --brent
  • 5. re: void *几用
  • 个人用3 的情况比较多
  • --oshj
  • 6. re: 简要记录sizeof和内存对齐
  • 很清楚,受教了
  • --rdeam
  • 7. re: 局部变量
  • 我不用ATL,一般都是用标准c++支持的和平台API。
    crt里的wcs和mbs转换的函数,ms的实现是不完整的,在它的实现代码里有一段说明;而且还要设置local,比较烦琐。
  • --清风雨
  • 8. re: 简单字符串转换
  • win下,atl中有CT2CA, CW2CA等一系列转换类。
    crt中有wcstombs和mbstowcs
  • --局部变量
  • 9. re: 一个奇怪但可能有用的缓存
  • vc资料站:http://www.vcmsdn.com/     对学习很有帮助的,可以上去

    看看,或加群46138350,里面有高手可以请教的。
  • --maggie
  • 10. #progma整理
  • #pragma整理
  • --hi_wyl
  • 11. re: hpho
  • 缓冲在一等程度上是临时性的,而且实际上如果保持std::vector的iterator下次使用,也会有问题。

    所以,这个问题也就是使用时不允许这样用。
  • --清风雨
  • 12. re: 一个奇怪但可能有用的缓存
  • 如果有指针引用着arrange()所调整的那块内存,那就乱了.
  • --hpho
  • 13. re: 一个奇怪但可能有用的缓存
  • 用std::string不就行了?
  • --金庆
  • 14. re: ZiDing
  • 鉴于你的建议,前段时间我看了下boost的内存对象池,没有过于深入,
    判断下来属于做法类似,性能应该相当,甚至可能我这个略好一点。

    因为编写测试是一件相当麻烦,而且要求也很高的事,而要全面又很难。

    boost的代码我看起来比较难读,维护、调试起来对我来说是一个大麻烦。所以,我一般不选择boost。
  • --清风雨
  • 15. re: 简单内存对象池
  • 和boost的对比过没有?
  • --ZiDing

阅读排行榜

评论排行榜

前段时间在gameres上写的一篇文章

定时器的设计和实现

张家旺       2005-02-26

 

       开始想学习DX编程时,一个朋友介绍了这个网站。平时,在里面也学习了不少内容,自己经常听同事说起定时器。而自己第一次使用时,所设计的一个定时器,是问题多多。经过一些总结和思考,设计了一个新的定时器,拿出来和大家共享。也免了总是拿来,而不付出。}

       定时器,是一个应该来说游戏最基本常用的功能。它的易用与否,直接影响了开发的效率;功能的完备与否,直接导致实现的难易;性能的好坏,直接影响到了游戏的运行表现。那么,如何实现一个简单易用、功能完善、性能较好的定时器呢?

 

       首先,先看功能的完善。

 

       定时器,那么,第一点,我们希望他能有最基本的定时功能:指定一段时间以后,发生某个事件。

然后,如果所有事件都是一定时间以后发生,而,我们经常可能由于某个操作,会取消前面事件或无效前面的事件。比如:定时炸弹,一段时间以后会爆炸,在爆炸以前,是可以拆毁的。那么,就需要能取消或无效某个定时。

好,这就是一个最基本的定时器,能够设定时间,能够取消设定。就有如下接口:

setTime(int time,…                可能还不明确,改为:int timeEvent(int time,Event &e)

cancelTime(int timeID)          统一名字:                  void cancelEvent(int e)

       但是,往往,我们很多游戏希望能暂停,然后,从暂停点继续。

              void pauseTime()

              void resumeTime()

       怎么暂停,就有个游戏时间、系统时间(时间的获取,一般都是以系统时间为基础)了。

              unsigned playTime()

              unsigned sysTime()

       功能上就有了:定时、取消、暂停、继续、查询。作为一般的游戏开发已经相对比较充分了。

 

       再看,简单易用。

 

       我们在前面引入了一个事件的概念Event,这样一个类。如果按照前面的思路,那么,就需要在时间到了,发生时间。

       Event::onOcured()

       实际的使用中,发现自己处理自己发生了,不是一个好的方式,我们再通过一个中转:

       EventHandler::occurred(Event &e)

       使用时,每个事件都要有一个对象,而且是临时创建,还要销毁,并且要处理,必需继承EventHandler,使用相当不方便。需要最好不要继承,也不需要创建对象。

       设计模式里有个proxy,可以借鉴一下。我们改为从proxy去取发生了的事件。

       bool EventProxy::fetchEvent(Event &e)

       void EventProxy::addOccured(Evene &e)

       我们再使用时只需要fetch看有没有了,有、处理。进一步,取消也用proxy

       void EventProxy::cancelEvent(int e)

       干脆,更方便,易于理解,我们把所有的借口都放这个proxy里算了。不过,不能叫EventProxy了。

       int Timer:: timeEvent(int time,Event &e)

       void Timer::cancelEvent(int e)

       void Timer::pauseTime()

       void Timer::resumeTime()

       bool Timer::fetchEvent(Event &e)

       这样,所有操作都只需要通过Timer了。不过,为了防止多份事件,需要采用singleton(单件)模式。同时,把时间的获取也加进来。

typedef unsigned int  U32;

class TimeOffice

{

public:

     /**

      * 定时邮递

      * @return 邮递定时器

      * @para ms 间隔毫秒

      * @para receiver 接收对象

      * @para packet 邮递的包裹

      * @para count 邮递次数(< 0 每隔ms毫秒邮递一次包裹)

      */

     U32 timePost( U32 ms,const void *receiver,

         const Packet &packet,int count = 1 );

     /**

      * 取消邮递(取消指定的定时器)

      * @return 定时器存在否

      * @para timer 邮递定时器

      */

     bool cancelPost( U32 timer );

     /**

      * 取消邮递(取消发往指定接收对象的所有定时器)

      * @return 被取消的邮递定时器个数

      * @para receiver 接收者

      */

     U32 cancelPost( const void *receiver );

     /**

      * 邮递到了的包裹数

      * @return 已到达接收者但尚未取出的包裹的数目

      * @para receiver 包裹接收者

      */

     U32 arrivedPackets( const void *receiver );

     /**

      * 取邮递包裹

      * @return 有可取的包裹否

      * @para receiver 接收者

      * @para packet 取出的包裹

      */

     bool fetchPacket( const void *receiver,Packet &packet);

     /**

      * 丢弃接收者所有已邮递的包裹

      * @return 丢弃的包裹的数目

      * @para receiver 接收者

      */

     U32 discardPackets( const void *receiver );

 

     /**

      * 生成时间戳

      * @return 基于操作系统或游戏的时间戳

      * @para system 是否采用依赖操作系统的时间戳

      */

     static U32 stampTime( bool system = true );

     /**

      * 暂停游戏时间的流逝

      * @return 无

      */

     static void pause( void );

     /**

      * 启动被暂停的游戏时间的流逝

      * @return 无

      */

     static void resume( void );

 

     /**

      * 申请定时器实例

      * @return 定时器实例

      */

     static TimeOffice *getInstance( void );

     /**

      * 释放定时器

      * @return 无

      */

     static void release( void );

 

private:

     TimeOffice( void );

     ~TimeOffice( void );

 

     void step( void );

};

 

    

最后是性能。这个问题,是一个比较难以象前面泛泛而谈的了。

      

       我们学过《数据结构》。知道,空间和运算性能通常是互斥的。既要空间利用少,又要运算性能高,通常是比较困难的。幸好,我们这里的fetchtimediscard等基本都是列表操作。由于cancel可能从中间删除事件,那么我们可以选择std::list,舍弃std::vector了。具体的实现就看大家怎么写了。

      

通篇,没有什么内容,只是一个思考的过程,和最后的设计结果。如果对此定时器有什么疑问或讨论,或对文章字句不解者,或对文章描述很烦者,都可建议修改,敬请在论坛发表帖子。个人,会抽时间去论讨和大家一起讨论。比较遗憾的是,自己机器上没有UML工具,因此,也没有相关“协作图”可供大家图形感觉(实在太过粗浅,这里不敢擅用“理解”一词)。

如果本文能对大家以后的游戏开发学习或游戏实际开发有所帮助。个人将深感高兴,并抽空再和大家一起讨论一般的windows游戏基本流程改进。恳请宝贵意见于论坛,个人已准备好cn_zhangJW用户,接受大家的臭鸡蛋了。:}

posted on 2005-06-01 19:38 终于有了间茅草棚 阅读(723) 评论(0)  编辑 收藏

评论

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]