您的位置:首页 > 其它

SDL学习笔记四(事件处理)

2013-04-29 14:04 295 查看
游戏主要就是互动,没有互动的游戏跟电影有什么区别。。。

于是我们就得处理许多相关的事件,键盘按下或放开,鼠标移动,单击。。。。

用事件来驱动游戏的运行,SDL提供了很方便的函数可以处理程序中的事件,事件定义为一个多种事件的联合SDL_Event,下面这个函数可以取回事件队列中的第一个事件:

int SDL_PollEvent(SDL_Event *event);

这个函数很明显,给他一个SDL_Event变量的地址,它会将事件返回到对应的结构里,这个函数不会等待事件的到来,或者说不会阻塞,不管有没有事件,直接返回,下面这个函数相应的会等待事件的到来

int SDL_WaitEvent(SDL_Event *event);

这两个函数都会将事件从队列里取出,而

int SDL_PeepEvent(SDL_Event *event);

只是偷看第一个事件的内容。。。

有这三个函数来获取事件就足够了,下面就是怎么处理事件

我们可以简单的判断事件的类型

SDL_Event event;

通过判断event.type的值来区分事件的类型,然后相应的类型,event是不同的结构体,有对应的成员可以判断发生了什么事件,哪个地方改变了,比如:哪个按键按下了

当然,有时候这样一个个判断比较烦,我们可以使用下面一系列函数来获取我们关心的事件的状态:

Uint8 *SDL_GetKeyState(int *numkeys);

Uint8 SDL_GetMouseState(int *x, int *y);

还有一些类似的函数,这些函数返回一个数组来保存一些事件的状态,通过访问数组就能知道相应的事件状态

最后,综合前面所学到的东西,写一个简单的程序,它获取键盘和鼠标的事件,并用中文输出发生的事件

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <stdio.h>

#define WM_WIDTH 860
#define WM_HEIGHT 460
#define WM_BITS 32
#define WM_FLAGS SDL_SWSURFACE

const char *fontname="JDFYUANYI.TTF";
const char *backname="back.bmp";

SDL_Surface *screen=NULL;
SDL_Surface *background=NULL;
TTF_Font *font=NULL;

void init(void);
void clean(void);
void event_handle(void);
SDL_Surface *load_image(const char *iname);
void draw_surface(int x, int y, const char *msg);
void error_quit()
{
    printf("Some errors: %s\n", SDL_GetError());
    exit(EXIT_FAILURE);
}

int main(int argc, char **argv)
{
    init();
    atexit(clean);

    draw_surface((screen->clip_rect.w-12)/2,(screen->clip_rect.h-16)/2, "欢迎使用SDL");
    
    event_handle();
    exit(EXIT_SUCCESS);
}

void init(void)
{
    if(SDL_Init(SDL_INIT_EVERYTHING)==-1)
        error_quit();

    screen=SDL_SetVideoMode(WM_WIDTH, WM_HEIGHT, WM_BITS, WM_FLAGS);
    if(screen==NULL)error_quit();

    SDL_WM_SetCaption("SDL Events", NULL);

    if(TTF_Init()==-1)
        error_quit();

    font=TTF_OpenFont(fontname, 16);
    if(font==NULL)error_quit();

    background=load_image(backname);
    if(font==NULL)error_quit();
}

void clean(void)
{
    SDL_FreeSurface(background);
    TTF_CloseFont(font);
    TTF_Quit();
    SDL_Quit();
}

void event_handle(void)
{
    int gameover=0;
    while(gameover==0)
    {
        SDL_Event gevent;
        if(SDL_WaitEvent(&gevent))
        {
            switch(gevent.type)
            {
                case SDL_QUIT:
                    gameover=1;break;
                case SDL_KEYDOWN:
                    draw_surface((screen->clip_rect.w-12)/2,(screen->clip_rect.h-16)/2, "按键被按下");
                    break;
                case SDL_KEYUP:
                    draw_surface((screen->clip_rect.w-12)/2,(screen->clip_rect.h-16)/2, "按键被松开");
                    break;
                case SDL_MOUSEMOTION:
                    draw_surface((screen->clip_rect.w-12)/2,(screen->clip_rect.h-16)/2, "鼠标移动了");
                    break;
                case SDL_MOUSEBUTTONUP:
                    draw_surface((screen->clip_rect.w-12)/2,(screen->clip_rect.h-16)/2, "鼠标松开了");
                    break;
                case SDL_MOUSEBUTTONDOWN:
                    draw_surface((screen->clip_rect.w-12)/2,(screen->clip_rect.h-16)/2, "鼠标按下了");
                    break;
                default:
                    draw_surface((screen->clip_rect.w-12)/2,(screen->clip_rect.h-16)/2, "不能识别的事件");
                    break;
            }
        }
    }
}

void draw_surface(int x, int y, const char *msg)
{
    SDL_Surface *message=NULL;
    SDL_Color wordcolor={255, 255, 0};
    message=TTF_RenderUTF8_Solid(font, msg, wordcolor);
    if(message==NULL)error_quit();

    if(SDL_BlitSurface(background, NULL, screen, NULL)==-1)
        error_quit();

    SDL_Rect offset;
    offset.x=x;
    offset.y=y;
    if(SDL_BlitSurface(message, NULL, screen, &offset)==-1)
        error_quit();
    
    SDL_FreeSurface(message);
    if(SDL_Flip(screen)==-1)
        error_quit();
}

SDL_Surface *load_image(const char *iname)
{
    SDL_Surface *image=NULL;
    SDL_Surface *format=NULL;
    image=IMG_Load(iname);
    if(image==NULL)error_quit();
    format=SDL_DisplayFormat(image);

    SDL_FreeSurface(image);
    if(format==NULL)error_quit();
    return format;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: