SDL(Simple DirectMedia Layer) 是一个的第三方图形库(library),用于主要2D游戏开发(当然你也可以用它开发普通的应用)。优点有轻量,跨平台,简单。很适合想做游戏开发但目前仅有基本的C++基础(至少了解类和指针的操作)的童鞋。
这是 官网地址 ,英文OK的童鞋可以在wiki板块得到很大帮助。在这篇博客的底部会有一些英文资源为这些童鞋准备。
不同平台的安装方法不一,这里我就不解释了(自行Google)。最新的稳定版本是SDL2.0.3(不过只要是SDL2.0或以上基本没区别),这一个系列的博客将写下我的学习历程和对一些问题的感想,也有翻译国外一些教程。不定期更新。
这篇博客是用SDL2创建一个简单的窗口程序。
要使用SDL2,要包含“SDL.h”的头文件:
1 #include "SDL.h"
于是有了下面的大体结构:
1 #include "SDL.h" 2 #include <iostream> 3 int main(int argc,char* argv[[]){ 4 5 return 0; 6 }
不同于学习C++时的int main(){return 0;},这里的main函数有了两个很怪的参数,对于初学者只要先记住就好。
接下来是初始化SDL:
1 SDL_Init(SDL_INIT_EVERYTHING);
这个SDL_Init函数的语法是SDL_Init(Uint32 flags).这个Uint32类型是SDL中的一种特殊类型,是Unsigned Int 32(占32字节的无符号整数)的缩写。这里的flags有以下几个:
如果你英文实在不好我还制作了如下表格(翻译水平很烂):
作为初学者,了解SDL_INIT_AUDIO,SDL_INIT_VIDEO,SDL_INIT_EVERYTHING就已足够。我一般选择SDL_INIT_EVERYTHING,应为它初始化了所有的分支系统(不管是不是我需要的,但一定可以满足我的需求)。
而SDL_Init函数的返回类型是int,如果初始化成功就返回0,失败就返回一个负数。所以要检查是否初始化成功,一个if语句就OK:
#include "SDL.h" #include <iostream> int main(int argc,char* argv[]){ if(SDL_Init(SDL_INIT_EVERYTHING)!=0){ std::cout<<"初始化失败"<<std::endl; }else{ //做我们想干的事情 } return 0; }
我们想干什么呢?我们要创建一个窗口!得有一个窗口对象。SDL中这个对象的类型为SDL_Window.
1 SDL_Window* myWindow;
你可能对为吗要声明一个指针而不是直接声明对象有疑问,这个我只能说为了以后方便。现在我们把myWindow作为全局变量。
目前为止我们声明了一个指针,但我们的窗口没有属性(标题,位置,大小,展现形式),SDL中用SDL_CreateWindow函数来给窗口添加属性。
SDL_CreateWindow函数的语法如下:
1 SDL_Window* SDL_CreateWindow(const char* title, 2 int x, 3 int y, 4 int w, 5 int h, 6 Uint32 flags)
6个参数,title代表window的标题,x和y是window左上角的坐标(当然你也可以填SDL_WINDOWPOS_CENTERED来让你的窗口在屏幕正中间),w和h是window的宽和高。最后一个flags有以下几个可选:
好多,我就不翻译了,英文不好的童鞋还是好好学一下吧,满眼都是英文,你不懂会打击你的。
这里我认为3个应该掌握:1.SDL_WINDOW_SHOWN(window不可改变大小)2.SDL_WINDOW_RESIZABLE(window可改变大小)3.SDL_WINDOW_FULLSCRREEN(全屏)。大家可以把每一个都试一下。我个人习惯SDL_WINDOW_RESIZABLE。现在代码应该长这个样子:
1 #include "SDL.h" 2 #include <iostream> 3 SDL_Window* myWindow; 4 int main(int argc,char* argv[]){ 5 if(SDL_Init(SDL_INIT_EVERYTHING)!=0){ 6 std::cout<<"初始化SDL失败"<<std::endl; 7 }else{ 8 myWindow=SDL_CreateWindow("Demo",300,300,600,450,SDL_WINDOW_RESIZABLE); 9 } 10 return 0; 11 }
这里需要说明的是SDL_CreateWindow是有返回类型的,他返回一个(SDL_Window*)类型的指针。在这里正好是myWindow。
要检查myWindow是否创建成功,只需检查myWindow是否是空指针就好。代码:
1 if(myWindow==NULL){ 2 std::cout<<"创建窗口失败"<<std::endl; 3 }else{ 4 //做我们想干的事 5 }
有初始就有毁灭,我们初始化了SDL和myWindow,程序不可能一直运行,是时候毁灭他们了。
1 SDL_DestroyWindow(myWindow);//毁灭窗口 2 SDL_Quit();//退出程序
现在代码应该长这样:
1 #include "SDL.h" 2 #include <iostream> 3 SDL_Window* myWindow; 4 int main(int argc,char* argv[]){ 5 if(SDL_Init(SDL_INIT_EVERYTHING)!=0){ 6 std::cout<<"初始化失败"<<std::endl; 7 }else{ 8 myWindow=SDL_CreateWindow("Demo",300,300,600,450,SDL_WINDOW_RESIZABLE); 9 if(myWindow==NULL){ 10 std::cout<<"创建窗口失败"<<std::endl; 11 }else{ 12 //做我们想干的事 13 } 14 SDL_DestroyWindow(myWindow); 15 SDL_Quit(); 16 return 0; 17 }
}
可是想一下我们到底干了些什么:我们创建了一个window,然后立马把它毁灭,仅此而已!!这个程序可以运行,但我们什么也看不到(程序是逐语句运行的,myWindow创建后立即被毁灭的速度很快);怎样才能看到我们辛苦创建的window呢?
在毁灭窗口前用SDL_Delay函数,它的语法是:
1 SDL_Delay(int 毫秒数);
比如SDL_Delay(5000);就可以让SDL在执行其后的语句前停留5秒钟;
最终代码:
1 #include "SDL.h" 2 #include <iostream> 3 SDL_Window* myWindow; 4 int main(int argc,char* argv[]){ 5 if(SDL_Init(SDL_INIT_EVERYTHING)!=0){ 6 std::cout<<"初始化失败"<<std::endl; 7 }else{ 8 myWindow=SDL_CreateWindow("Demo",300,300,600,450,SDL_WINDOW_RESIZABLE); 9 if(myWindow==NULL){ 10 std::cout<<"创建窗口失败"<<std::endl; 11 }else{ 12 //做我们想干的事 13 } 14 SDL_Delay(5000); 15 SDL_DestroyWindow(myWindow); 16 SDL_Quit(); 17 return 0; 18 } 19 }
运行后你将看到一个宽600,高450的窗口,它会持续5秒,之后自动消失。
2个SDL2的英文资源:
1. headerphile.com (这个人网站的SDL2教程简洁又不乏深度)
2.SDL2 Game Development(为数不多的SDL2书籍,讲的蛮好),下一篇博客我将给出百度网盘链接