AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > C++

C++跨平台游戏开发之ClanLib SDK

51自学网 http://www.wanshiok.com

  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 }

 
 

上一篇:C++箴言:接口继承和实现继承  下一篇:Bjarne:有了qsort()为何还要sort()?