SDL游戏编程门篇.docx

上传人:b****2 文档编号:17044340 上传时间:2023-07-21 格式:DOCX 页数:30 大小:326.87KB
下载 相关 举报
SDL游戏编程门篇.docx_第1页
第1页 / 共30页
SDL游戏编程门篇.docx_第2页
第2页 / 共30页
SDL游戏编程门篇.docx_第3页
第3页 / 共30页
SDL游戏编程门篇.docx_第4页
第4页 / 共30页
SDL游戏编程门篇.docx_第5页
第5页 / 共30页
SDL游戏编程门篇.docx_第6页
第6页 / 共30页
SDL游戏编程门篇.docx_第7页
第7页 / 共30页
SDL游戏编程门篇.docx_第8页
第8页 / 共30页
SDL游戏编程门篇.docx_第9页
第9页 / 共30页
SDL游戏编程门篇.docx_第10页
第10页 / 共30页
SDL游戏编程门篇.docx_第11页
第11页 / 共30页
SDL游戏编程门篇.docx_第12页
第12页 / 共30页
SDL游戏编程门篇.docx_第13页
第13页 / 共30页
SDL游戏编程门篇.docx_第14页
第14页 / 共30页
SDL游戏编程门篇.docx_第15页
第15页 / 共30页
SDL游戏编程门篇.docx_第16页
第16页 / 共30页
SDL游戏编程门篇.docx_第17页
第17页 / 共30页
SDL游戏编程门篇.docx_第18页
第18页 / 共30页
SDL游戏编程门篇.docx_第19页
第19页 / 共30页
SDL游戏编程门篇.docx_第20页
第20页 / 共30页
亲,该文档总共30页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

SDL游戏编程门篇.docx

《SDL游戏编程门篇.docx》由会员分享,可在线阅读,更多相关《SDL游戏编程门篇.docx(30页珍藏版)》请在冰点文库上搜索。

SDL游戏编程门篇.docx

SDL游戏编程门篇

使用SDL打造游戏世界之入门篇

/vc/2005/12/y057433.html

简介  SimpleDirectMediaLayer,简称SDL,是一个自由的跨平台的多媒体开发包,主要通过OpenGL和2D视频帧缓冲(framebuffer)提供对音频、键盘、鼠标、游戏操纵杆(joystick)和3D硬件的底层访问。

它被广泛的应用于MPEG回放软件、模拟器和多个著名游戏中,如获得大奖的《文明:

权倾天下》(Civilization:

CallToPower)的Linux移植版本。

它的官方站点是:

,还有一个非常个性的LOGO(图1)。

在Win32编程中,如果要操纵2D图像,可以选择使用GDI或者DirectDraw,前者速度较慢,而后者是特定针对Microsoft平台的,在非Win32平台上移植会带来很大的麻烦。

这时,你可以选择使用SDL。

SDL支持多种平台:

Linux、Windows,BeOS,MacOSClassic,MacOSX,FreeBSD,OpenBSD,BSD/OS,Solaris,IRIX和QNX,同时也部分支持部分其他平台:

WindowsCE,AmigaOS,Dreamcast,Atari,NetBSD,AIX,OSF/Tru64,RISCOS和SymbianOS。

当然SDL本身是针对2D图像编程的,如果使用到3D编程,那么需要将SDL和OpenGL结合使用。

  SDL是用C编写的,但是也支持C++,同时其他多种语言,下面给出了其他语言的SDL的开发包的相关信息:

·Ada

   AdaSDL-/adasdl/

  ·C#

   SDL.Net-http:

//cs-

  ·Eiffel

   ewg-

  ·Erlang

   ESDL-/~dgud/esdl/

  ·Euphoria

   SDL_Wrap-_wrap.zip

  ·Guile

   guile-sdl-/guile-sdl/

  ·Java

   JSDL-

   sdljava-

  ·Lisp

   CL-SDL-http:

//cl-

   SDLforCormanCommonLisp-_sdl.php3

  ·Lua

   luaSDL-http:

//lua-users.org/wiki/LuaModuleLuaSdl

  ·ML

   SDLML-/SDLML.html

   OCamlSDL-

  ·ObjectiveC

   SDLOBJC-/sdlobjc/

  ·Pascal

   SDL4Freepascal-

   JEDI-SDL--jedi.org/Jedi:

TEAM_SDL_HOME

  ·Perl

   SDLPerl-

  ·PHP

   PHPSDLmodule-

  ·Pike

   Nativelysupported(moduleSDL)-.se/

  ·Pliant

   Pligame-

  ·Python

   PyGame-

  ·Ruby

   Ruby/SDL--u.ac.jp/~ohai/index.en.html

   RUDL-

  功能

视频

  ·设置8bpp或更高的任意色彩深度的视频模式。

如果某个模式硬件不支持,可以选择转化为另一模式。

  ·直接写入线性的图像帧缓冲(framebuffer)。

  ·用颜色键值(colorkey)或者alpha混合属性创建用于绘图的表面(surface)。

  ·Surface的blit能自动的转化为目标格式。

blit是优化过的,并能使用硬件加速。

x86平台上有针对MMX优化过的blit。

  ·硬件加速的blit和fill(填充)操作,如果硬件支持的话。

  事件

  ·提供以下事件:

  o应用程序的visibility(可视性)发生改变

  o键盘输入

  o鼠标输入

  o用户要求的退出

  ·每种事件都能通过SDL_EventState()关闭或者打开。

  ·事件经由用户指定的过滤函数再被加入到内部的事件队列。

  ·线程安全的事件队列。

  音频

  ·设置8位和16位的音频,单声道或者立体声,如果格式硬件不支持,可以选择转换。

  ·由独立的线程执行音频部分,并提供用户回调(callback)机制。

  ·设计上考虑到了客户定制的软混音器,但实际上在例程中就包含了一个完整的音频/音乐输出库。

  CD音频

  ·完整的CD音频控制API

  线程

  ·简单的线程创建API

  ·用于同步的简单的二进制信号量(semaphores)

  定时器

  ·读取已流逝的毫秒数。

  ·等待指定的毫秒数。

  ·设置一个10毫秒精度的周期性定时器。

  字节序无关

  ·侦测当前系统的字节序

  ·快速转换数据的函数

  ·读写指定字节序的数据

  下载

  SDL的官方下载地址为-1.2.php,最新版本为1.2.8,分为运行库RuntimeLibrary和开发库DevelopmentLibrary,使用SDL开发需要下载的是后者。

由于SDL支持多平台和多个开发工具如VC6、VisualStudio.NET2003、Dev-C++等等,所以可以根据需要选择合适自己的平台版本。

由于笔者采用VC6给朋友们讲解SDL的使用,因此文章中只介绍了VC6下的安装方式,并使用了一个小例子做说明。

如果您使用其他的平台和工具,请在官方网站上查找相应的说明并按照要求去安装使用。

VC6下SDL的安装和初步使用

  首先,我们为所有的工程创建一个文件夹tutorial,将下载的开发库SDL-devel-,并保证如下的文件夹层次(图2)如下:

  下面我们打开VisualStudio6.0,开发一个非常简单的小例子。

选择File->New,新建一个工程,选择Win32Application,将工程gp保存为tutorial目录下,如图3所示。

  在图4中,保持默认设置,点击Finish。

  为了使用SDL,我们需要进行相关的设置,选择Project->Settings...,选择C/C++属性页,在Category中选择CodeGeneration,在Userun-timelibrary中选择DebugMultithreadedDLL,如图5所示。

  在Category中选择Preprocessor,在'Additionalincludedirectories'的文本框中填上..\SDL-,如图6所示。

  选择Link属性页,在'Object/librarymodules'文本框的首部增加SDLmain.lib和sdl.lib,如图7所示。

  仍然是Link属性页,选择Category中的Input,在'Additionallibrarypath'文本框中填写..\SDL-,如图8所示。

  这样我们就完成了编程前的设置工作,不过这是针对Debug版本的,如果要设置Release版本,需要选择Build->SetActiveConfiguration,选择Release,然后再次如上配置一次。

下面我们正式开始编程,将E:

\tutorial\SDL-,然后给gp工程增加一个C++文件main.cpp。

如图9所示。

  将以下代码拷贝到main.cpp并保存。

Copycode

#include

#ifdefined(_MSC_VER)

#include"SDL.h"

#else

#include"SDL/SDL.h"

#endif

SDL_Surface*screen;

voidrender()

{

 //独占资源,将surface锁定

 if(SDL_MUSTLOCK(screen))

  if(SDL_LockSurface(screen)<0)

   return;

 //获取当前时间,以毫秒计时

 inttick=SDL_GetTicks();

 //声明变量

 inti,j,yofs,ofs;

 //对窗口进行绘制

 yofs=0;

 for(i=0;i<480;i++)

 {

  for(j=0,ofs=yofs;j<640;j++,ofs++)

  {

   ((unsignedint*)screen->pixels)[ofs]=i*i+j*j+tick;

  }

  yofs+=screen->pitch/4;

 }

 //解除锁定

 if(SDL_MUSTLOCK(screen))

  SDL_UnlockSurface(screen);

 //使用SDL对窗口进行更新

 SDL_UpdateRect(screen,0,0,640,480);

}

//Entrypoint

intmain(intargc,char*argv[])

{

 //初始化SDL子系统,这里只对视频进行初始化

 if(SDL_Init(SDL_INIT_VIDEO)<0)

 {

  fprintf(stderr,"UnabletoinitSDL:

%s\n",SDL_GetError());

  exit

(1);

 }

 //注册SDL_Quit,当退出时调用,使得退出时程序自动清理

 atexit(SDL_Quit);

 //使用32位象素创建640x480的窗口

 screen=SDL_SetVideoMode(640,480,32,SDL_SWSURFACE);

 //若失败,则退出

 if(screen==NULL)

 {

  fprintf(stderr,"Unabletoset640x480video:

%s\n",SDL_GetError());

  exit

(1);

 }

 //主循环

 while

(1)

 {

  //Renderstuff

  render();

  //SDL中的事件轮询机制

  SDL_Eventevent;

  while(SDL_PollEvent(&event))

  {

   //对消息进行处理

   switch(event.type)

   {

    //如果按下某键的消息响应

    caseSDL_KEYDOWN:

     break;

     //如果某键按下后弹起的消息响应

    caseSDL_KEYUP:

     //若按下ESC键,则退出

     if(==SDLK_ESCAPE)

      return0;

     break;

     //退出消息响应

    caseSDL_QUIT:

     return(0);

   }

  }

 }

 return0;

}

  对工程gp进行编译,可以看看动态水波纹的效果了:

)如图10所示。

  如果你能够看到图10中的美丽动态窗口,那么恭喜你,你可以开始漫游SDL的精彩世界了。

下面我们将正式开始我们的SDL之旅。

简单的象素绘制

  下文从使用SDL的编程函数开始,介绍了如何使用SDL在屏幕上进行象素绘制的基本知识,并给出了一个简单的例子。

  如果要在VC中用SDL库,必须在源文件头部包含以下头文件:

#include“SDL.h”

  初始化SDL是通过SDL_Init()函数来实现的。

如果初始化失败,函数返回值为0。

函数只接受初始化对象作为参数。

如果要初始化视频屏幕,传入常数SDL_INIT_VIDEO作为参数;初始化音频,传入常数SDL_INIT_AUDIO;如果同时初始化视频和音频,传入SDL_INIT_VIDEO|SDL_INIT_AUDIO。

其它还有一些量可以传入作为参数的(如果同时传入多个量要使用|将它们隔开):

SDL_INIT_TIMER

SDL_INIT_AUDIO

SDL_INIT_VIDEO

SDL_INIT_CDROM

SDL_INIT_JOYSTICK

SDL_INIT_NOPARACHUATE

SDL_INIT_EVENTTHREAD

SDL_INIT_EVERYTHING

 如果我们要初始化,可以使用如下语句:

if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)<0)

{

 printf(“UnabletoinitSDL:

%s\n”,SDL_GetError());

 return1;

}

  如果初始化失败,则函数SDL_GetError()返回关于错误的一个字符串提示信息。

  当从你的C++语句返回时,记住使用SDL_Quit()进行程序的清理工作,否则就会出现奇怪的现象。

可以使用如下语句进行描述:

atexit(SDL_Quit);

  这样的话就不需要在main函数中每个return语句前加入SDL_Quit()了。

  在SDL中你可以拥有多个surface,每件物体都是一个surface。

你可以在一个surface上进行绘图或者在其他surface上绘制另外一个surface。

程序中一个surface的表示即为指向结构SDL_Surface的指针。

如果要获得一个surface只要如下定义:

SDL_Surface*screen;

  如果需要对screen所指向的surface上进行绘图,你可以使用函数SDL_SetVideoMode()来设置屏幕分辨率:

screen=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF);

  前三个参数分别为屏幕宽度,高度和屏幕上的每象素包含的位数(bitsperpixel,BPP)。

如果填入0则SDL自动选择最合适的BPP。

第四个参数用来给出某些特殊标志位。

如果要在屏幕上进行图形绘制就必须使用SDL_HWSURFACE或者SDL_SWSURFACE。

以下给出了一个你可以指定的标志位:

  SDL_SWSURFACE:

在系统内存中创建视频Surface

  SDL_HWSURFACE:

在视频内存中创建视频Surface

  SDL_ASYNCBLIT:

允许在显示surface上使用异步更新。

在单CPU机器上会变慢,但在SMP系统上会有显著的性能提升。

  SDL_ANYFORMAT:

一般的,如果指定位数的bpp不可用,那么SDL就会模拟使用阴影surface。

如果传入SDL_ANYFORMAT就会阻止这样做,并且不管色深强制使用视频surface。

  SDL_HWPALETTE:

给予SDL特许的画盘的访问权,使用这个标志位就不需要总是使用SDL_SetColors或者SDL_SetPalette来获取所需的颜色。

  SDL_DOUBLEBUF:

允许硬件双缓冲;只是和SDL_HWSURFACE一起使用时比较有用。

调用SDL_Flip将会flip整个缓冲并且更新屏幕。

所有的绘制将会在当前未显示的surface上发生。

如果双缓冲被允许,那么SDL_Flip将会对整个屏幕进行SDL_UpdateRect操作。

  SDL_FULLSCREEN:

SDL将会尝试使用全屏模式。

如果硬件分辨率的调整由于某种情况无法完成,那么下一个稍高的分辨率将会被使用,并且显示窗口将会处于一个黑色背景的中央。

  SDL_OPENGL:

创建一个OPENGLrenderingcontext。

使用前必须已经使用SDL_GL_SetAttribute对OpenGL视频属性进行设置。

  SDL_OPENGLBLIT:

和上一个选项一样创建一个OPENGLrenderingcontext,但是允许使用正常的blitting操作。

  SDL_RESIZABLE;创建一个可伸缩大小的窗口。

当用户调整窗口大小时,将会触发一个SDL_VIDEORESIZE事件,SDL_SetVideoMode将会使用新大小作为参数再次被调用。

  SDL_NOFRAME:

如果可以的话,SDL_NOFRAME将会创建出一个没有标题栏和边界修饰的窗口,全屏方式自动设置此标志位。

  建议使用SDL_HWSURFACE|SDL_DOUBLEBUF,如果出现错误可以尝试使用SDL_SWSURFACE。

  SDL_SetVideoMode如果操作成功,则返回一个指向SDL_Surface的指针,否则的话返回NULL。

可以使用如下语句检查发生的错误:

If(screen==NULL)

{

 printf(“Unabletoset640x480video:

%s\n”,SDL_GetError());

 return1;

}

  以上介绍了如何对SDL进行初始化,下面可以开始绘制了。

但是还有一些需要注意的关键地方,首先是一些SDL使用的容易让人产生迷惑的数据类型:

Uint8–相当于unsignedchar

Uint16–16位(2字节)unsignedinteger

Uint32–32位(4字节)unsignedinteger

Uint64-64位(8字节)unsignedinteger

Sint8–相当于signedchar

Sint16–16位(2字节)signedinteger

Sint32–32位(4字节)signedinteger

Sint64-64位(8字节)signedinteger

  还有,有的时候如果初始化出现错误,没必要完全退出。

例如当初始化了SDL_INIT_VIDEO而没有初始化SDL_INIT_AUDIO,那么你可以继续这个错误只是没有音频而已。

要检查是否音频初始化是否成功,可以使用SDL_WasInit()函数来检查。

下面是一个例子:

Uint32init=SDL_WasInit(SDL_INIT_AUDIO);

If(init&SDL_INIT_AUDIO)

{

 sound=1;

}else{

 sound=0;

}

  你可以在程序初始化的某些地方加入以上语句。

  以下是SDL介绍中进行象素绘制的语句,可以暂时不需要完全了解其中的意思:

voidDrawPixel(SDL_Surface*screen,intx,inty,Uint8R,Uint8G,Uint8B)

{

 Uint32color=SDL_MapRGB(screen->format,R,G,B);

 switch(screen->format->BytesPerPixel)

 {

  case1:

//Assuming8-bpp

  {

   Uint8*bufp;

   bufp=(Uint8*)screen->pixels+y*screen->pitch+x;

   *bufp=color;

  }

  break;

  case2:

//Probably15-bppor16-bpp

  {

   Uint16*bufp;

   bufp=(Uint16*)screen->pixels+y*screen->pitch/2+x;

   *bufp=color;

  }

  break;

  case3:

//Slow24-bppmode,usuallynotused

  {

   Uint8*bufp;

   bufp=(Uint8*)screen->pixels+y*screen->pitch+x*3;

   if(SDL_BYTEORDER==SDL_LIL_ENDIAN)

   {

    bufp[0]=color;

    bufp[1]=color>>8;

    bufp[2]=color>>16;

   }else{

    bufp[2]=color;

    bufp[1]=color>>8;

    bufp[0]=color>>16;

   }

  }

  break;

  case4:

//Probably32-bpp

  {

   Uint32*bufp;

   bufp=(Uint32*)screen->pixels+y*screen->pitch/4+x;

   *bufp=color;

  }

  break;

 }

}

  通过这个函数,可以传递给surface要绘制的点的(x,y)坐标和RGB值。

同时,由于绘制的屏幕不能同时接受两个函数的同时操作,我们需要其他两个辅助函数,用于在绘制前对屏幕进行锁定,以及在绘制完成之后解除锁定。

这两个工作一般由SDL_MUSTLOK(SDL_Surface*screen)和SDL_UnlockSurface(SDL_Surface*screen)完成。

使用如下两个自定义的函数会更加简单:

voidSlock(SDL_Surface*screen)

{

 if(SDL_MUSTLOCK(screen))

 {

  if(SDL_LockSurface(screen)<0)

  {

   return;

  }

 }

}

voidSulock(SDL_Surface*screen)

{

 if(SDL_MUSTLOCK(screen))

 {

  SDL_UnlockSurface(screen);

 }

}

这样,我们可以得到一个简单的主程序框架如下:

#include

#include

#include"SDL.h"

//Thefunctionsarenotshowntosavespace

voidDrawPixel(SDL_Surface*screen,intx,inty,Uint8R,Uint8G,Uint8B);

voidSlock(SDL_Surface*screen);

void

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 经管营销 > 经济市场

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2