游戏开发论坛

 找回密码
 立即注册
搜索
查看: 10269|回复: 11

我的游戏开发总结[3]

[复制链接]

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
发表于 2005-6-30 12:29:00 | 显示全部楼层 |阅读模式
这个版本,键盘输入处理加上去了

并且增加了对avi等视频文件播放的处理

sf_200563012294.rar

607.95 KB, 下载次数:

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-6-30 13:21:00 | 显示全部楼层

Re:我的游戏开发总结[3]



这里比较完整系统的介绍一下我的图形模块部分,网络部分已经有介绍了,也有例子

1、游戏的框架

游戏调用gc_init初始化,调用gc_destory释放内存,下面的代码是标准调用

    // 这里进行系统初始化,返回一个根对象
    LPOBJ pRoot = gc_init( hInstance, hwndMain, true );       
       
    ShowWindow(hwndMain, nCmdShow);
    UpdateWindow(hwndMain);

    while ( msg.message != WM_QUIT )
    {
        if ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }        
        else
        {
            gc_update( ); // 这里是用来处理渲染和输入的函数
        }
    }

    gc_destory( );

要注意的是gc_init会返回一个根对象,所有的渲染对象都有一个父对象,最终的父对象就是这个根,也就是说在我的图形模块里,游戏渲染对象是用树来组织的。



2、资源文件


我对每个资源文件进行命名,函数有两个

// 从文件中生成一个名为sName的图像资源
int GC_API gc_img_file( LPCSTR sName, LPCSTR sFile, int x, int y, int w, int h, DWORD dwColor );

// 从内存中生成一个名为sName的图像资源
int GC_API gc_img_memory( LPCSTR sName, BYTE * imgBuf, int nSize, int x, int y, int w, int h, DWORD dwColor );

参数sName是给资源文件取的名字,比如“背景图片”,“地图资源2001”等都可以,只要保证不同的资源取不同的名字即可,否则,如果取相同的名字就是用后一个文件Update前一个。

参数x, y, w, h分别是图片坐上角坐标和大小,因为有时候我们可能只想读取图片文件的一部分,如果读取整个图片文件又不知道大小,w, h参数给0就可以了,dwColor是需要过滤的颜色,如果不需要过滤,dwColor=0x0,注意这是带alhpa的过滤,如果是过滤黑色,dwColor=0xFF000000

之所以有2个函数,第二个函数是从内存中的图片缓冲中生成资源,因为有时候我们需要给图片加密,不能直接从文件中读取,可以先在内存中解密,然后直接调用gc_img_memory函数,要注意的是,这里从内存中生成资源不是支持自定义的图片格式,内存中的数据也必须是通用的图片文件格式。


3、渲染对象
图形部分最重要的是对资源文件和渲染对象的组织,那么渲染对象怎么来实现呢。

对于众多的游戏对象,比如:地图,精灵,NPC,角色,界面UI中的按钮等等,可能不同的游戏不一样,有2D的,3D的,这个没有关系,这些对象最终是一个渲染对象,最终是要送到渲染队列中去的。

我们只要获得这些对象实例的指针,调用一个渲染函数来挨个渲染他就可以了

因此,我定义了一个基类cls_obj,这个基类是一个虚基类,不能直接实例化的。我们在使用这个类的时候必须先进行派生,实现我们自己的功能,当然,也可以不用派生,我已经实现了一个派生类cls_obj_imp,可以直接new一个cls_obj_imp。

而且,由于我的框架需要自己来管理这些渲染对象的指针,那么不能让外部来删除这些对象,因为如果外部删除了,我的渲染队列不知道,还在继续引用该对象的指针就会出错,而且有时候,我们也容易用完了不释放,那么没关系,这一切我来帮你做,只要在派生cls_obj的时候,加上宏IMP_DELETE就万事OK了,至于原因,我前面的论述中已经说明了。那么我们如果要删除渲染对象怎么办呢,调用delete是不行的了,只能调用Destory函数。

下面是一个简单的派生类

class cls_obj_imp : public cls_obj
{
    MP_DELETE
public:
    cls_obj_imp( cls_obj * pFather ) : cls_obj( pFather ) { }
};

上面说过,我们的每个对象都是有父对象的,在构造的时候就必须指定父对象,我们的根对象就是通过gc_init返回的。

4、实现
渲染对象有了,比如我们要实现一个按钮(我的例子中有代码)

class CMButton : cls_obj
{
    CTSS        m_sMethod;
    LPOBJ       m_pCaller;
    CAGV        m_agvClick;

    IMP_DELETE
public:

    CMButton( cls_obj * pFather, LPCSTR sBtName, int x, int y, int w, int h ) : cls_obj( pFather )
    {
        SetRect( x, y, w, h );

        // 这里是按钮的图片,刚才说了,我们对每个图片资源都取了名字的
        // sBtName就是图片资源的名字
        // 后面的3,1是表示这个图片是3列1行,每行每列的大小是w,h,这样一共有3帧
        SetImage( sBtName, 0, 0, w, h, 3, 1 );
        // 默认就是第1帧图片,索引是0

    }

    // 这个函数就是用来设置按钮Click事件调用的参数
    void SetClick( LPOBJ pCaller, LPCSTR sMethod, CAGV& agvClick )
    {
        m_sMethod = sMethod;
        m_pCaller = pCaller;
        m_agvClick = agvClick;
    }

    virtual void OnLBDown( int nFlag, int x, int y )            // 左键按下
    {
        // 鼠标按下去的时候显示第3帧的图片
        SetFrame( 2 );
    }
    virtual void OnLBUp( int nFlag, int x, int y )            // 左键弹起
    {
        // 鼠标弹起也就是按钮Click事件,那么我们要处理这个Click事件
        // m_pCaller是处理事件的对象,m_sMethod是该对象的方法名称,m_agvClick是方法的参数
        if ( m_pCaller && !m_sMethod.is_empty( ) )
            m_pCaller->Call( m_sMethod, m_agvClick );

        // 鼠标弹起的时候显示第2帧的图片
        SetFrame( 1 );
    }
    virtual void OnMouseOver( int nFlag, int x, int y )        // 鼠标移动
    {
        // 鼠标移过按钮的时候显示第2帧的图片
        SetFrame( 1 );
    }
    virtual void OnMouseLeave( int nFlag )                    // 鼠标离开
    {
        // 鼠标离开按钮的时候显示第1帧的图片
        SetFrame( 0 );
    }
};


这样一个按钮就做好了,用的时候

    gc_img_file( "按钮0001", "rc/btn.png", 0, 0, 0, 0, 0xFF00FF00 ); // 绿色ColorKey
    CMButton * pBtn = new CMButton( this, "按钮0001", 360, 320, 58, 22 );

    IMP_METHOD(OnBtnClick); // 注册一个方法
    pBtn->SetClick( this, "OnBtnClick", agv );



89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-6-30 13:54:00 | 显示全部楼层

Re:我的游戏开发总结[3]

注意:不支持gif格式

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-6-30 19:18:00 | 显示全部楼层

Re:我的游戏开发总结[3]

关于d3dx9_26.dll动态库

和D3DX相关的一些函数,引用了d3dx9_26.dll动态库,该函数在dxdiag上并没有注册,d3dx9_26是微软最新版本的June 2005所包含,Apri 2005所包含的是d3dx9_25。

我所写的程序需要在最新的版本下运行

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
 楼主| 发表于 2005-6-30 19:28:00 | 显示全部楼层

Re:我的游戏开发总结[3]

我生成了1024个cls_obj渲染对象,Debug的时候,FPS=17,而当Release的时候,FPS=60(我的笔记本刷新频率为60,D3D默认是垂直同步的)。

可能是Debug下,微软在处理渲染时,生成了大量的调试

3

主题

8

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2005-7-7 11:32:00 | 显示全部楼层

Re:我的游戏开发总结[3]

我 想问问 你的压缩包 到底想演示什么  难道还要让我编译一次

139

主题

2005

帖子

2057

积分

金牌会员

Rank: 6Rank: 6

积分
2057
QQ
发表于 2005-7-7 18:21:00 | 显示全部楼层

Re:我的游戏开发总结[3]

比OGRE还...

0

主题

48

帖子

48

积分

注册会员

Rank: 2

积分
48
发表于 2005-7-8 14:00:00 | 显示全部楼层

Re:我的游戏开发总结[3]

恩,严重是这样的。

0

主题

2

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2005-7-11 21:36:00 | 显示全部楼层

Re:我的游戏开发总结[3]

看了你的头文件,那么小,不知能够开发出什么游戏来。你知道,如果采用接口继承是无需源文件的,例如COM,但采用实现继承的经常要读源文件才知道如何继承法。例如MFC和BORLAND C++的库。

3

主题

68

帖子

68

积分

注册会员

Rank: 2

积分
68
发表于 2005-7-15 16:29:00 | 显示全部楼层

Re:我的游戏开发总结[3]

代码好混乱,好几中命名风格
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-21 03:45

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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