SDL入门教程(五):6、对C++异常机制的思考,代码重写

[复制链接]

该用户从未签到

2380

主题

2433

帖子

9139

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
9139
QQ
跳转到指定楼层
楼主
发表于 2017-12-19 09:51:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
6.1:用bool作为命令是不是画蛇添足了?

        不知道为什么,我总觉得总是用if结构来调用命令让人读起程序来很不连贯。所以,我决定重新修改下,并且异常抛出改为使用类对象,这样是不是更C++一点呢?

6.2:修改后的代码。
//FileName: SurfaceClass.h

#ifndef SURFACE_CLASS_H
#define SURFACE_CLASS_H

#include
<iostream>
#include
<string>
#include
"SDL/SDL.h"

using std::string;

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;
   
void flip() const;
};

class DisplaySurface
{
private:
   
string fileName;
    SDL_Surface
* pSurface;
    SDL_Surface
* pScreen;
public:
    DisplaySurface(
string file_name, const ScreenSurface& screen);
   
~DisplaySurface();
    SDL_Surface
* point() const;
   
void blit() const;
   
void blit(int at_x, int at_y) const;
   
void blit(int at_x, int at_y,
               
int from_x, int from_y, int w, int h,
               
int delta_x = 2, int delta_y = 2) const;
   
void blitToSurface(const DisplaySurface& dst_surface,
                        
int at_x = 0, int at_y = 0) const;
   
void blitToSurface(const DisplaySurface& dst_surface,
                        
int at_x, int at_y,
                        
int from_x, int from_y, int w, int h,
                        
int delta_x = 2, int delta_y = 2) const;
};

class ErrorInfo
{
private:
   
string info;
public:
    ErrorInfo():info(
"Unknown ERROR!")
    {}
    ErrorInfo(
const char* c_str)
    {
        info
= string(c_str);
    }
    ErrorInfo(
const string& str):info(str)
    {}
   
void show() const
    {
        std::cerr
<< info << std::endl;
    }
};

#endif


#include "SurfaceClass.h"

//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
//class ScreenSurface

int ScreenSurface::screenNum = 0;

ScreenSurface::ScreenSurface():
width(
640), height(480), bpp(32), flags(0)
{
   
if ( screenNum > 0 )
        
throw ErrorInfo("DONOT create more than ONE screen!");
   
if ( SDL_Init(SDL_INIT_VIDEO < 0 ) )
        
throw ErrorInfo(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 ErrorInfo("DONOT create more than ONE screen!");
   
if ( SDL_Init(SDL_INIT_VIDEO < 0 ) )
        
throw ErrorInfo(SDL_GetError());
    pScreen
= SDL_SetVideoMode(width, height, bpp, flags);
    screenNum
++;
}

ScreenSurface::
~ScreenSurface()
{
    SDL_Quit();
}

SDL_Surface
* ScreenSurface::point() const
{
   
return pScreen;
}

void ScreenSurface::flip() const
{
   
if ( SDL_Flip(pScreen) < 0 )
        
throw ErrorInfo(SDL_GetError());
}

//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
//class DisplaySurface

DisplaySurface:isplaySurface(std::
string file_name, const ScreenSurface& screen):
fileName(file_name)
{
    pSurface
= SDL_LoadBMP(file_name.c_str());
   
if ( pSurface == 0 )
        
throw ErrorInfo(SDL_GetError());
    pScreen
= screen.point();
}

DisplaySurface::
~DisplaySurface()
{
    SDL_FreeSurface(pSurface);
}

SDL_Surface
* DisplaySurface::point() const
{
   
return pSurface;
}

void DisplaySurface::blit() const
{
   
if ( SDL_BlitSurface(pSurface, 0, pScreen, 0) < 0 )
        
throw ErrorInfo(SDL_GetError());
}


void DisplaySurface::blit(int at_x, int at_y) const
{
    SDL_Rect offset;
    offset.x
= at_x;
    offset.y
= at_y;

   
if ( SDL_BlitSurface(pSurface, 0, pScreen, &offset) < 0 )
        
throw ErrorInfo(SDL_GetError());
}

void DisplaySurface::blit(int at_x, int at_y,
                          
int from_x, int from_y, int w, int h,
                          
int delta_x, int delta_y) const
{
    SDL_Rect offset;
    offset.x
= at_x - delta_x;
    offset.y
= at_y - delta_y;

    SDL_Rect dest;
    dest.x
= from_x - delta_x;
    dest.y
= from_y - delta_y;
    dest.w
= w + delta_x*2;
    dest.h
= h + delta_y*2;

   
if ( SDL_BlitSurface(pSurface, &dest, pScreen, &offset) < 0 )
        
throw ErrorInfo(SDL_GetError());
}

void DisplaySurface::blitToSurface(const DisplaySurface& dst_surface, int at_x, int at_y) const
{
    SDL_Rect offset;
    offset.x
= at_x;
    offset.y
= at_y;

   
if ( &dst_surface == this )
        
throw ErrorInfo("Cannot blit surface to itself!");

   
if ( SDL_BlitSurface(pSurface, 0, dst_surface.point(), &offset) < 0 )
        
throw ErrorInfo(SDL_GetError());
}

void DisplaySurface::blitToSurface(const DisplaySurface& dst_surface,
                                    
int at_x, int at_y,
                                    
int from_x, int from_y, int w, int h,
                                    
int delta_x, int delta_y) const
{
    SDL_Rect offset;
    offset.x
= at_x - delta_x;
    offset.y
= at_y - delta_y;

    SDL_Rect dest;
    dest.x
= from_x - delta_x;
    dest.y
= from_y - delta_y;
    dest.w
= w + delta_x*2;
    dest.h
= h + delta_y*2;

   
if ( &dst_surface == this )
        
throw ErrorInfo("Cannot blit surface to itself!");

   
if ( SDL_BlitSurface(pSurface, &dest, dst_surface.point(), &offset) < 0 )
        
throw ErrorInfo(SDL_GetError());
}

//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


#include "SurfaceClass.h"

int game(int argc, char* argv[]);
int main(int argc ,char* argv[])
{
   
int mainRtn = 0;
   
try {
        mainRtn
= game(argc, argv);
    }
   
catch ( const ErrorInfo& info ) {
        info.show();
        
return -1;
    }
   
   
return mainRtn;
}

int game(int argc ,char* argv[])
{
   
//Create a SDL screen.
    const int SCREEN_WIDTH = 640;
   
const int SCREEN_HEIGHT = 480;
    ScreenSurface screen(SCREEN_WIDTH, SCREEN_HEIGHT);

   
//Create 2 SDL surface for the screen that just created.
    DisplaySurface backGround("bg.bmp", screen);
    DisplaySurface frontImage(
"image.bmp", screen);
   
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
   
//way2: If use blitToSurface, must get a copy of backGround.
/*

    DisplaySurface backGroundCopy("bg.bmp", screen);
*/
   
//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

   
//Blit backGround surface to screen and flip the screen.
    backGround.blit();
    screen.flip();

   
//variable for main loop.
   
//key event for up, down, left and right.
    Uint8* keys;
   
//moving image's coordinate.
    int xpos = 0;
   
int ypos = 0;
   
//moving image's size.
    const int IMG_WIDTH = 128;
   
const int IMG_HEIGHT = 128;
   
//main loop.
    bool gameOver = false;
   
while( gameOver == false ){
        
//press ESC or click X to quit.
        SDL_Event gameEvent;
        
while ( SDL_PollEvent(&gameEvent) != 0 ){
            
if ( gameEvent.type == SDL_QUIT ){
                gameOver
= true;
            }
            
if ( gameEvent.type == SDL_KEYUP ){
               
if ( gameEvent.key.keysym.sym == SDLK_ESCAPE ){
                    gameOver
= true;
                }
            }
        }
        
//key event to move image.
        keys = SDL_GetKeyState(0);
        
if ( keys[SDLK_UP] || keys[SDLK_w] ){
            ypos
-= 1;
        }
        
if ( keys[SDLK_DOWN]|| keys[SDLK_s] ){
            ypos
+= 1;
        }
        
if ( keys[SDLK_LEFT]|| keys[SDLK_a] ){
            xpos
-= 1;
        }
        
if ( keys[SDLK_RIGHT]|| keys[SDLK_d] ){
            xpos
+= 1;
        }

        
//Hold moving image on the backGround area.
        if ( xpos <= 0 )
            xpos
= 0;
        
if ( xpos >= SCREEN_WIDTH - IMG_WIDTH )
            xpos
= SCREEN_WIDTH - IMG_WIDTH;
        
if ( ypos <= 0 )
            ypos
= 0;
        
if ( ypos >= SCREEN_HEIGHT - IMG_HEIGHT )
            ypos
= SCREEN_HEIGHT - IMG_HEIGHT;

        
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
        
//way1: blit surface to screen
        
//Blit a part of backGround ( a rectangular area ) to screen,
        
//then the original blitted backGround can be "cleaned".
        backGround.blit(xpos, ypos, xpos, ypos, IMG_WIDTH, IMG_HEIGHT);
        
//Blit the image to screen.
        frontImage.blit(xpos, ypos);
        
//Flip the screen
        screen.flip();
        
//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

        
//VVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
        
//way2: blit surface to surface, then blit the last surface to screen
/*

        backGroundCopy.blitToSurface(backGround, xpos, ypos, xpos, ypos, IMG_WIDTH, IMG_HEIGHT);
        frontImage.blitToSurface(backGround, xpos, ypos);
        backGround.blit();
        screen.flip();
*/
        
//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    }

   
return 0;
}

                     
分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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