| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1089 人关注过本帖
标题:[AnyPlay游戏引擎代码] String模版,字符串操作的封装
只看楼主 加入收藏
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
结帖率:100%
收藏
 问题点数:0 回复次数:7 
[AnyPlay游戏引擎代码] String模版,字符串操作的封装
前言:
由于本人还是在校学生,不可能拥有一个成熟的游戏开发团队。单靠一人的力量开发游戏引擎,我有种力不从心的感觉。因此,我希望广大的网友——不论你水平如何,经验多少——都能够参与到AnyPlay游戏引擎的开发工作当中。我将陆续把游戏引擎的各个模块发布到https://bbs.bccn.net/中,希望大家共同探讨,共同进步,同时也希望让更多的人加入到开放源代码的行列!

说明:
AnyPlay是我从今年(2008年)9月开始着手的一款2D游戏引擎,目前有以下模块:

A:基本类型
1. String(字符串)
2. Color(颜色)
3. Vector(向量)
4. Rect, Quad(矩形、四边形)
5. Node(节点)

B:框架
1. Singleton(单件类,其子类对象在全局被访问,但是只能创建一个实体)
2. Application(应用程序基类,以后做游戏的游戏框架要继承这个类)
3. Event, EventSet(事件集,使用类内回调来反馈信息)
4. Logger(日志记录器,记录发出的事件并输出)

C:系统
1.渲染系统:RenderSystem 派生出 D3D9RenderSystem 和 OGLRenderSystem(尚未完成)。
2.文件系统:FileSystem 可访问磁盘上的文件和资源包(*.zip)里的文件。
3.音频系统:AudioSystem 使用开源的WMp3代码实现mp3文件以及内存中的音频流的播放。
4.输入系统:InputSystem 派生出的 APIInputSystem 通过调用WinAPI来获得鼠标、键盘的状态。
5.计时系统:Timer 使用 WinAPI “QueryPerformanceCounter” 来实现高精度计时。

D:管理器
1.RenderSystem(纹理管理器,作为渲染系统的同时也包含管理纹理的功能)
2.ImageManager(图片管理器,载入和释放图片)
3.SpriteManager(精灵动画管理器,载入和释放精灵动画)
4.SceneManager(场景管理器,管理场景内的精灵动画,并向其发出用户事件)

E:动画
1.Animation(动画基类,借鉴Adobe Flash的帧/层思想做的)
2.Image(单个图片,一个纹理内可能含有多个图片)
3.Sprite(精灵动画,派生于Animation,用来真正实现游戏动画的播放)

[bo]一个人的思维,难免会有Bug或不完善的地方,
如果你对以下代码有什么意见或建议,欢迎发帖回复,非常感谢!
我坚信,好代码是改出来的[/bo]


完整源代码下载:https://bbs.bccn.net/thread-238896-1-1.html

AnyPlay.h
/************************************************************************/
// 创建时间: 080906
// 最后确定: 081017

#ifndef _AnyPlay_h_
#define _AnyPlay_h_

#pragma warning (disable : 4786)

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <math.h>

// 求大小
#define APMax(a,b)        (((a) > (b)) ? (a) : (b))
#define APMin(a,b)        (((a) < (b)) ? (a) : (b))
// 安全释放指针, COM接口
#define SAFE_DELETE(p)    { if(p) { delete (p); (p) = NULL; } }
#define SAFE_RELEASE(p)    { if(p) { (p)->Release(); (p) = NULL; } }
// 修正像素坐标
#define PIXEL_ALIGNED(x)((float)((x) + ((x) >= 0.0f ? 0.5f : -0.5f)))
// 退出程序
#define QUIT_PROGRAM    { PostMessage(GetActiveWindow(), WM_CLOSE, 0, 0); }

typedef unsigned char    byte;
typedef unsigned long    dword;
typedef unsigned short    ushort;
typedef unsigned short    wchar;

#define NULL 0
// 迭代器是否在范围内
#define IN_RANGE(_iter, _lst) ((_iter) >= (_lst).begin() && (_iter) < (_lst).end())
// 向Logger发出记录事件消息
#define LOG(_s, _lv) { Logger::GetSingleton().LogEvent(_s, _lv); }

#endif



String.h
/************************************************************************/
// 创建时间: 081005
// 最后确定: 081017

#ifndef _String_h_
#define _String_h_

#include "AnyPlay.h"

//////////////////////////////////////////////////////////////////////////
// AnyPlay名称空间
namespace AnyPlay
{
    //////////////////////////////////////////////////////////////////////////
    // 字符串模版类
    // 之所以要写成一个模版, 是因为以后做游戏输入框可能会用到
    template<typename T> class StringT
    {
    public:
        StringT() { m_pTmpStr = NULL; m_bChanged = false; }
        StringT(const StringT<T>& str) { m_pTmpStr = NULL; SetString(str); }
        StringT(const T* str) { m_pTmpStr = NULL; SetString(str); }

        //////////////////////////////////////////////////////////////////////////
        // 析构函数, 释放分配的内存
        virtual ~StringT() { SAFE_DELETE(m_pTmpStr); }

        //////////////////////////////////////////////////////////////////////////
        // 清空字符列表
        virtual void Clear() { if(m_String.size()) { m_String.clear(); m_bChanged = true; } }

        //////////////////////////////////////////////////////////////////////////
        // 获得字符串长度
        virtual dword GetLength() const { return (dword)m_String.size(); }

        //////////////////////////////////////////////////////////////////////////
        // 设置StringT字符串
        virtual void SetString(const StringT<T>& str)
        {
            if(&str == this) return;    // 如果是自己则返回
            m_bChanged = true;
            Clear();
            dword slen = str.GetLength();
            for(dword i = 0; i < slen; i++)
                m_String.push_back(str.m_String[i]);
        }

        //////////////////////////////////////////////////////////////////////////
        // 设置字符串指针
        virtual bool SetString(const T* str)
        {
            if(str)
            {
                m_bChanged = true;
                Clear();
                dword i = 0;
                while(str[i] != 0)
                {
                    m_String.push_back(str[i]);
                    i++;
                }
                return true;
            }
            return false;
        }

        //////////////////////////////////////////////////////////////////////////
        // 寻找字符串
        virtual dword FindString(const StringT<T>& str, dword begin) const
        {
            dword localLen = GetLength();
            dword targetLen = str.GetLength();
            for(dword i = begin; i <= localLen - targetLen; i++)
            {
                for(dword j = 0; j < targetLen; j++)
                {
                    if(m_String[i + j] != str.m_String[j]) break;
                    else if(j == targetLen - 1) return i;
                }
            }
            return -1;
        }
        
        //////////////////////////////////////////////////////////////////////////
        // 逆向寻找字符串
        virtual dword InverseFindString(const StringT<T>& str, dword begin) const
        {
            dword localLen = GetLength();
            dword targetLen = str.GetLength();
            for(dword i = localLen - targetLen; i >= begin; i--)
            {
                for(dword j = 0; j < targetLen; j++)
                {
                    if(m_String[i + j] != str.m_String[j]) break;
                    else if(j == targetLen - 1) return i;
                }
            }
            return -1;
        }

        //////////////////////////////////////////////////////////////////////////
        // 从pos位置插入字符串
        virtual bool InsertString(const StringT<T>& str, dword pos)
        {
            if(IN_RANGE(m_String.begin() + pos, m_String) || (m_String.begin() + pos == m_String.end()))
            {
                m_bChanged = true;
                m_String.insert(m_String.begin() + pos, str.m_String.begin(), str.m_String.begin() + str.GetLength());
                return true;
            }
            return false;
        }

        //////////////////////////////////////////////////////////////////////////
        // 从begin开始删除长度为len的字符串
        virtual bool RemoveString(dword begin, dword len)
        {
            if( IN_RANGE(m_String.begin() + begin, m_String) &&
                IN_RANGE(m_String.begin() + begin + len - 1, m_String))
            {
                m_bChanged = true;
                m_String.erase(m_String.begin() + begin, m_String.begin() + begin + len);
                return true;
            }
            return false;
        }

        //////////////////////////////////////////////////////////////////////////
        // 获得字符串指针
        virtual T* GetBuffer() const
        {
            if(m_bChanged || !m_pTmpStr)
            {
                SAFE_DELETE(const_cast<T*>(m_pTmpStr));
                const_cast<T*>(m_pTmpStr) = new T[m_String.size() + 1];
                dword i = 0;
                while(m_String.begin() + i != m_String.end())
                {
                    m_pTmpStr[i] = m_String[i];
                    i++;
                }
                m_pTmpStr[i] = 0;    // 0结尾
                // 关闭已经改变的标记
                const_cast<StringT<T>*>(this)->m_bChanged = false;
            }
            return m_pTmpStr;
        }

        //////////////////////////////////////////////////////////////////////////
        // 字符串相加, 就是从尾部插入
        virtual StringT<T> operator + (const StringT<T>& str) const
        {
            StringT<T> strTmp = *this;
            strTmp.InsertString(str, strTmp.GetLength());
            return strTmp;
        }

        //////////////////////////////////////////////////////////////////////////
        // 自身的字符串相加
        virtual void operator += (const StringT<T>& str)
        {
            InsertString(str, GetLength());
        }

        //////////////////////////////////////////////////////////////////////////
        // 从尾部添加字符
        virtual StringT<T> operator + (const T ch) const
        {
            StringT<T> strTmp = *this;
            strTmp.m_bChanged = true;
            strTmp.m_String.push_back(ch);
            return strTmp;
        }

        //////////////////////////////////////////////////////////////////////////
        // 自身从尾部添加字符
        virtual void operator += (const T ch)
        {
            m_bChanged = true;
            m_String.push_back(ch);
        }

        //////////////////////////////////////////////////////////////////////////
        // 比较两字符串是否相等
        virtual bool operator == (const StringT<T>& str) const
        {
            if(&str == this) return true;
            dword slen = GetLength();
            if(slen == str.GetLength())
            {
                for(dword i = 0; i < slen; i++)
                {
                    if(str.m_String[i] != m_String[i]) return false;
                }
                return true;
            }
            return false;
        }

        //////////////////////////////////////////////////////////////////////////
        // 取字符串中间从start开始, 长度为len的字符
        virtual StringT<T> Mid(dword start, dword len) const
        {
            StringT<T> strTmp;
            strTmp.m_bChanged = true;
            for(dword i = 0; i < len; i++)
            {
                if(IN_RANGE(m_String.begin() + i + start, m_String))
                    strTmp.m_String.push_back(m_String[i + start]);
                else break;
            }
            return strTmp;
        }

        //////////////////////////////////////////////////////////////////////////
        // 取字符串左边len个字符
        virtual StringT<T> Left(dword len) const
        {
            StringT<T> strTmp;
            strTmp.m_bChanged = true;
            for(dword i = 0; i < len; i++)
            {
                if(IN_RANGE(m_String.begin() + i, m_String))
                    strTmp.m_String.push_back(m_String[i]);
                else break;
            }
            return strTmp;
        }

        // 取字符串右边len个字符
        virtual StringT<T> Right(dword len) const
        {
            StringT<T> strTmp;
            strTmp.m_bChanged = true;
            dword localLen = GetLength();
            for(dword i = 0; i < len; i++)
            {
                if(i >= localLen) break;
                strTmp.m_String.insert(strTmp.m_String.begin(), m_String[localLen - i - 1]);
            }
            return strTmp;
        }

        //////////////////////////////////////////////////////////////////////////
        // 不相等判断
        virtual bool        operator != (const StringT<T>& str) const { return !(*this == str); }

        //////////////////////////////////////////////////////////////////////////
        // 赋值字符串指针
        virtual StringT<T>& operator = (const T* str) { SetString(str); return *this; }

        //////////////////////////////////////////////////////////////////////////
        // 赋值StringT
        virtual StringT<T>& operator = (const StringT<T>& str) { SetString(str); return *this; }

        //////////////////////////////////////////////////////////////////////////
        // 获得字符串指针
        virtual T*            operator () () const { return GetBuffer(); }

        //////////////////////////////////////////////////////////////////////////
        // 快速比较
        struct FastLessCompare
        {
            bool operator () (const StringT<T>& a, const StringT<T>& b) const
            {
                const dword la = a.GetLength();
                const dword lb = b.GetLength();
                if(la == lb)
                    return (memcmp(a(), b(), la * sizeof(T)) < 0);
                return (la < lb);
            }
        };

    protected:
        std::vector<T>    m_String;    // 字符列表
        T*                m_pTmpStr;    // 字符串指针
        bool            m_bChanged;    // 字符串是否已被改变
    };

    typedef StringT<TCHAR> String;    // TCHAR型字符串(常用)
}

#endif


[[it] 本帖最后由 flyue 于 2008-10-17 20:05 编辑 [/it]]
搜索更多相关主题的帖子: String 模版 AnyPlay 引擎 字符 
2008-10-17 18:54
中学者
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:20
帖 子:3554
专家分:80
注 册:2007-9-14
收藏
得分:0 
来支持一下我的小朋友....可惜我不搞游戏

樱花大战,  有爱.
2008-10-17 19:09
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
收藏
得分:0 
即使你不搞游戏,看过我的代码之后,总会发现我的不足之处吧??

天之道,损有余而补不足.人之道则不然,损不足以奉有余.孰能有余以奉天下,唯有道者.
2008-10-17 19:15
中学者
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:20
帖 子:3554
专家分:80
注 册:2007-9-14
收藏
得分:0 
最近发现自己的C++越来越差了.....是不是没用的缘故-,-

樱花大战,  有爱.
2008-10-17 19:17
goku_1
Rank: 1
等 级:新手上路
帖 子:2
专家分:0
注 册:2008-10-17
收藏
得分:0 
嘿嘿
好厉害, 来支持下!
2008-10-17 19:25
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
收藏
得分:0 
其实我最希望的,是大家可以指出我的不足之处……

天之道,损有余而补不足.人之道则不然,损不足以奉有余.孰能有余以奉天下,唯有道者.
2008-10-17 19:29
中学者
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:20
帖 子:3554
专家分:80
注 册:2007-9-14
收藏
得分:0 
回复 6# flyue 的帖子
我跑题了.....

樱花大战,  有爱.
2008-10-17 19:30
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
收藏
得分:0 
比如,InsertString如果自己把自己插入,会怎样?
如:
String str;
str.InsertString(str);
我怀疑,会死循环…………

天之道,损有余而补不足.人之道则不然,损不足以奉有余.孰能有余以奉天下,唯有道者.
2008-10-17 19:37
快速回复:[AnyPlay游戏引擎代码] String模版,字符串操作的封装
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.062866 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved