SDL入门教程(五):4、让图片动起来!

[复制链接]

该用户从未签到

2380

主题

2433

帖子

9139

积分

管理员

Rank: 9Rank: 9Rank: 9

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

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

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

x
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/SDLKey

4.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;
}

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

使用道具 举报

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

本版积分规则

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