您的位置:首页 > 编程语言 > C语言/C++

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

2012-09-10 10:14 645 查看
作者:龙飞

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::DisplaySurface(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;

}

此篇文章来自【/article/10941191.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐