作者:龙飞
4.1:再讨论简单的SDL event响应。
Uint8 *SDL_GetKeyState(int *numkeys);
要让图片动起来,最好是我们可以“操作”的动。按照一般思路,键盘的“上”“下”“左”“右”是不错的选择。在FPS游戏和模拟器中,我们可能更习惯wsad四个键,所以,让他们同时起作用吧。这个函数的一般用法,是把参数设置为空指针。我们还是先忽略细节。因为有了两个新的blit()重载方法的加入,我们设置要移动的图片在screen上的坐标是(xpos,ypos),则:
//key event for up, down, left and right.
Uint8* keys;
//moving image's coordinate.
int xpos = 0;
int ypos = 0;
控制图片移动的代码如下:
//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;
}
代码一目了然,不用多解释。具体对应的按键可参考:
http://www.libsdl.org/cgi/docwiki.cgi/SDLKey4.2:对于第二种方法的分析。
我们前面讨论了总是把surface blit到screen上的情况。如果我们的思路是把其他surface先blit到一个作为背景画布的surface上,最后把背景画布blit到screen上呢?
我们将遇到的第一个疑问是,surface能不能把自己blit到自己上面?试验的结果是否定的,而SDL并没有给出官方的异常信息,即SDL_GetError()没有起作用。所以,异常得我们自己来抛出。另外一个后果是,我们必须建立背景画布的拷贝,把拷贝blit到背景画布上才是可行的。
class DisplaySurface
{
public:
bool blitToSurface(const DisplaySurface& dst_surface,
int at_x = 0, int at_y = 0) const;
bool 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;
};
这和blit到screen是类似的,但是实际效果是完全不一样的。因为,没有被blit到screen上的surface,都不可能被flip显示出来。所以,虽然参数列表是不一样的,意味着我可以继续用blit()这个名字重载。但是为了表明他们的实际效果有区别,我重新用了方法名。
bool 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 "Cannot blit surface to itself!";
if ( SDL_BlitSurface(pSurface, 0, dst_surface.point(), &offset) < 0 )
return false;
else return true;
}
bool 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 "Cannot blit surface to itself!";
if ( SDL_BlitSurface(pSurface, &dest, dst_surface.point(), &offset) < 0 )
return false;
else return true;
}
posted on 2008-02-21 15:12
lf426 阅读(3795)
评论(2) 编辑 收藏 引用 所属分类:
SDL入门教程