follow my heart...
分类:
2006-11-26 19:27:43
一、 简介
ClanLib是一个主要针对游戏开发者的跨平台C++框架。尽管API主要为游戏开发设计,你照样可以容易地使用ClanLib来开发一个科学的3D可视化工具或多媒体应用程序(例如Gecko多媒体系统)。
ClanLib拥有各种API-2D和3D图形,声音,网络,I/O,输入,以及资源管理。它还提供透明的OpenGL支持,因此你可以使用本机OpenGL命令而让ClanLib处理依赖于操作系统的窗口管理和其它一切事情。ClanLib通过DirectX或简单的Direct Media Layer(一平台独立的多)生成2D图形。ClanLib游戏主页上列举了约50多个开发非常成功的游戏,包括以2D和3D形式完成的难题、策略以及射手类游戏。例如,Asteroid Arena(见图1)使用了ClanLib和OpenGL技术,实现了胜人一筹的经典街机游戏。
图1.Asteroid Arena屏幕快照 |
图2.一个进行中的盒子游戏,得分情况是蓝8/红3 |
1 #i nclude 2 #i nclude 3 #i nclude 4 #i nclude 5 #i nclude 6 #i nclude 7 #i nclude 8 9 const int boardsize = 6, spacing = 50, border = 20; 10 const int numsquares = int(pow(float(boardsize - 1), 2)); 11 12 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_::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 } |
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 |
89 90 redturn = true; 91 curs.vert = false; 92 fullup = false; 93 curs.x = curs.y = 1; 94 95 srand(CL_System::get_()); //启动随机数字生成器 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 |
105 CL_Slot keypress = CL_Keyboard::sig_key_down().connect(this, &Boxes::inputHandler); |
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 } |
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 } |
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 } |
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 } |