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

作者:龙飞

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 ;
}
 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值