Cross-Platform Game Development for C++ Developers, Part IV: ClanLib SDK
ClanLib is a cross-platform C++ framework focused primarily on the needs of game developers. Although the API is streamlined for gaming, you could easily use ClanLib to develop a scientific 3D visualization tool or multimedia application (such as the Gecko Multimedia System).
ClanLib has APIs for 2D and 3D graphics, sound, network, I/O, input, and GUI and resource administration. It provides transparent support for OpenGL, so you can use native OpenGL commands while letting ClanLib handle the OS-dependent window management and everything else. ClanLib renders 2D graphics through DirectX or Simple Direct Media Layer (a platform-independent multimedia library). The ClanLib games page lists about 50 well-developed games, including puzzles, strategy, and shooter games in 2D and 3D. For example, Asteroid Arena (see Figure 1) uses ClanLib and OpenGL to one-up the arcade classic.
Figure 1. Screenshot of Asteroid Arena
ClanLib works on Windows, Linux, and MacOS and is supplied in source-only zip or tar files. Windows developers can use Microsoft Visual Studio, Borland C++, or MinGW (Minimalist GNU for Windows) compilers and environments. Third-party support for Ruby and Perl language bindings is also available. Optional extras include a Lua plug-in (the popular lightweight scripting language) and FreeType (a free TrueType font library).
Inside the ClanLib Feature Set
Before digging into the API, take a quick glance at its major features:
- Basic cross-platform runtime (GUI, threading, file I/O, and so forth)
- Template-based C++ signal/slots library (type-safe callbacks/delegates)
- Integrated resource management
- Sound mixer supporting .WAV files, Ogg Vorbis, and anything supported by the MikMod library (MOD, S3M, XM, and so on)
- Document Object Model (DOM) XML parser support
- High-level 2D graphics API supporting OpenGL, DirectX, and SDL as render targets
- Batch rendering engine for best performance when rendering 2D with OpenGL
- 2D collision detection
- 2D sprite animation support
- Highly customizable GUI framework
- Network library with low- to high-level interfaces
The Basic Gaming Model of ClanLib
Now, examine the ClanLib API model from the inside out. I've always found that the best tutorial is a fully explained example program. Specifically, you'll look inside Luke Worth's boxes, an electronic version of the two-player, paper-and-pencil game (see Figure 2). The boxes game consists of a grid of points between which players alternately draw lines. Whoever encloses a square with the final line, scores one point and gets to play another turn. (If you're eager to see the API reference first, by all means do so.)
Figure 2. A Boxes Game in Progress with a Score of Blue 8 and Red 3
I purposely kept the main program as short as possible to better highlight the "game loop:"
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 }

Comments
There are no comments yet. Be the first to comment!