Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3427565
  • 博文数量: 864
  • 博客积分: 14125
  • 博客等级: 上将
  • 技术积分: 10634
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-27 16:53
个人简介

https://github.com/zytc2009/BigTeam_learning

文章分类

全部博文(864)

文章存档

2023年(1)

2021年(1)

2019年(3)

2018年(1)

2017年(10)

2015年(3)

2014年(8)

2013年(3)

2012年(69)

2011年(103)

2010年(357)

2009年(283)

2008年(22)

分类: C/C++

2010-12-27 09:34:08


1.1:整理两种SDL_Surface的关系。

        前面一直在用面向过程的思想写程序,因为OOP细分到每一个具体的方法,还是过程。OOP的难点其实在于理清楚不同类之间的关系。说实话,我只是为了自己 的理想,为了实现我计划的项目,刚刚开始学习C++的菜鸟。两个多月的C++能有什么水平,希望前辈们不要见笑,我会继续努力的。而且,可能因为对于 C++的偏爱,再加上我目前能找到的SDL相关教程都是C风格的,所以我充满了用C++来写SDL教程挑战的热情。
        SDL_Surface是SDL的一个结构。在我们前面的知识中,学习了构建这个结构的两种方法:一种是通过SDL_SetVideoMode();一种 是SDL_LoadBMP()。其实,通过SDL_SetVideoMode()构建的SDL_Surface是一种特殊的surface,因为,实际 上,其他的surface都是通过blit到这个surface上,最终通过flip这个surface,才能显示出来。所以,这个surface可以看 成是SDL库中,数据形式的surface(储存在电脑中)与实体形式的surface(通过屏幕显示出来)的唯一接口。另外,因为构建这两种 surface需要的数据成员小同大异,类方法也不尽相同。所以,虽然我也考虑过建立一个基类把两种surface作为派生类,但是我最终选择了建立两个 类。

1.2:构建SDL screen surface类。
class ScreenSurface
{
private:
    
static int screenNum;
    
int width;
    
int height;
    
int bpp;
    Uint32 flags;
    SDL_Surface
* pScreen;
public:
    ScreenSurface();
    ScreenSurface(
int w, int h, int b = 0, Uint32 f = 0);
    
~ScreenSurface();
    SDL_Surface
* point() const;
    
bool flip() const;
};
        我先设定了一个静态int作为计数器。我的考虑是,screen surface实际上只需要建立一个。并且,其他的surface实际上都是“依赖”于这个surface才能显示出来的。在SDL中,多次 SDL_SetVideoMode()的效果实际上是保留了最后一次的surface作为了screen surface,所以,多次SDL_SetVideoMode()其实是没有实际意义的。计数器screenNum用于保证只创建一次screen surface,多次创建我倾向让程序抛出异常。
        构建函数除了调用SDL_SetVideoMode()函数,还作为SDL_Init()的启动载入。所以,我专门定义析构函数的目的,是因为C++会在 类对象消亡的时候自动调用析构函数。因为保证了只建立一个screen surface,并且在创建对象的时候载入了SDL_Init(),所以,如果析构函数中使用SDL_Quit(),则可以在手动调用析构函数或者程序结 束的时候调用SDL_Quit()了。
        方法point()返回对象中的pScreen,其实就是SDL_Surface结构的指针。因为SDL库是C风格的,所以,直接使用指针的函数很多。
        方法flip()用于把screen surface最终显示出来。

1.3:screen surface的类方法。
int ScreenSurface::screenNum = 0;
首先为静态变量附初值。
ScreenSurface::ScreenSurface():
width(
640), height(480), bpp(32), flags(0)
{
    
if ( screenNum > 0 )
        
throw "DONOT create more than ONE screen!";
    
if ( SDL_Init(SDL_INIT_VIDEO < 0 ) )
        
throw SDL_GetError();
    pScreen 
= SDL_SetVideoMode(width, height, bpp, flags);
    screenNum
++;
}

ScreenSurface::ScreenSurface(
int w, int h, int b, Uint32 f):
width(w), height(h), bpp(b), flags(f)
{
    
if ( screenNum > 0 )
        
throw "DONOT create more than ONE screen!";
    
if ( SDL_Init(SDL_INIT_VIDEO < 0 ) )
        
throw SDL_GetError();
    pScreen 
= SDL_SetVideoMode(width, height, bpp, flags);
    screenNum
++;
}
构造函数。如果创建1个以上的screen surface,则会抛出异常。
ScreenSurface::~ScreenSurface()
{
    SDL_Quit();
}
析构函数。在对象消亡时,退出SDL系统。
SDL_Surface* ScreenSurface::point() const
{
    
return pScreen;
}
返回screen surface中SDL_Surface结构的指针,主要提供给SDL的函数调用。
bool ScreenSurface::flip() const
{
    
if ( SDL_Flip(pScreen) < 0 )
        
return false;
    
else return true;
}
显示(弹出flip)screen surface到屏幕上。
2.1:构建普通的surface类。

        在所有的surface里面,只有screen surface是最特殊的。因为第一,screen surface只有一个;第二,其他所有的普通surface都必须被blit到screen surface上,通过flip screen surface才能显示出来。所以,我们可以认为普通的surface是“依赖”于一个screen surface的。所以,考虑在构建surface的时候,除了需要装载的bmp文件,还需要指定其所依赖的screen surface。
class DisplaySurface
{
private:
    
string fileName;
    SDL_Surface
* pSurface;
    SDL_Surface
* pScreen;
public:
    DisplaySurface(
string file_name, const ScreenSurface& screen);
    
~DisplaySurface();
    SDL_Surface
* point() const;
    
bool blit() const;
};

2.2:surface的类方法。
DisplaySurface::DisplaySurface(std::string file_name, const ScreenSurface& screen):
fileName(file_name)
{
    pSurface 
= SDL_LoadBMP(file_name.c_str());
    
if ( pSurface == 0 )
        
throw SDL_GetError();
    pScreen 
= screen.point();
}
构造函数。我们指定一个bmp文件,和一个screen surface对象来构造surface。注意,这里我们用到了C++的string。我们前面说过,string的方法c_str()用于把C++的 string对象转化为C风格字符串,而这正是SDL的函数所需要的。
DisplaySurface::~DisplaySurface()
{
    SDL_FreeSurface(pSurface);
}
虽然load的bmp可以在SDL_Quit()的时候自动释放,不过也许我们也会有需要手动释放的时候。比如,装载一张图片,进行某种处理和转换后,保留处理后的,就可以把原来用于处理的对象释放掉了。
SDL_Surface* DisplaySurface::point() const
{
    
return pSurface;
}
返回对象中,bmp的SDL_Surface指针。同样为了用于SDL库的函数。
bool DisplaySurface::blit() const
{
    
if ( SDL_BlitSurface(pSurface, 0, pScreen, 0< 0 )
        
return false;
    
else return true;
}
把surface blit到screen surface上面,左上角重合。到这里,我们前面用到的对于surface的所有操作,都包含到类方法中了。

阅读(1080) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~