在Delphi下面配置SDL是非常简单的,因为有一个组织(JEDI)连安装程序都做好了。
你可以到这个网站http://www.delphi-jedi.org/,下载一个JEDI-SDL的安装程序。文件的名字是[JEDI-SDLFullSetup.exe],安装就是了。当然你事先要有一个Delphi,我用的是7,其他版本的我还真不清楚。
不过要想你的游戏能正常运行,你还要去下载SDL的DLL文件,这个建议你到SDL的主页去看看。如果需要image,ttf,mixer等其他的支持,可以到这里http://www.libsdl.org/projects/。之后你要把你用到的部分放到你的游戏目录里面。当然嫌麻烦的话放到系统目录里面应该也可以,不过据说现在很多人不喜欢往系统目录里面放东西。
这些都做好了你就可以试着编写一个使用SDL的Delphi程序了。我第一次做的时候是选了一个新建控制台程序,这样打开游戏的时候会有两个窗口。这倒不是问题,至少你可以随时把
{$APPTYPE CONSOLE}
这一行注释掉取消那个控制台窗口,但是我建议你还是暂时留着。至少控制台窗口的关闭按钮是随时都有效的,而SDL的主窗口的关闭按钮却不一定随时能用,在编写和调试阶段还是很方便的。
这时你有了一个dpr文件,如果把所有的函数与子程全写到这里当然不成问题,但是我认为更好的办法是把子程全写到另一个pas文件里,再在dpr文件的uses部分添加这个pas文件。因为在dpr文件里面我还没搞清楚能不能用函数预声明,如果不能的话就只能引用前面已经写好的部分,这无论如何不是个好的选择。而pas文件里面随意性就大得多。
这样你的dpr文件的内容大致应是这样(这里的语法加亮不行,凑合着看吧):
program MyGame
{$APPTYPE CONSOLE}
uses
SysUtils,
windows,
Dialogs,
SDL,
myfunctions in 'myfunctions.pas';
begin
Run;
end.
而myfunctions.pas文件里面应有这样的内容:
unit myfunctions;
interface
uses
sysutils,
windows,
sdl;procedure Run;
implementation
var
screen: PSDL_Surface;procedure Run;
begin
SDL_Init(SDL_INIT_VIDEO);
screen:=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE or SDL_DOUBLEBUF);
while true do
;SDL_Quit;
exit;end;
end.
uses里面加上Windows和Sysutils显然是必要的,因为我们可能还需要Windows的API。调试中如果想用showmessage显示一些结果的话还需要Dialogs,它比MessageBox还是方便很多。
全局变量里有一个screen,用它作为最主要的画图板,其余的画图板可以在使用的时候由子程定义。至于类型译成“SDL表面指针”看来也并不合适,不过没关系,知道它是做什么的就可以了。
SDL_Init(SDL_INIT_VIDEO)的作用是初始化视频系统,SDL_INIT_VIDEO其实是一个定义好的常数。一般这样用大致是可以,但是一个较为正式的用法应是这样:
if (SDL_Init(SDL_INIT_VIDEO)<0) then
begin
MessageBox(0, PChar(Format('Couldn''t initialize SDL : %s',[SDL_GetError])), 'Error', MB_OK or MB_ICONHAND);
SDL_Quit;
exit;
end;
就是尝试初始化视频系统,一旦失败用MessageBox输出错误消息(SDL_GetError),并退出程序。不仅是视频,其他的许多比如初始化音频时都应该添加类似的判断。我在这里略去了这部分是为了让代码看来清晰一点,但是你如果真的动手编写一个游戏的时候,判断一下无疑还是必要的。
而在初始化视频之后,还需要一个窗口显示游戏画面,就是
screen:=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE or SDL_DOUBLEBUF);
这一行的作用了,前面3个数字是屏幕的分辨率和色深,后面就是初始化的一些选项了。这里用的两个选项是在显存中生成画面并使用双缓冲,可能是要求比较高的一种,其实用 SDL_ANYFORMAT 和 SDL_SWSURFACE 也许就能满足多数情况。这里就不再一一解释这些选项的含义了,可以查看SDL的说明文件。
这样就获得了一个640*480大小的窗口,并用screen标记它。
再往后是一个死循环,这只是为了让这个窗口保持住,否则再执行下去,SDL_Quit 加上 exit 谁都知道代表什么含义。当然我们并非是真的需要一个死循环,一个游戏所需的循环应是这样:
1 如果接收到指令
2 执行指令
3 返回1在执行指令这里应有:
如果指令为“退出”,则退出循环。
把原来的死循环这样改写,并在全局变量里面添加一个event:
event: TSDL_event;
……while SDL_PollEvent(@event)>=0 do
begin
if event.type_=SDL_QUITEV then break;
end;
event是定义用来接收游戏的消息(事件)的,任何游戏都应该有这样的一个变量(而且似乎只能作为全局变量或者在最初的子程序中定义,这一点我还并没确定)。而PollEvent就是用于查询的,@在Delphi中是取地址算符,因为SDL_PollEvent的参数是指针类型。
通常可以用两种方式进行查询:
SDL_PollEvent:直接查询。返回值为0表示未查询到事件,大于0表示有事件。无论查询结果如何,程序都会继续执行。
SDL_WaitEvent:等待查询。与上面的区别是如果未查询到事件,会使游戏的流程停在此句。
何时使用这两种方式需根据情况决定。如果你觉得某些情况只需处理按键(比如在选单内部),那么Wait方式会好一些;而如果在没有事件的时候你需要一些自动效果,Poll方式也许更适合。
循环中的判断就是:一旦发生关闭窗口事件(SDL_QUITEV,注意在说明文档里面写成了SDL_QUIT,这与SDL中用于退出的重要函数同名,显然是写错了),则退出循环。
这个程序在执行时可能会占用CPU过大,这时可以在每次循环时让CPU休息一下。在while内
部加上一个:
Sdl_delay(10);
即可大大降低CPU的占用,这可能会带来10毫秒的延时,但不会真的有人在乎吧!
No comments:
Post a Comment