| 订阅 | 在线投稿
分享
 
 
 

C++跨平台游戏开发之ClanLibSDK

2008-06-01 02:08:08  编辑来源:互联网  宽屏版  评论

本文为【C++跨平台游戏开发之ClanLibSDK】的汉字拼音对照版显示拼音

yi jianjieClanLibshiyigezhuyaozhenduiyouxikaifazhedekuapingtaiC++kuangjiajinguanAPIzhuyaoweiyouxikaifashejinizhaoyangkeyiqingyidi使shiyongClanLiblaikaifayigekexuede3Dkeshihuagongjuhuoduomeitiyingyongchengxu(liruGeckoduomeitixitong)ClanLibyongyougezhongAPI-2Dhe3DtuxingshengyinwangluoI/OshuruGUIyijiziyuanzhilitahuantigongtoumingdeOpenGLzhichiyincinikeyi使shiyongbenjiOpenGLminglingerrangClanLibchuliyikaoyucaozuoxitongdechuangkouzhiliheqitayiqieshiqingClanLibtongguoDirectXhuojiandandeDirect Media Layer(yipingtaidulideduomeitiku)shengcheng2DtuxingClanLibyouxizhuyeshangliejuleyue50duogekaifafeichangchenggongdeyouxibaokuoyi2Dhe3DxingshiwanchengdenanticelueyijisheshouleiyouxiliruAsteroid Arena(jiantu1)使shiyongleClanLibheOpenGLjishushixianleshengrenyichoudejingdianjiejiyouxi

C++跨平台游戏开发之ClanLibSDK

tu1.Asteroid Arenapingmukuaizhao

ClanLibkeyigongzuozaiWindowslinuxheMacOScaozuoxitongzhishangbingqietigongyuanmajideziphuotarwenjianzhichiWindowskaifazhekeyi使shiyongweiruanVisual StudioBorland C++huozheMinGW(xiaoxingGNU for Windows)bianyiqihehuanjingdisanfangdeduiyuRubyhePerlyuyandebangdingzhichiyeshikeyongdekexuandetexiaochengxubaokuoyigeLuachajian(liuxingdexiaojiaobenbianchengyuyan)heFreeType(yigemianfeideTrueTypezitiku)

er ClanLibtezhengji

zaijuti使shiyongAPIzhiqianrangwomenkanyixiaClanLibdezhuyaotezheng:

·jibenkuapingtaiyunxingshikeku(GUIduo线xianchengwenjianI/Odengdeng)

·jiyumobandeC++xinhao/caoku(leixinganquandehuitiao/daili)

·zonghedeziyuanzhili

·shengyinhunheqizhichiWAVwenjianOgg VorbisyijiyouMikModku(MODS3MXMdengdeng)zhichiderenheleixingwenjian

·wendangduixiangmoxing(DOM)xmlfenxiqizhichi

·gaoji2DtuxingAPIzhichiOpenGLDirectXheSDLzuoweizhesemubiao

·gaoxingnengdepiliangzheseyinqingdangyongOpenGLzhese2Dshi

·2Dpengzhuangjiance

·2Djinglingdonghuazhichi

·gaodukedingzhideGUIkuangjia

·congdijidaogaojidewangluokujiekou

san ClanLibjibendeyouximoxing

xianzairangwomenzaixifenxiyixiaClanLib APImoxingwofaxianzuihaodejiaochengshiyigewanquanzijieshideshilichengxujutidirangwomenfenxiyixiaLuke Worthdeheziyouxizheshiyigeyoulianggewanjiadezhiheqianbiyouxi(jiantu2)zhegeheziyouxibaohanyixiegezidianzairenyiliangdianjianwanjiadoukeyihua线xianshuiyongzuihouyitiao线xianhuachengyigefengzhuangdejuxingshuijiudeyifenbingjinrudaoxiayilunzhong

C++跨平台游戏开发之ClanLibSDK

tu2.yigejinxingzhongdeheziyouxidefenqingkuangshilan8/hong3

woteyi使shichengxudemainhanshujinkenengjianduanzheyangwomenkenengjizhongzhuchongliyugaoliangchude"youxixunhuan"

1 #include <iostream>

2 #include <ClanLib/application.h>

3 #include <ClanLib/core.h>

4 #include <ClanLib/display.h>

5 #include <ClanLib/gl.h>

6 #include <ClanLib/sound.h>

7 #include <ClanLib/vorbis.h>

8

9 const int boardsize = 6, spacing = 50, border = 20;

10 const int numsquares = int(pow(float(boardsize - 1), 2));

11

12 enum coloursquare { off, blue, red };

13 strUCt cursor {

14 int x, y;

15 bool vert;

16 };

17

18 class Boxes: public CL_ClanApplication {

19 bool ver[boardsize][boardsize - 1];

20 bool hor[boardsize - 1][boardsize];

21 coloursquare squares[boardsize - 1][boardsize - 1];

22 bool redturn;

23 bool fullup;

24 cursor curs;

25

26 void inputHandler(const CL_InputEvent &i);

27 bool findsquares(void);

28 inline int numaroundsquare(int x, int y);

29 void init();

30 void drawBoard();

31 void endOfGame();

32

33 public:

34 virtual int Boxes::main(int, char **);

35 } app;

36

37 using namespace std;

40

41 int Boxes::main(int, char **)

42 {

43 int winsize = spacing * (boardsize - 1) + border * 2;

44 try {

45 Boxes::init();

46 while (!CL_Keyboard::get_keycode(CL_KEY_ESCAPE)) {

47 Boxes::drawBoard();

48 if (fullup) break;

49 CL_System::keep_alive(20);

50 }

51 Boxes::endOfGame();

52

53 CL_SetupVorbis::deinit();

54 CL_SetupSound::deinit();

55 CL_SetupGL::deinit();

56 CL_SetupDisplay::deinit();

57 CL_SetupCore::deinit();

58 }

59 catch (CL_Error err) {

60 std::cout << "Exception caught: "<< err.message.c_str() << std::endl;

61 }

62

63 return 0;

64 }

guanyuzhegeyingyongchengxuyingzhuchongdediyishiqingshimain()hanshu(jianxing41)bingbushiyigezuidingcengdehanshuershiqianrudaoyigecongCL_ClanApplicationpaishengdeduixiangzhonggaiduixiangfengzhuanglebushaonanyibimiandepingtaiyikaoxing-zhekenengbaohanyigechuantongde::main()shixian(liruzaiWin32yingyongchengxuzhongbixu使shiyongWinMain())

erqiehuanyingzhuchongshishishangsuoyoudekezhixingdedaima(xing43-58)beifengzhuangzaiyigetry{}/catch{}yichangchuliqikuaizhongjiaruxuyaodehuaClanLibjiangyinfayichangnikeyichongqiyiyouxi,dengdengjibenshangsuoyoudeyouxiluojibaohanzaiinit()drawBoard()endOfGame()heinputHandler()zhejigefangfazhongjiaruboardbuzaiyidong(fullup==true)ze退tuichuyouxixunhuan(xing48)CL_System::keep_alive()gengxinsuoyoudeshuruhexitongshijian(xiangguanbichuangkouhuozheyidongta)zhezailaoshideWin16 API ::Yield()huozheLinuxshangdesleep()zhongjianghuishifangCPUzhouqi

66 void Boxes::init()

67 {

68 CL_SetupCore::init();

69 CL_SetupDisplay::init();

70 CL_SetupGL::init();

71 CL_SetupSound::init();

72 CL_SetupVorbis::init();

73

74 CL_DisplayWindow window("Boxes", winsize, winsize);

75 CL_SoundOutput output(44100); //xuanze44Khzcaiyang

76

77 CL_Surface *cursimg = new CL_Surface("cursor.tga");

78 cursimg->set_alignment(origin_center);

79 CL_Surface *redpict = new CL_Surface("handtransp.tga");

80 redpict->set_alignment(origin_center);

81 redpict->set_scale(float(spacing)/float(redpict->get_width()),

82 float(spacing)/float(redpict->get_height()));

83 CL_Surface *bluepict = new CL_Surface("circlehandtransp.tga");

84 bluepict->set_alignment(origin_center);

85 bluepict->set_scale(float(spacing) / float(bluepict->get_width()),

86 float(spacing) / float(bluepict->get_height()));

87

zhelideinit()fangfawanchengdabufendeyouxichushihuagongzuodangranzaicixuyaoClanLibzixitongyiyongyuchulituxingheshengyin(xing68-72)ranhougoujianyigechuangkouyongyuxianshisuoyoudetuxing(xing75)

CL_Surface(xing77-87)shiyige2Dweituleiyongyuhuizhiguangbiaoyonglansetianchongdefanggeheyonghongsetianchongdefangge

TGAwenjianshiyizhongweituwenjiangeshiClanLibyouyigejichengdePNGkuyincitakeyiduxiezuiliuxingdeweituwenjiangeshihua

xiayibunibixubabanzichushihuachengyigekongzhuangtai(xing87-103)bingzhixingleisideqitadeqingligongzuoyishixianxindeyouxijishuqi

89

90 redturn = true;

91 curs.vert = false;

92 fullup = false;

93 curs.x = curs.y = 1;

94

95 srand(CL_System::get_time()); //qidongsuijishuzishengchengqi

96

97 for (int x = 0; x < boardsize - 1; x++) {

98 for (int y = 0; y < boardsize; y++)

99 hor[x][y] = ver[y][x] = false;

100

101 for (int y = 0; y < boardsize - 1; y++)

102 squares[x][y] = off;

103

104

ClanLibdeyigefeifantuchudefangmianshitabikaichuantongxingyingyongyuxuduokuangjiazhongdehuitiaomoxingeryinrule"xinhaohecao"moxingzhezhongmoxing广guangfanyingyongyuBoost C++kuzhongbingzaiQTzhongdedaoshixianxinhaodaibiaojuyouduogemubiaodehuitiaohanshuyouzaiyixieleisidexitongzhongchengzuo"chubanzhe"huozhe"shijian"xinhaobeilianjiedaoyixiecaoshangtamenshihuitiaohanshujieshouqi(yechengzuoshijianmubiaohuozhedinghu)dangxinhaobei"fachu"shijibeitiaoyongxinhaojuyouleixinganquandeyoudiantamenbikailezaichuantongxingdekuangjiazhongdebukebimiandecastcaozuo

xinhaohecaobeitongyizhilizaixinhaohecaozhong(huozhegengzhunquexieshuoshizuoweicaodeyibufenchuxiandeduixiang)genzongsuoyoudelianjiebingdangrenheqiyibeipohuaishinenggouzidongdiduankaixinhao/caolianjiezhenenggou使shiyonghujianlixinhao/caolianjieerbuxuyaohuafeiduodadedaijialaizhilinaxielianjieyijisuoyoubaohanyuqizhongdeduixiangdeshengmingzhouqizaixing105zhongnizhiyaobuzhuosuoyoudejianji("down")shijianbingquebao使shiyonglenizijideinputHandler()(jianxing168-216)

105 CL_Slot keyPRess =

CL_Keyboard::sig_key_down().connect(this,

&Boxes::inputHandler);

xianzainijiangkaishichushihuachengxudeyinlebufenshouxianniyongyige.wavgeshide("binary")yinlewenjianzhuangzaiyigeCL_SoundBufferranhouyubeiyigehuihuajubingyiweiwanyouxizhiyongxiayibuniyingyongyigedanrudanchuguolvqilaiyibuditiaozhengyinliang-zaiwumiao(xing 108-112)neibayinliangconglingbianhuadaozuidayinliangdebaifenzhiliushi

106 CL_SoundBuffer *music = new CL_SoundBuffer("linemusic.ogg");

107 CL_SoundBuffer_session session = music->prepare();

108 CL_FadeFilter *fade = new CL_FadeFilter(0.0f);

109 session.add_filter(fade);

110 session.set_looping(true);

111 session.play();

112 fade->fade_to_volume(0.6f, 5000);

113 }

drawBoard()fangfahuizhi线xianduansuozaidedianhuagezituanrumeigewanjiayingdedehongsede西xihongshihelansedeshichejukuangchudefanggehuanyoumonideguangbiaoerzuichongyaodedaimaxingshidi165xingCL_Display::flip()jiaohuanqianhoutaihuanchongquhoutaihuanchongqushizaigaizhenzhongnihuizhisuoyoutuxingdedifangerqiantaihuanchongqushixianshizaipingmushangdeneirong

115 void Boxes::drawBoard()

116 {

117 CL_Display::clear(redturn ? CL_Color::red : CL_Color::blue);

118 CL_Display::fill_rect(CL_Rect(border/2, border/2,

119 winsize - border/2, winsize - border/2),CL_Color::black);

120

121 //huafangkuang

122 for (int x = 0; x < boardsize - 1; x++)

123 for (int y = 0; y < boardsize - 1; y++) {

124 if (squares[x][y] == red) {

125 CL_Display::fill_rect(CL_Rect(x * spacing + border,y * spacing + border, x * spacing + border +

spacing,

127 y * spacing + border + spacing),CL_Gradient(CL_Color::red,

128 CL_Color::red, CL_Color::tomato, CL_Color::tomato));

129 redpict->draw(x * spacing + border + spacing / 2,

130 y * spacing + border + spacing / 2);

131 }

132 else if (squares[x][y] == blue) {

133 CL_Display::fill_rect(CL_Rect(x * spacing + border,

134 y * spacing + border,x * spacing + border +spacing,

135 y * spacing + border +spacing),CL_Gradient(CL_Color::blue,

136 CL_Color::blue, CL_Color::cornflowerblue,CL_Color::cornflowerblue));

137 bluepict->draw(x * spacing + border + spacing / 2,y * spacing + border + spacing / 2);

139 }

140 }

141

142 //hua线xian

143 for (int x = 0; x < boardsize; x++) {

144 for (int y = 0; y < boardsize - 1; y++) {

145 if (ver[x][y]) CL_Display::draw_line(x * spacing + border,

146 y * spacing + border,x * spacing + border,

147 y * spacing + border+ spacing,CL_Color::yellow);

148 if (hor[y][x]) CL_Display::draw_line(y * spacing + border,

149 x * spacing + border,y * spacing + border+ spacing,x * spacing + border,CL_Color::yellow);

151 }

152 }

153

154 //huagezi

155 for (int x = 0; x < boardsize; x++)

156 for (int y = 0; y < boardsize; y++)

157 CL_Display::draw_rect(CL_Rect(x * spacing + border,

158 y * spacing + border,x * spacing + border + 2,159 y * spacing + border + 2),CL_Color::white);

160

161 //huaguangbiao

162 if (curs.vert) cursimg->draw((curs.x - 1) * spacing + border,int((curs.y - 0.5) * spacing + border));

163 else cursimg->draw(int((curs.x - 0.5) * spacing + border),(curs.y - 1) * spacing + border);

164

165 CL_Display::flip();

166 }

nianzhuangdeinputHandler()hanshuyongyuguanchazaixing105deanjianxinhaozhegehanshufuzechulixijiewenti-bajianjibianchengyouxiyundonghuanyouzuichongyaodekonggehuozhehuichejian-yongyuzhishidangqianwanjiadeyigexuanze(xing200-210)ranhouniyaojianchayixiashifouyiwanchengleyige"fangxing"bingbakongzhifanhuidaoyuanlaidewanjia

168 void Boxes::inputHandler(const CL_InputEvent &i)

169 {

170 if (redturn) {

171 switch(i.id) {

172 case CL_KEY_LEFT:

173 case CL_KEY_G:

174 if (curs.x > 1) curs.x--;

175 break;

176 case CL_KEY_RIGHT:

177 case CL_KEY_J:

178 if (curs.x < boardsize) curs.x++;

179 break;

180 case CL_KEY_UP:

181 case CL_KEY_Y:

182 if (!curs.vert && curs.y > 1) {

183 curs.y--;

184 curs.vert = !curs.vert;

185 }

186 else if (curs.vert) curs.vert = false;

187 break;

188 case CL_KEY_DOWN:

189 case CL_KEY_H:

190 if (curs.vert && curs.y < boardsize) {

191 curs.y++;

192 curs.vert = !curs.vert;

193 }

194 else if (!curs.vert) curs.vert = true;

195 break;

196 }

197 if (curs.x == boardsize && !curs.vert) curs.x--;

198 if (curs.y == boardsize && curs.vert)

curs.vert = false;

199

200 if (i.id == CL_KEY_SPACE i.id == CL_KEY_ENTER) {

201 if (curs.vert) {

202 if (!ver[curs.x-1][curs.y-1]) {

203 ver[curs.x-1][curs.y-1] = true;

204 if (!findsquares()) redturn = !redturn;

205 }

206 }

207 else {

208 if (!hor[curs.x-1][curs.y-1]) {

209 hor[curs.x-1][curs.y-1] = true;

210 if (!findsquares()) redturn = !redturn;

211 }

212 }

213 }

214 }

215 }

zuihouyouendOfGame()fangfajisuanzuihoudedefenjizhuyouxihuanmeiyoujieshuzhidaobanzimanleweizhi(jianxing48)huozhemourentongguoanxiaESCjian(jianxing46)退tuichuzuihouniyongdayue1miaodeshijianbayinliangdanchudao0

217 void Boxes::endOfGame()

218 {

219 // jishudefen

220 int redscore, bluescore;

221 redscore = bluescore = 0;

222 for (int x = 0; x < boardsize - 1; x++)

223 for (int y = 0; y < boardsize - 1; y++) {

224 if (squares[x][y] == red) redscore++;

225 else if (squares[x][y] == blue) bluescore++;

226 }

227

228 cout << "Red: " << redscore << "\nBlue: " << bluescore << endl;

229 if (bluescore != redscore)

230 cout << (bluescore > redscore ? "Blue" : "Red") << " player wins\n";

231 else cout << "It was a tie\n";

232

233 if (fullup) {

234 fade->fade_to_volume(0.0f, 1000);

235 CL_System::sleep(1000);

236 }

237 }

原文
一、 简介 ClanLib是一个主要针对游戏开发者的跨平台C++框架。尽管API主要为游戏开发设计,你照样可以轻易地使用ClanLib来开发一个科学的3D可视化工具或多媒体应用程序(例如Gecko多媒体系统)。 ClanLib拥有各种API-2D和3D图形,声音,网络,I/O,输入,GUI以及资源治理。它还提供透明的OpenGL支持,因此你可以使用本机OpenGL命令而让ClanLib处理依靠于操作系统的窗口治理和其它一切事情。ClanLib通过DirectX或简单的Direct Media Layer(一平台独立的多媒体库)生成2D图形。ClanLib游戏主页上列举了约50多个开发非常成功的游戏,包括以2D和3D形式完成的难题、策略以及射手类游戏。例如,Asteroid Arena(见图1)使用了ClanLib和OpenGL技术,实现了胜人一筹的经典街机游戏。 [url=http://www.wangchao.net.cn/bbs/hydetail_1785417.html][img]http://image.wangchao.net.cn/it/1323423490174.jpg[/img][/url] 图1.Asteroid Arena屏幕快照   ClanLib可以工作在Windows,linux和MacOS操作系统之上,并且提供源码级的zip或tar文件支持。Windows开发者可以使用微软Visual Studio,Borland C++或者MinGW(小型GNU for Windows)编译器和环境。第三方的对于Ruby和Perl语言的绑定支持也是可用的。可选的特效程序包括一个Lua插件(流行的小脚本编程语言)和FreeType(一个免费的TrueType字体库)。   二、 ClanLib特征集   在具体使用API之前,让我们看一下ClanLib的主要特征:   ·基本跨平台运行时刻库(GUI,多线程,文件I/O,等等)   ·基于模板的C++信号/槽库(类型安全的回调/代理)   ·综合的资源治理   ·声音混合器支持。WAV文件,Ogg Vorbis,以及由MikMod库(MOD,S3M,XM,等等)支持的任何类型文件   ·文档对象模型(DOM)xml分析器支持   ·高级2D图形API,支持OpenGL,DirectX和SDL作为着色目标   ·高性能的批量着色引擎,当用OpenGL着色2D时   ·2D碰撞检测   ·2D精灵动画支持   ·高度可定制的GUI框架   ·从低级到高级的网络库接口   三、 ClanLib基本的游戏模型   现在,让我们仔细分析一下ClanLib API模型。我发现最好的教程是一个完全自解释的示例程序。具体地,让我们分析一下Luke Worth的盒子游戏,这是一个有两个玩家的纸和铅笔游戏(见图2)。这个盒子游戏包含一些格子点,在任意两点间玩家都可以画线。谁用最后一条线画成一个封装的矩形,谁就得一分,并进入到下一轮中。 [url=http://www.wangchao.net.cn/bbs/hydetail_1785417.html][img]http://image.wangchao.net.cn/it/1323423490343.jpg[/img][/url] 图2.一个进行中的盒子游戏,得分情况是蓝8/红3   我特意使程序的main函数尽可能简短,这样我们可能集中注重力于高亮处的"游戏循环": 1 #include <iostream> 2 #include <ClanLib/application.h> 3 #include <ClanLib/core.h> 4 #include <ClanLib/display.h> 5 #include <ClanLib/gl.h> 6 #include <ClanLib/sound.h> 7 #include <ClanLib/vorbis.h> 8 9 const int boardsize = 6, spacing = 50, border = 20; 10 const int numsquares = int(pow(float(boardsize - 1), 2)); 11 12 enum coloursquare { off, blue, red }; 13 strUCt cursor { 14  int x, y; 15  bool vert; 16 }; 17 18 class Boxes: public CL_ClanApplication { 19  bool ver[boardsize][boardsize - 1]; 20  bool hor[boardsize - 1][boardsize]; 21  coloursquare squares[boardsize - 1][boardsize - 1]; 22  bool redturn; 23  bool fullup; 24  cursor curs; 25 26  void inputHandler(const CL_InputEvent &i); 27  bool findsquares(void); 28  inline int numaroundsquare(int x, int y); 29  void init(); 30  void drawBoard(); 31  void endOfGame(); 32 33 public: 34  virtual int Boxes::main(int, char **); 35 } app; 36 37 using namespace std; 40 41 int Boxes::main(int, char **) 42 { 43  int winsize = spacing * (boardsize - 1) + border * 2; 44  try { 45   Boxes::init(); 46   while (!CL_Keyboard::get_keycode(CL_KEY_ESCAPE)) { 47    Boxes::drawBoard(); 48    if (fullup) break; 49     CL_System::keep_alive(20); 50   } 51   Boxes::endOfGame(); 52 53   CL_SetupVorbis::deinit(); 54   CL_SetupSound::deinit(); 55   CL_SetupGL::deinit(); 56   CL_SetupDisplay::deinit(); 57   CL_SetupCore::deinit(); 58  } 59  catch (CL_Error err) { 60   std::cout << "Exception caught: "<< err.message.c_str() << std::endl; 61  } 62 63  return 0; 64 }   关于这个应用程序,应注重的第一事情是main()函数(见行41)并不是一个最顶层的函数,而是嵌入到一个从CL_ClanApplication派生的对象中。该对象封装了不少难以避免的平台依靠性-这可能包含一个传统的::main()实现(例如在Win32应用程序中必须使用WinMain())。   而且还应注重,事实上所有的可执行的代码(行43-58)被封装在一个try{}/catch{}异常处理器块中。假如需要的话,ClanLib将引发异常,你可以重启一游戏,等等。基本上,所有的游戏逻辑包含在init(),drawBoard(),endOfGame()和inputHandler()这几个方法中。假如board不再移动(fullup==true),则退出游戏循环(行48)。CL_System::keep_alive()更新所有的输入和系统事件(象关闭窗口或者移动它)。这在老式的Win16 API ::Yield()或者Linux上的sleep()中将会释放CPU周期。 66 void Boxes::init() 67 { 68  CL_SetupCore::init(); 69  CL_SetupDisplay::init(); 70  CL_SetupGL::init(); 71  CL_SetupSound::init(); 72  CL_SetupVorbis::init(); 73 74  CL_DisplayWindow window("Boxes", winsize, winsize); 75  CL_SoundOutput output(44100); //选择44Khz采样 76 77  CL_Surface *cursimg = new CL_Surface("cursor.tga"); 78  cursimg->set_alignment(origin_center); 79  CL_Surface *redpict = new CL_Surface("handtransp.tga"); 80  redpict->set_alignment(origin_center); 81  redpict->set_scale(float(spacing)/float(redpict->get_width()), 82  float(spacing)/float(redpict->get_height())); 83  CL_Surface *bluepict = new CL_Surface("circlehandtransp.tga"); 84  bluepict->set_alignment(origin_center); 85  bluepict->set_scale(float(spacing) / float(bluepict->get_width()), 86  float(spacing) / float(bluepict->get_height())); 87   这里的init()方法完成大部分的游戏初始化工作。当然,在此需要ClanLib子系统以用于处理图形和声音(行68-72),然后构建一个窗口用于显示所有的图形(行75)。   CL_Surface(行77-87)是一个2D位图类,用于绘制光标,用蓝色填充的方格和用红色填充的方格。   TGA文件是一种位图文件格式。ClanLib有一个集成的PNG库,因此它可以读写最流行的位图文件格式化。   下一步,你必须把板子初始化成一个空状态(行87-103)并执行类似的其它的清理工作以实现新的游戏计数器。 89 90 redturn = true; 91 curs.vert = false; 92 fullup = false; 93 curs.x = curs.y = 1; 94 95 srand(CL_System::get_time()); //启动随机数字生成器 96 97 for (int x = 0; x < boardsize - 1; x++) { 98  for (int y = 0; y < boardsize; y++) 99  hor[x][y] = ver[y][x] = false; 100 101  for (int y = 0; y < boardsize - 1; y++) 102   squares[x][y] = off; 103 104   ClanLib的一个非凡突出的方面是它避开传统型应用于许多框架中的回调模型,而引入了"信号和槽"模型。这种模型广泛应用于Boost C++库中,并在QT中得到实现。信号代表具有多个目标的回调函数,又在一些类似的系统中称作"出版者"或者"事件"。信号被连接到一些槽上,它们是回调函数接收器(也称作事件目标或者订户),当信号被"发出"时即被调用。信号具有类型安全的优点,它们避开了在传统型的框架中的不可避免的cast操作。   信号和槽被统一治理。在信号和槽中(或者更准确些说是,作为槽的一部分出现的对象)跟踪所有的连接,并当任何其一被破坏时能够自动地断开信号/槽连接。这能够使用户建立信号/槽连接而不需要花费多大的代价来治理那些连接以及所有包含于其中的对象的生命周期。在行105中,你只要捕捉所有的键击("down")事件并确保使用了你自己的inputHandler()(见行168-216)。 105 CL_Slot keyPRess = CL_Keyboard::sig_key_down().connect(this, &Boxes::inputHandler);   现在,你将开始初始化程序的音乐部分。首先,你用一个.wav格式的("binary")音乐文件装载一个CL_SoundBuffer,然后预备一个会话句柄以为玩游戏之用。下一步,你应用一个淡入淡出过滤器来异步地调整音量-在五秒(行 108-112)内把音量从零变化到最大音量的百分之六十。 106 CL_SoundBuffer *music = new CL_SoundBuffer("linemusic.ogg"); 107 CL_SoundBuffer_session session = music->prepare(); 108 CL_FadeFilter *fade = new CL_FadeFilter(0.0f); 109 session.add_filter(fade); 110 session.set_looping(true); 111 session.play(); 112 fade->fade_to_volume(0.6f, 5000); 113 }   drawBoard()方法绘制线段所在的点画格子图案,如,每个玩家赢得的红色的西红柿和蓝色的矢车菊框出的方格,还有模拟的光标。而最重要的代码行是第165行。CL_Display::flip()交换前后台缓冲区。后台缓冲区是在该帧中你绘制所有图形的地方,而前台缓冲区是显示在屏幕上的内容。 115 void Boxes::drawBoard() 116 { 117  CL_Display::clear(redturn ? CL_Color::red : CL_Color::blue); 118  CL_Display::fill_rect(CL_Rect(border/2, border/2, 119    winsize - border/2, winsize - border/2),CL_Color::black); 120 121  //画方框 122  for (int x = 0; x < boardsize - 1; x++) 123   for (int y = 0; y < boardsize - 1; y++) { 124    if (squares[x][y] == red) { 125     CL_Display::fill_rect(CL_Rect(x * spacing + border,y * spacing + border, x * spacing + border +         spacing, 127       y * spacing + border + spacing),CL_Gradient(CL_Color::red, 128       CL_Color::red, CL_Color::tomato, CL_Color::tomato)); 129     redpict->draw(x * spacing + border + spacing / 2, 130        y * spacing + border + spacing / 2); 131    } 132    else if (squares[x][y] == blue) { 133      CL_Display::fill_rect(CL_Rect(x * spacing + border, 134      y * spacing + border,x * spacing + border +spacing, 135        y * spacing + border +spacing),CL_Gradient(CL_Color::blue, 136        CL_Color::blue, CL_Color::cornflowerblue,CL_Color::cornflowerblue)); 137      bluepict->draw(x * spacing + border + spacing / 2,y * spacing + border + spacing / 2); 139    } 140   } 141 142   //画线 143   for (int x = 0; x < boardsize; x++) { 144    for (int y = 0; y < boardsize - 1; y++) { 145     if (ver[x][y]) CL_Display::draw_line(x * spacing + border, 146       y * spacing + border,x * spacing + border, 147       y * spacing + border+ spacing,CL_Color::yellow); 148     if (hor[y][x]) CL_Display::draw_line(y * spacing + border, 149       x * spacing + border,y * spacing + border+ spacing,x * spacing + border,CL_Color::yellow); 151     } 152   } 153 154   //画格子 155   for (int x = 0; x < boardsize; x++) 156    for (int y = 0; y < boardsize; y++) 157     CL_Display::draw_rect(CL_Rect(x * spacing + border, 158       y * spacing + border,x * spacing + border + 2,159 y * spacing + border + 2),CL_Color::white); 160 161     //画光标 162     if (curs.vert) cursimg->draw((curs.x - 1) * spacing + border,int((curs.y - 0.5) * spacing + border)); 163     else cursimg->draw(int((curs.x - 0.5) * spacing + border),(curs.y - 1) * spacing + border); 164 165      CL_Display::flip(); 166    }   你安装的inputHandler()函数用于观察在行105的按键信号。这个函数负责处理细节问题-把键击变成游戏运动,还有最重要的空格或者回车键-用于指示当前玩家的一个选择(行200-210)。然后,你要检查一下是否已完成了一个"方形"并把控制返回到原来的玩家。 168 void Boxes::inputHandler(const CL_InputEvent &i) 169 { 170  if (redturn) { 171   switch(i.id) { 172    case CL_KEY_LEFT: 173    case CL_KEY_G: 174     if (curs.x > 1) curs.x--; 175     break; 176    case CL_KEY_RIGHT: 177    case CL_KEY_J: 178     if (curs.x < boardsize) curs.x++; 179     break; 180    case CL_KEY_UP: 181    case CL_KEY_Y: 182     if (!curs.vert && curs.y > 1) { 183      curs.y--; 184      curs.vert = !curs.vert; 185     } 186     else if (curs.vert) curs.vert = false; 187     break; 188    case CL_KEY_DOWN: 189    case CL_KEY_H: 190     if (curs.vert && curs.y < boardsize) { 191      curs.y++; 192      curs.vert = !curs.vert; 193     } 194     else if (!curs.vert) curs.vert = true; 195     break; 196    } 197    if (curs.x == boardsize && !curs.vert) curs.x--; 198    if (curs.y == boardsize && curs.vert)       curs.vert = false; 199 200    if (i.id == CL_KEY_SPACE i.id == CL_KEY_ENTER) { 201     if (curs.vert) { 202      if (!ver[curs.x-1][curs.y-1]) { 203       ver[curs.x-1][curs.y-1] = true; 204       if (!findsquares()) redturn = !redturn; 205      } 206    } 207    else { 208     if (!hor[curs.x-1][curs.y-1]) { 209      hor[curs.x-1][curs.y-1] = true; 210      if (!findsquares()) redturn = !redturn; 211     } 212    } 213   } 214  } 215 }   最后,由endOfGame()方法计算最后的得分。记住游戏还没有结束,直到板子满了为止(见行48)或者某人通过按下ESC键(见行46)退出。最后,你用大约1秒的时间把音量淡出到0。 217 void Boxes::endOfGame() 218 { 219  // 计数得分 220  int redscore, bluescore; 221  redscore = bluescore = 0; 222  for (int x = 0; x < boardsize - 1; x++) 223   for (int y = 0; y < boardsize - 1; y++) { 224    if (squares[x][y] == red) redscore++; 225    else if (squares[x][y] == blue) bluescore++; 226   } 227 228  cout << "Red: " << redscore << "\nBlue: " << bluescore << endl; 229  if (bluescore != redscore) 230   cout << (bluescore > redscore ? "Blue" : "Red") << " player wins\n"; 231  else cout << "It was a tie\n"; 232 233  if (fullup) { 234   fade->fade_to_volume(0.0f, 1000); 235   CL_System::sleep(1000); 236  } 237 }
󰈣󰈤
 
 
 
>>返回首页<<
 
 
 转载本文
 UBB代码 HTML代码
复制到剪贴板...
 
 热帖排行
 
 
王朝网络微信公众号
微信扫码关注本站公众号wangchaonetcn
 
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
©2005- 王朝网络 版权所有