今天因为一个网上的朋友的请求,做个一个关于鼠标事件的演示程序。实际上,可以完全用到前面我们构造的类和类方法,这里送上主程序,供大家参考。其他两个文件和图片文件均不需要任何改变。
#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);
//Blit backGround surface to screen and flip the screen.
backGround.blit();
screen.flip();
//moving image's coordinate.
int xpos = 0;
int ypos = 0;
//mouse's coordinate.
int px = 0;
int py = 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;
}
}
//mouse event
if ( gameEvent.type == SDL_MOUSEMOTION ) {
px = gameEvent.motion.x;
py = gameEvent.motion.y;
}
}
if ( xpos < px )
xpos++;
if ( xpos > px )
xpos--;
if ( ypos < py )
ypos++;
if ( ypos > py )
ypos--;
backGround.blit(xpos, ypos, xpos, ypos, IMG_WIDTH, IMG_HEIGHT);
frontImage.blit(xpos, ypos);
screen.flip();
}
return 0;
}
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);
//Blit backGround surface to screen and flip the screen.
backGround.blit();
screen.flip();
//moving image's coordinate.
int xpos = 0;
int ypos = 0;
//mouse's coordinate.
int px = 0;
int py = 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;
}
}
//mouse event
if ( gameEvent.type == SDL_MOUSEMOTION ) {
px = gameEvent.motion.x;
py = gameEvent.motion.y;
}
}
if ( xpos < px )
xpos++;
if ( xpos > px )
xpos--;
if ( ypos < py )
ypos++;
if ( ypos > py )
ypos--;
backGround.blit(xpos, ypos, xpos, ypos, IMG_WIDTH, IMG_HEIGHT);
frontImage.blit(xpos, ypos);
screen.flip();
}
return 0;
}
1:扩充库(Extension Libraries)
SDL本身所支持的,仅仅是读取bmp格式的图片。要使用其它格式的图片,我们需要使用SDL的扩充库。在下面地址,我们可以下载到相关文件SDL_image-devel-1.2.6-VC8.zip。
http://www.libsdl.org/projects/SDL_image/
与SDL本身的设置一样,将include下的*.h文件拷贝到:
C:\MinGW\include\SDL (MinGW)
C:\Program Files\Microsoft Visual Studio 9.0\VC\include\SDL (VC2008)
将*.lib文件拷贝到:
C:\MinGW\lib (MinGW)
C:\Program Files\Microsoft Visual Studio 9.0\VC\lib (VC2008)
将*.dll文件拷贝到:
C:\WINDOWS\system32
在编译的时候,gcc注意增加共同编译的库文件-lSDL_image,比如,我设置了一个批处理文件g++img.bat内容如下:
g++ -o MySDL.exe main.cpp -lmingw32 -lSDLmain -lSDL -lSDL_image -mwindows
在VC2008中,需要在projec属性中,Configuration Properties -- Linker -- Input -- Additional Dependencies 下增加SDL_image.lib。在程序的头文件中,需要增加:
#include "SDL/SDL_image.h"
2:更加通用的Display Surface构造函数
我们现在可以回头过来修改我们在SDL入门教程(五):6、对C++异常机制的思考,代码重写中的Display Surface类的构造函数,使其能够更加通用的读取其它格式的图片。
DisplaySurface::DisplaySurface(std::string file_name, const ScreenSurface& screen):
fileName(file_name)
{
SDL_Surface* pSurfaceTemp = IMG_Load(file_name.c_str());
if ( pSurfaceTemp == 0 )
throw ErrorInfo(SDL_GetError());
pSurface = SDL_DisplayFormat(pSurfaceTemp);
if ( pSurface == 0 )
throw ErrorInfo(SDL_GetError());
SDL_FreeSurface(pSurfaceTemp);
pScreen = screen.point();
}
IMG_Load()可以读取多种格式的图片文件,包括BMP, PNM, XPM, LBM, PCX, GIF, JPEG, TGA和PNG。fileName(file_name)
{
SDL_Surface* pSurfaceTemp = IMG_Load(file_name.c_str());
if ( pSurfaceTemp == 0 )
throw ErrorInfo(SDL_GetError());
pSurface = SDL_DisplayFormat(pSurfaceTemp);
if ( pSurface == 0 )
throw ErrorInfo(SDL_GetError());
SDL_FreeSurface(pSurfaceTemp);
pScreen = screen.point();
}
3:将图片修改为适合显示的格式
SDL_Surface *SDL_DisplayFormat(SDL_Surface *surface);
在上面的程序中,我们使用到了函数SDL_DisplayFormat()。在之前的教程中,我一直没有用到这个函数,是因为我还没有发现用 SDL_LoadBMP()的时候会出现格式兼容性的问题——即使是图片位深与显示不一致。但是使用IMG_Load()的时候,小小的bug出现了。所 以,这里我必须使用SDL_DisplayFormat(),将读取的图片文件转换为适合显示的格式。如果转换失败,或者内存溢出,这个函数将返回空指针。