游戏开发论坛

 找回密码
 立即注册
搜索
查看: 916|回复: 1

游戏制作心得(一)

[复制链接]

2

主题

3

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2004-12-10 14:09:00 | 显示全部楼层 |阅读模式
  谈了很多关于网络游戏的一些技术技巧和框架,但都是零散的,这有好处,但大多数新手或是爱好者都不知道该如何下手,下面谈谈我的游戏开发心得

  游戏开发一般使用VC+DX,你可以使用Win32 API直接创建一个Windows应用程序框架,也可以使用MFC来创建一个Windows应用程序框架,注意,并不是像很多人想象的那样,用了MFC就觉得很慢,其实我们只是用MFC搭建了一个应用程序框架,而且MFC有很多很好用的类库,这些类库可以提高我们开发的效率,但并不影响我们的图形渲染和数据处理,因为在图形渲染和数据处理部分我们很少能用得上MFC,不会影响执行效率。

  当然,不用MFC也可以,直接使用Win32 API 也并不是需要花很多时间。可以根据个人需求进行选择。

大多数人都知道游戏的基本结构

Game_Init( );

while ( )
{
    if ( )
    {
    }
    else
    {
        Update( );
        Render( );
    }
}

Game_Destroy( );

我先说简单的 Update( )和Render( ) 函数

  一般说来不同的数据更新在自己不同的事件中处理,但有很多是带状态的数据,比如:IDirectInput的状态机,需要在一定的时间来处理这些数据,那么我们可以在Update函数里来处理。我们还可以模拟一些自定义的事件消息,比如自定义的UI,或者脚本。

Update( )
{
   while ( Events_Count > 0 )
   {
       Do_Events( );
   }
}

关于渲染函数很简单了,很多游戏资料都介绍了如何渲染,但渲染什么我稍后再说

Render ( )
{
    Begin_Render( );

    // 场景,角色,UI等等

    ...

    End_Render( );
}

下面说渲染内容,渲染内容都是预先准备好的。

我们一般有2种方式组织数据,一种我称之为集合式,一种我称之为派生式。
1、集合式
所有的对象都有2个类
class CObj
{
    // 对象的方法属性
};

typedef CObj* ObjPtr;


class CCObj
{
protected:

    map<ObjKey, ObjPtr> m_lstObjs;     // 对象清单

public:

    CCObj( );
    ~CCObj( )
    {
        clear( );
    }  
  
public:
   
    static CCObj * GetInst( );

public:

  LoadFromConfigFile( char * szFile );  // 从配置文件中批量读取对象

    ObjPtr New( );                         // 直接新建对象
    bool Add( ObjPtr p );                  // 增加新对象
    bool Remove( ObjKey );                 // 移除对象
    ObjPtr Find( );                        // 检索对象

    void clear( )                          // 全部清空
    {
        map<ObjKey, ObjPtr>::iterator it = m_lstObjs.begin( );
        for ( ; it != m_lstObjs.end( ); ++it )
        {
            ObjPtr p = (*it);
            if ( p )
            {
                delete p;
                p = NULL;
            }
        }

        m_lstObjs.clear( );         
    }
};

要特别注意的是那个集合的析构函数,另外还有一个函数就是GetInst( ),它是静态的,用来访问这个类,其实也就是说这个集合类是个全局性的实例,用来管理整个游戏中所用的该对象。那么我们在CPP文件里需要这样定义:

#include "Obj.h"

CCObj g_CCObj;

CCObj * CCObj::GetInst( )
{
   return &g_CCObj;
}

这样,关于Obj的数据我们就处理好了,用的时候是随需申请,集中释放,比如:

#include "Obj.h"

{
   ...
   
   ObjPtr pNewObj = new CObj;
   CCObj::GetInst( )->Add( pNewObj );

   ...
}

我们不需要去调用delete pNewObj来释放该对象,因为当程序退出的时候,集合CCObj会把所有申请的对象全部集中释放,不用担心内存问题,用的时候只管用就好了。

上面的是集合式管理


2、派生式管理
派生式管理就是我们定义一个基类
class CObjBase
{
public:

   typedef CObjBase * CObjBasePtr;

private:

   map<ObjKey, CObjBasePtr> m_lstObjs;     // 对象清单
  
public:
   
   bool AddSubObj( CObjBase * pChild )
   {
       m_lstObjs.insert( map<ObjKey, CObjBasePtr>::value_type( pChild->m_Key, pChild );
       return true;
   }

   CObjBase( CObjBase * pBase )
   {
       if ( pBase )
       {
           pBase->AddObj( this );
       }
   }

   ~CObjBase( )
   {
        map<ObjKey, CObjBasePtr>::iterator it = m_lstObjs.begin( );
        for ( ; it != m_lstObjs.end( ); ++it )
        {
            CObjBasePtr p = (*it);
            if ( p )
            {
                delete p;
                p = NULL;
            }
        }

        m_lstObjs.clear( );        
   }

};

这就像一棵大树,每个节点下面有几个子类,释放的时候一级一级的释放,主要是根节点需要手工释放,用的时候比较方便,但释放时其实是递归调用,所以一般用于休闲小游戏,用法如下:

CObjBase * pRoot = new pRoot( NULL );

new CObjBase( pRoot );
new CObjBase( pRoot );
...
new CObjBase( pRoot );

delete pRoot;

上面new的时候甚至不用返回值,我们只需要释放掉pRoot就可以了。所有其他的类都可以从这个基类派生,比如:

class CObj1 : public CObjBase
{
};

class CObj2 : public CObj1
{
};

用的时候

p1 = new CObj1( pRoot );
new CObj2( pRoot );
p2 = new CObj2( p1 );
new CObj2( p2 );

还是很方便的。

今天就讲这么多了,下次再聊

                  转:chaosstars

http://bbs.chaosstars.com/dispbbs.asp?boardid=61&id=232

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
发表于 2004-12-10 14:18:00 | 显示全部楼层

Re:游戏制作心得(一)

我倒,把我的联接弄没了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-12-23 16:13

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表