翻译声明:
本系列教程来自 Dev Hub,一切解释权归原作者。我只是出自个人爱好,才翻译了本系列教程。因为本人也是个初学者,而且英语水平有限,错误难免,望各路高手指正。
本课原文地址:http://www.sdltutorials.com/sdl-events/
和游戏开发基础相关的有一个叫事件(译者注:Events,我感觉还是消息比较贴切,以后就译为“消息”)的模块。消息是程序和用户之间最基本的交互。一个消息可能来自键盘、鼠标、游戏杆、游戏板等或者来自操作系统。要想处理好用户和游戏之间的交互,了解消息的运行机制很重要。前面我们已经用过消息了,虽然只是用来关闭窗口,现在我们就看看如何从用户那里接受消息。
如果你没跟上(译者注:你就去自己回顾下吧~),每个课程都是建立在前一个的基础之上的,所以我们就使用前面一节课的代码。为了跟踪所有的消息,并把它们传递给适当的函数,我们就要建立一个新的类。创建两个文件,CEvent.h和CEvent.cpp。这两个文件要处理我们的消息,并调用相应的函数。CApp要继承此类,以便我们需要捕获一个消息的时候简单的重写一个函数就行了。
打开CEvent.h,添加如下代码:
非常强大的一个类吧?好了,接着打开CEvent.cpp,并添加如下代码:
代码有点多呵,不过应该已经覆盖了所有的SDL消息了。我们要做的很简单,建立一个SDL_Event指针,然后根据其类型进行switch,并调用相应的函数。由于消息比较多,所有代码看起来有点长。
现在一切就绪,让我们回到CApp.h,然后把这两个连接起来:
编译一切正常。我们已经设定好了消息类,现在就让我们把消息连接到我们新类的结构里。打开CApp_OnEvent.cpp并编辑如下函数:
现在我们已经把消息结构传送给我们的类了,要注意调用正确的回调函数。现在,当我们要检查一个消息的时候,就重写一个函数。由于我们去掉了对SDL_QUIT消息的检查,就让我们用函数来代替。再次打开CApp.h,并添加如下函数:
OnExit()函数会处理SDL_QUIT消息。现在我们有了原型,让我们定义下它都做些什么。打开CApp_OnEvent.cpp,并添加如下代码:
重新编译一下,试试看。你应该可以像以前那样退出程序。
我希望你能认真看看我们检查的那些消息。以后我们将在我们的游戏里用到某些消息,现在你就先去熟悉熟悉吧。
跳到下一节课,看看创建我们的第一个游戏吧,Tic-Tac-Toe.
SDL 消息 —— 课程文件:
Win32: Zip, Rar
Linux: Tar(多谢Gaten)
本系列教程来自 Dev Hub,一切解释权归原作者。我只是出自个人爱好,才翻译了本系列教程。因为本人也是个初学者,而且英语水平有限,错误难免,望各路高手指正。
本课原文地址:http://www.sdltutorials.com/sdl-events/
和游戏开发基础相关的有一个叫事件(译者注:Events,我感觉还是消息比较贴切,以后就译为“消息”)的模块。消息是程序和用户之间最基本的交互。一个消息可能来自键盘、鼠标、游戏杆、游戏板等或者来自操作系统。要想处理好用户和游戏之间的交互,了解消息的运行机制很重要。前面我们已经用过消息了,虽然只是用来关闭窗口,现在我们就看看如何从用户那里接受消息。
如果你没跟上(译者注:你就去自己回顾下吧~),每个课程都是建立在前一个的基础之上的,所以我们就使用前面一节课的代码。为了跟踪所有的消息,并把它们传递给适当的函数,我们就要建立一个新的类。创建两个文件,CEvent.h和CEvent.cpp。这两个文件要处理我们的消息,并调用相应的函数。CApp要继承此类,以便我们需要捕获一个消息的时候简单的重写一个函数就行了。
打开CEvent.h,添加如下代码:
- #ifndef _CEVENT_H_
- #define _CEVENT_H_
- #include <SDL.h>
- class CEvent {
- public:
- CEvent();
- virtual ~CEvent();
- virtual void OnEvent(SDL_Event* Event);
- virtual void OnInputFocus();
- virtual void OnInputBlur();
- virtual void OnKeyDown(SDLKey sym, SDLMod mod, Uint16 unicode);
- virtual void OnKeyUp(SDLKey sym, SDLMod mod, Uint16 unicode);
- virtual void OnMouseFocus();
- virtual void OnMouseBlur();
- virtual void OnMouseMove(int mX, int mY, int relX, int relY, bool Left,bool Right,bool Middle);
- virtual void OnMouseWheel(bool Up, bool Down); //Not implemented
- virtual void OnLButtonDown(int mX, int mY);
- virtual void OnLButtonUp(int mX, int mY);
- virtual void OnRButtonDown(int mX, int mY);
- virtual void OnRButtonUp(int mX, int mY);
- virtual void OnMButtonDown(int mX, int mY);
- virtual void OnMButtonUp(int mX, int mY);
- virtual void OnJoyAxis(Uint8 which, Uint8 axis, Sint16 value);
- virtual void OnJoyButtonDown(Uint8 which, Uint8 button);
- virtual void OnJoyButtonUp(Uint8 which, Uint8 button);
- virtual void OnJoyHat(Uint8 which, Uint8 hat, Uint8 value);
- virtual void OnJoyBall(Uint8 which, Uint8 ball, Sint16 xrel, Sint16 yrel);
- virtual void OnMinimize();
- virtual void OnRestore();
- virtual void OnResize(int w,int h);
- virtual void OnExpose();
- virtual void OnExit();
- virtual void OnUser(Uint8 type, int code, void* data1, void* data2);
- };
- #endif
非常强大的一个类吧?好了,接着打开CEvent.cpp,并添加如下代码:
- #include "CEvent.h"
- CEvent::CEvent() {
- }
- CEvent::~CEvent() {
- //Do nothing
- }
- void CEvent::OnEvent(SDL_Event* Event) {
- switch(Event->type) {
- case SDL_ACTIVEEVENT: {
- switch(Event->active.state) {
- case SDL_APPMOUSEFOCUS: {
- if ( Event->active.gain ) OnMouseFocus();
- else OnMouseBlur();
- break;
- }
- case SDL_APPINPUTFOCUS: {
- if ( Event->active.gain ) OnInputFocus();
- else OnInputBlur();
- break;
- }
- case SDL_APPACTIVE: {
- if ( Event->active.gain ) OnRestore();
- else OnMinimize();
- break;
- }
- }
- break;
- }
- case SDL_KEYDOWN: { OnKeyDown(Event->key.keysym.sym,Event->key.keysym.mod,Event->key.keysym.unicode);
- break;
- }
- case SDL_KEYUP: { OnKeyUp(Event->key.keysym.sym,Event->key.keysym.mod,Event->key.keysym.unicode);
- break;
- }
- case SDL_MOUSEMOTION: { OnMouseMove(Event->motion.x,Event->motion.y,Event->motion.xrel,Event->motion.yrel,(Event->motion.state&SDL_BUTTON(SDL_BUTTON_LEFT))!=0,(Event->motion.state&SDL_BUTTON(SDL_BUTTON_RIGHT))!=0,(Event->motion.state&SDL_BUTTON(SDL_BUTTON_MIDDLE))!=0);
- break;
- }
- case SDL_MOUSEBUTTONDOWN: {
- switch(Event->button.button) {
- case SDL_BUTTON_LEFT: {
- OnLButtonDown(Event->button.x,Event->button.y);
- break;
- }
- case SDL_BUTTON_RIGHT: {
- OnRButtonDown(Event->button.x,Event->button.y);
- break;
- }
- case SDL_BUTTON_MIDDLE: {
- OnMButtonDown(Event->button.x,Event->button.y);
- break;
- }
- }
- break;
- }
- case SDL_MOUSEBUTTONUP: {
- switch(Event->button.button) {
- case SDL_BUTTON_LEFT: {
- OnLButtonUp(Event->button.x,Event->button.y);
- break;
- }
- case SDL_BUTTON_RIGHT: {
- OnRButtonUp(Event->button.x,Event->button.y);
- break;
- }
- case SDL_BUTTON_MIDDLE: {
- OnMButtonUp(Event->button.x,Event->button.y);
- break;
- }
- }
- break;
- }
- case SDL_JOYAXISMOTION: { OnJoyAxis(Event->jaxis.which,Event->jaxis.axis,Event->jaxis.value);
- break;
- }
- case SDL_JOYBALLMOTION: { OnJoyBall(Event->jball.which,Event->jball.ball,Event->jball.xrel,Event->jball.yrel);
- break;
- }
- case SDL_JOYHATMOTION: {
- OnJoyHat(Event->jhat.which,Event->jhat.hat,Event->jhat.value);
- break;
- }
- case SDL_JOYBUTTONDOWN: { OnJoyButtonDown(Event->jbutton.which,Event->jbutton.button);
- break;
- }
- case SDL_JOYBUTTONUP: {
- OnJoyButtonUp(Event->jbutton.which,Event->jbutton.button);
- break;
- }
- case SDL_QUIT: {
- OnExit();
- break;
- }
- case SDL_SYSWMEVENT: {
- //Ignore
- break;
- }
- case SDL_VIDEORESIZE: {
- OnResize(Event->resize.w,Event->resize.h);
- break;
- }
- case SDL_VIDEOEXPOSE: {
- OnExpose();
- break;
- }
- default: {
- OnUser(Event->user.type,Event->user.code,Event->user.data1,Event->user.data2);
- break;
- }
- }
- }
- void CEvent::OnInputFocus() {
- //Pure virtual, do nothing
- }
- void CEvent::OnInputBlur() {
- //Pure virtual, do nothing
- }
- void CEvent::OnKeyDown(SDLKey sym, SDLMod mod, Uint16 unicode) {
- //Pure virtual, do nothing
- }
- void CEvent::OnKeyUp(SDLKey sym, SDLMod mod, Uint16 unicode) {
- //Pure virtual, do nothing
- }
- void CEvent::OnMouseFocus() {
- //Pure virtual, do nothing
- }
- void CEvent::OnMouseBlur() {
- //Pure virtual, do nothing
- }
- void CEvent::OnMouseMove(int mX, int mY, int relX, int relY, bool Left,bool Right,bool Middle) {
- //Pure virtual, do nothing
- }
- void CEvent::OnMouseWheel(bool Up, bool Down) {
- //Pure virtual, do nothing
- }
- void CEvent::OnLButtonDown(int mX, int mY) {
- //Pure virtual, do nothing
- }
- void CEvent::OnLButtonUp(int mX, int mY) {
- //Pure virtual, do nothing
- }
- void CEvent::OnRButtonDown(int mX, int mY) {
- //Pure virtual, do nothing
- }
- void CEvent::OnRButtonUp(int mX, int mY) {
- //Pure virtual, do nothing
- }
- void CEvent::OnMButtonDown(int mX, int mY) {
- //Pure virtual, do nothing
- }
- void CEvent::OnMButtonUp(int mX, int mY) {
- //Pure virtual, do nothing
- }
- void CEvent::OnJoyAxis(Uint8 which,Uint8 axis,Sint16 value) {
- //Pure virtual, do nothing
- }
- void CEvent::OnJoyButtonDown(Uint8 which,Uint8 button) {
- //Pure virtual, do nothing
- }
- void CEvent::OnJoyButtonUp(Uint8 which,Uint8 button) {
- //Pure virtual, do nothing
- }
- void CEvent::OnJoyHat(Uint8 which,Uint8 hat,Uint8 value) {
- //Pure virtual, do nothing
- }
- void CEvent::OnJoyBall(Uint8 which,Uint8 ball,Sint16 xrel,Sint16 yrel) {
- //Pure virtual, do nothing
- }
- void CEvent::OnMinimize() {
- //Pure virtual, do nothing
- }
- void CEvent::OnRestore() {
- //Pure virtual, do nothing
- }
- void CEvent::OnResize(int w,int h) {
- //Pure virtual, do nothing
- }
- void CEvent::OnExpose() {
- //Pure virtual, do nothing
- }
- void CEvent::OnExit() {
- //Pure virtual, do nothing
- }
- void CEvent::OnUser(Uint8 type, int code, void* data1, void* data2) {
- //Pure virtual, do nothing
- }
代码有点多呵,不过应该已经覆盖了所有的SDL消息了。我们要做的很简单,建立一个SDL_Event指针,然后根据其类型进行switch,并调用相应的函数。由于消息比较多,所有代码看起来有点长。
现在一切就绪,让我们回到CApp.h,然后把这两个连接起来:
- #ifndef _CAPP_H_
- #define _CAPP_H_
- #include <SDL.h>
- #include "CEvent.h"
- #include "CSurface.h"
- class CApp : public CEvent {
- private:
- bool Running;
- SDL_Surface* Surf_Display;
- SDL_Surface* Surf_Test;
- public:
- CApp();
- int OnExecute();
- public:
- bool OnInit();
- void OnEvent(SDL_Event* Event);
- void OnLoop();
- void OnRender();
- void OnCleanup();
- };
- #endif
编译一切正常。我们已经设定好了消息类,现在就让我们把消息连接到我们新类的结构里。打开CApp_OnEvent.cpp并编辑如下函数:
- #include "CApp.h"
- void CApp::OnEvent(SDL_Event* Event) {
- CEvent::OnEvent(Event);
- }
现在我们已经把消息结构传送给我们的类了,要注意调用正确的回调函数。现在,当我们要检查一个消息的时候,就重写一个函数。由于我们去掉了对SDL_QUIT消息的检查,就让我们用函数来代替。再次打开CApp.h,并添加如下函数:
- #ifndef _CAPP_H_
- #define _CAPP_H_
- #include <SDL.h>
- #include "CEvent.h"
- #include "CSurface.h"
- class CApp : public CEvent {
- private:
- bool Running;
- SDL_Surface* Surf_Display;
- SDL_Surface* Surf_Test;
- public:
- CApp();
- int OnExecute();
- public:
- bool OnInit();
- void OnEvent(SDL_Event* Event);
- void OnExit();
- void OnLoop();
- void OnRender();
- void OnCleanup();
- };
- #endif
OnExit()函数会处理SDL_QUIT消息。现在我们有了原型,让我们定义下它都做些什么。打开CApp_OnEvent.cpp,并添加如下代码:
- #include "CApp.h"
- void CApp::OnEvent(SDL_Event* Event) {
- CEvent::OnEvent(Event);
- }
- void CApp::OnExit() {
- Running = false;
- }
重新编译一下,试试看。你应该可以像以前那样退出程序。
我希望你能认真看看我们检查的那些消息。以后我们将在我们的游戏里用到某些消息,现在你就先去熟悉熟悉吧。
跳到下一节课,看看创建我们的第一个游戏吧,Tic-Tac-Toe.
SDL 消息 —— 课程文件:
Win32: Zip, Rar
Linux: Tar(多谢Gaten)