大家好! 这是SDL 2中的第三课。信息来自
此来源。 我不喜欢Lasy Foo事件处理教程,所以我会自己编写,但是可以在
这里和
这里找到资料。
我们开始,欢迎上课
大事记
今天,我们将教我们的程序在
约翰的帮助下应对事件。
因此,让我们开始吧。 连接SDL 2并创建3个全局变量和2个常量。
#include <SDL2/SDL.h> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *john = NULL;
接下来,我们编写上一课中已经知道的3个函数:
初始化 int init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init: " << SDL_GetError() << std::endl; system("pause"); return 1; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; system("pause"); return 1; } scr = SDL_GetWindowSurface(win); return 0; }
负荷 int load() { john = SDL_LoadBMP("john.bmp"); if (john == NULL) { std::cout << "Can't load image: " << SDL_GetError() << std::endl; system("pause"); return 1; } return 0; }
退出 int quit() { SDL_FreeSurface(john); SDL_DestroyWindow(win); SDL_Quit(); return 0; }
注意(!),如果您复制上一课的代码,请不要忘记将
微笑改为
john 。
应该说的一切:我决定在初始化和图像加载阶段显示错误。
因此,让我们继续。 打开
main并调用
Init和
Load函数。
int main (int argc, char ** args) { if (init() == 1) { return 1; } if (load() == 1) { return 1; } }
现在,让我们看看任何应用程序如何工作。 您运行的任何程序(Google Chrome,Paint,Minecraft)都具有运行大量次的主循环。 这对于动态性是必要的。 以前,我们编写了一个仅显示2秒钟微笑的程序,但是为了使该程序学习如何响应用户的操作(或至少无休止地显示图像),它需要一个
While循环。
它会不断重复,并且在其中我们已经可以做我们想要的事情,例如处理事件。 但是在开始胶质循环之前,让我们创建一些变量。
bool run = true; SDL_Event e; SDL_Rect r; int x = 0; int y = 0; rx = x; ry = y;
现在,我们将分析所有内容。 首先,创建一个
boolean类型的
运行变量。 该变量负责执行循环:程序运行时,它为
true ,如果我们要停止执行,则将该变量设置为
false 。 接下来,创建类
SDL_Event的
e对象。 该对象的属性将包含接收到的事件的数据,将更加详细。 之后,我们创建
SDL_Rect类的对象
r 。 这是绘制带有我们所需坐标的对象所需的矩形。 然后我们创建
int类型的变量
x和
y 。 立即将其值分配为零。 这些将是我们角色的坐标。 下一项,我们分别给变量
rx和
ry赋值
x和
y 。
rx和
ry是矩形
r的坐标。
现在是时候打开主循环了。
while (run) { while(SDL_PollEvent(&e) != 0) { if (e.type == SDL_QUIT) { run = false; } if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_UP) { y -= 1; } if (e.key.keysym.sym == SDLK_DOWN) { y += 1; } if (e.key.keysym.sym == SDLK_RIGHT) { x += 1; } if (e.key.keysym.sym == SDLK_LEFT) { x -= 1; } } } rx = x; ry = y; SDL_FillRect(scr, NULL, SDL_MapRGB(scr -> format, 255, 255, 255)); SDL_BlitSurface(john, NULL, scr, &r); SDL_UpdateWindowSurface(win); }
让我们分析一下这段代码。 我们有两个周期。 如前所述,第一个主要对象是主要对象,它通过运行变量工作。 第二个循环负责处理事件。
SDL_PollEvent()函数打开一次执行主循环时接收到的事件队列,删除最后一个事件,并将有关此事件的数据写入传递给此函数的对象的变量中,即为
e 。 如果已删除队列中的所有事件,此函数将返回0,
NULL或
false ,因此我们编写
while条件
(SDL_PollEvent(&e)!= NULL) 。
我们进一步看:我们要做的第一步是单击窗口框架中的十字。 如果单击它,那么
将为对象
e的
类型变量分配值
SDL_QUIT 。 如果发生这种情况,则将
false赋给
运行变量,然后循环结束。
接下来,我编写了一个键盘击键测试。 如果按下按钮,则
e.type变量等于
SDL_KEYDOWN 。 接下来,检查键值。 变量
e.key.keysym.sym存储按钮的值。 我们将此值与所需值进行比较,并执行某些操作。 我们将更改约翰的坐标。 如果按下向上箭头,则
y减小1,如果向下箭头,则增大
y ,依此类推。
处理完事件后,重新分配
rx和
ry以更新Man的坐标。 接下来,我们编写已经熟悉的函数
SDL_FilRect ,它的作用非常大。 如果我们没有编写,那么约翰在移动时会留下难看的痕迹,因此,每一帧我们都会绘制一个白色背景,并在其上方绘制一个精灵。 之后,我们使用
SDL_BlitSurface函数绘制英雄。 在这里,我们将使用矩形
r或其变量
x和
y不仅在左上角绘制,还要绘制一些必要的坐标。 接下来,只需更新窗口。
在主循环之后,写
return quit(); 完成程序。
仅此而已,本课结束了。 这是这样的代码:
代号 #include <SDL2/SDL.h> #include <iostream> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; SDL_Window *win = NULL; SDL_Surface *scr = NULL; SDL_Surface *john = NULL; int init() { if (SDL_Init(SDL_INIT_VIDEO) != 0) { std::cout << "Can't init: " << SDL_GetError() << std::endl; system("pause"); return 1; } win = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (win == NULL) { std::cout << "Can't create window: " << SDL_GetError() << std::endl; system("pause"); return 1; } scr = SDL_GetWindowSurface(win); return 0; } int load() { john = SDL_LoadBMP("john.bmp"); if (john == NULL) { std::cout << "Can't load image: " << SDL_GetError() << std::endl; system("pause"); return 1; } return 0; } int quit() { SDL_FreeSurface(john); SDL_DestroyWindow(win); SDL_Quit(); return 0; } int main (int argc, char ** args) { if (init() == 1) { return 1; } if (load() == 1) { return 1; } bool run = true; SDL_Event e; SDL_Rect r; int x = 0; int y = 0; rx = x; ry = y; while (run) { while(SDL_PollEvent(&e) != NULL) { if (e.type == SDL_QUIT) { run = false; } if (e.type == SDL_KEYDOWN) { if (e.key.keysym.sym == SDLK_UP) { y -= 1; } if (e.key.keysym.sym == SDLK_DOWN) { y += 1; } if (e.key.keysym.sym == SDLK_RIGHT) { x += 1; } if (e.key.keysym.sym == SDLK_LEFT) { x -= 1; } } } rx = x; ry = y; SDL_FillRect(scr, NULL, SDL_MapRGB(scr -> format, 255, 255, 255)); SDL_BlitSurface(john, NULL, scr, &r); SDL_UpdateWindowSurface(win); } return quit(); }
我跟你说再见,再见!
<<上一课|| 下一课
>>