8.SDL游戏开发:事件(二)

雨燕双飞 提交于 2020-03-02 11:27:59

没上班日子无聊,没得上班又没钱的日子便是痛苦,在上海又换了个地,生活不容易,新地方还不错,上网用无线,下午准备接着写SDL系列,没想到的是B450上fedora12 无线网卡驱动没整上,然后我在XP和fedora12之间不停的开关机,最终驱动装上去(lsmod 看到了),但是无线网卡还是配置上,(iwconfig)竟然找不到设备(是不是真没装上)。看来得去好看看网卡驱动模块,然后回到XP上,在虚拟机上装了个fedora17,后来发现环境什么的都没搞好,gcc都没有^=^!但仍然挡不住我这颗火热的心。接着昨天的继续,在事件驱动中鼠标有两个事件,分别是SDL_MouseMotionEvent 和SDL_MouseButtonEvent,前者指是在整个显示屏上所占的位置(x,y)关于X,Y是如何定义的,可以这么理解,在显示器的左上方是原点,水平方向是X轴,垂直方向是Y轴。后者表示鼠标的点击(单击双击左击右击)事件,还有滚动事件,下面是关于两个事件的结构体。关于两者具体的解释请看结构体注释。

typedef struct{
  Uint8 type;     /* SDL_MOUSEMOTION */
  Uint8 state;    /* 当前鼠标的状态 */
  Uint16 x, y;    /* 鼠标此时XY的坐标*/
  Sint16 xrel, yrel; /*在X / Y方向的相对运动 */
} SDL_MouseMotionEvent;
typedef struct{
  Uint8 type; /* SDL_MOUSEBUTTONDOWN OR SDL_MOUSEBUTTONUP */
  Uint8 button; /* 当前鼠标的索引它们分别是SDL_BUTTON_LEFT SDL_BUTTON_MIDDLE, SDL_BUTTON_RIGHT */
  Uint8 state;   /* SDL_PRESSED OR SDL_RELEASED */
  Uint16 x, y;   /*记录鼠标按下或释放时X,Y时间,(翻译过来是这样,但是我也不确定)*/
} SDL_MouseButtonEvent;
大概就是这样,鼠标的事件就如此。从键盘到鼠标我都关注有几点值得注意的地方,其一是Uint8 type;其二都有Uint state;前者对应的宏还不一样,从字面意思就可知道是一种型号,所以当然不同啦,但不同之间有共性那就是有DOWN和UP,当面SDL_MOUSEMOTION有点特殊。其实也就是状态,一回事喽!所以也就有了接下来的这个例子,Key STATE;
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_ttf.h"
#include <string>

//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

//The surfaces
SDL_Surface *background = NULL;
SDL_Surface *up = NULL;
SDL_Surface *down = NULL;
SDL_Surface *left = NULL;
SDL_Surface *right = NULL;
SDL_Surface *screen = NULL;

//The event structure
SDL_Event event;

//The font
TTF_Font *font = NULL;

//The color of the font
SDL_Color textColor = { 0, 0, 0 };

SDL_Surface *load_image( std::string filename )
{
    //The image that's loaded
    SDL_Surface* loadedImage = NULL;


    //The optimized surface that will be used
    SDL_Surface* optimizedImage = NULL;

    //Load the image
    loadedImage = IMG_Load( filename.c_str() );

    //If the image loaded
    if( loadedImage != NULL )
    {
        //Create an optimized surface
        optimizedImage = SDL_DisplayFormat( loadedImage );

        //Free the old surface
        SDL_FreeSurface( loadedImage );

        //If the surface was optimized
        if( optimizedImage != NULL )
        {
            //Color key surface
            SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ) );
        }
    }

    //Return the optimized surface
    return optimizedImage;
}

void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
    SDL_Rect offset;

    offset.x = x;
    offset.y = y;

    SDL_BlitSurface( source, clip, destination, &offset );
}

bool init()
{
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) {
        return false;
    }

    screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

    //If there was an error in setting up the screen
    if( screen == NULL ) {
        return false;
    }

    //Initialize SDL_ttf
    if( TTF_Init() == -1 ) {
        return false;
    }

    //Set the window caption
    SDL_WM_SetCaption( "Press an Arrow Key", NULL );

    //If everything initialized fine
    return true;
}

bool load_files()
{
    //Load the background image
    background = load_image( "background.png" );

    //Open the font
    font = TTF_OpenFont( "lazy.ttf", 72 );

    //If there was a problem in loading the background
    if( background == NULL ) {
        return false;
    }

    //If there was an error in loading the font
    if( font == NULL ) {
        return false;
    }

    //If everything loaded fine
    return true;
}

void clean_up()
{
    //Free the surfaces
    SDL_FreeSurface( background );
    SDL_FreeSurface( up );
    SDL_FreeSurface( down );
    SDL_FreeSurface( left );
    SDL_FreeSurface( right );

    //Close the font
    TTF_CloseFont( font );

    //Quit SDL_ttf
    TTF_Quit();

    //Quit SDL
    SDL_Quit();
}

int main( int argc, char* args[] )
{
    //Quit flag
    bool quit = false;

   //Initialize
    if( init() == false ) {
        return 1;
    }

    //Load the files
    if( load_files() == false ) {
        return 1;
    }

    //Render the text
    up = TTF_RenderText_Solid( font, "Up", textColor );
    down = TTF_RenderText_Solid( font, "Down", textColor );
    left = TTF_RenderText_Solid( font, "Left", textColor );
    right = TTF_RenderText_Solid( font, "Right", textColor );

    //While the user hasn't quit
    while( quit == false ) {
        while( SDL_PollEvent( &event ) ) {
            if( event.type == SDL_QUIT ) {
                quit = true;
            }
        }
        apply_surface( 0, 0, background, screen );

        //得到所有键的状态
        Uint8 *keystates = SDL_GetKeyState( NULL );

        //If up is pressed
        if( keystates[ SDLK_UP ] )
        {
            apply_surface( ( SCREEN_WIDTH - up->w ) / 2, ( SCREEN_HEIGHT / 2 - up->h ) / 2, up, screen );
        }

        //进行判断
        if( keystates[ SDLK_DOWN ] )
        {
            apply_surface( ( SCREEN_WIDTH - down->w ) / 2, ( SCREEN_HEIGHT / 2 - down->h ) / 2 + ( SCREEN_HEIGHT / 2 ), down, screen );
        }

        //If left is pressed
        if( keystates[ SDLK_LEFT ] )
        {
            apply_surface( ( SCREEN_WIDTH / 2 - left->w ) / 2, ( SCREEN_HEIGHT - left->h ) / 2, left, screen );
        }

        //If right is pressed
        if( keystates[ SDLK_RIGHT ] )
        {
            apply_surface( ( SCREEN_WIDTH / 2 - right->w ) / 2 + ( SCREEN_WIDTH / 2 ), ( SCREEN_HEIGHT - right->h ) / 2, right, screen );
        }

        //Update the screen
        if( SDL_Flip( screen ) == -1 ) {
            return 1;
        }
    }   //End while quit

    //Clean up
    clean_up();

    return 0;
}
代码真没什么意思,里面有一个SDL_GetKeyState()函数,得到了整个键盘的当前信息状态。也就stata值返回给一个数组。整个数组里面的值是一组键盘定义的宏,是通用的。其次还可以使用SDL_GetMouseState()得到鼠标的当前状态信息。
到这个时候,事件也差不了吧!错了还差的远,还有事件同步,异步都没提到,以及系统事件,游戏手柄事件,窗口大小,窗口重绘,还有用户自定义事件,平台相关的系统事件,其中有一个退出事件,这个应该很清楚了吧,此外有组合键事件……

昨晚写到这里,本来准备发表的,但是发表不成功,所以今天上午倒腾到现在总算搞把fedora 无线上网搞点,只不过是换到fedroa17,用上去感觉还不错,至少字体,界面好看多了。有一点小小欣喜。U盘安装fedora DVD版本(到时候我也把整个安装过程遇到的问题和大家一起分享下。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!