There's tons of inline comments, please read them to learn things.
00001 /* 00002 GLICT - Graphics Library Interface Creation Toolkit 00003 Copyright (C) 2006 OBJECT Networks 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public 00016 License along with this library; if not, write to the Free 00017 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00027 // GLICTMemory 00028 // simple game made with GLICT 00029 // to compile you'll need GLUT 00030 00031 // GLUT includes 00032 // we use glut because it's cross platform compatible 00033 // for mac os x, use <OpenGL/glut.h> if i remember correclty 00034 #include <GL/glut.h> 00035 00036 // GLICT includes 00037 // following includes should, in your project, actually look a 00038 // bit different 00039 // this project, as it is, should be placed inside the GLICT's folder so 00040 // its includes is relative 00041 #include <GLICT/container.h> 00042 #include <GLICT/button.h> 00043 #include <GLICT/globals.h> 00044 #include <GLICT/window.h> 00045 #include <GLICT/panel.h> 00046 #include <GLICT/messagebox.h> 00047 #include <GLICT/fonts.h> 00048 #include "glut-helper.h" 00049 // some nice strings for the cards... ;) 00050 char cardtitles[16][16] = { "Gecko", "Smygflik", "mips", "the fike", "Pekay", "Yorick", "tliff", "SimOne"}; 00051 // and some colors for the cards 00052 float cardcolor[16][3] = { { 1., 0., 0.}, { 0., 0., .9 }, {.8, .8, 0.}, {.7, 0., .7}, 00053 {0., .85, 0.}, { .55, 0., 0. }, {0., 75., .75}, {.5, 1., .5}}; 00054 // other game related vars 00055 char matrix[16]; // matrix specifies where is each card 00056 char taken[16]; // taken specifies if we've used a card in generation, so we dont generate same pair again 00057 char solved[16]; // solved specifies if a piece has been solved 00058 char flipd[2]; // which cards are currently flipped 00059 00060 00061 int totalsolved = 0, totalopens = 0; 00062 00063 glictContainer desktop; 00064 glictWindow window; 00065 glictButton cards[16]; 00066 glictPanel pnlSolveds; 00067 glictMessageBox* msgSuccess; 00068 int windowhandle; // glut's window identifier 00069 00070 // displays stuff, glut's way of doing stuff 00071 void display() { 00072 00073 // make sure the stenciltest is off before clearing 00074 // in this example we're sure so we dont enforce it 00075 glClearColor(0.0,0.0,0.0,0.0); 00076 glClear(GL_COLOR_BUFFER_BIT); 00077 00078 00079 // below's the sample of glict render 00080 // you can practically copypaste for a simple program 00081 // prepare for render; set up tests 00082 glEnable(GL_STENCIL_TEST); // so clipping works 00083 glDisable(GL_DEPTH_TEST); // depth is not important to us 00084 00085 // make sure we're in modelview matrix mode 00086 glMatrixMode(GL_MODELVIEW); 00087 // and reset the modelview matrix 00088 // that step is not important and in this example just more than unnecessary 00089 // so you can delete it if you want (just like the above glMatrixMode thing) 00090 glLoadIdentity(); 00091 00092 // render it up 00093 desktop.Paint(); 00094 00095 // note: glict pops every matrix it pushes 00096 // and undoes every transformation it does 00097 // so dont worry about that 00098 00099 // now disable glstenciltest at the end 00100 // we dont put it up because we disabled it here 00101 // well, we disable it here because we might need it disabled... blah 00102 glDisable(GL_STENCIL_TEST); 00103 00104 // make glut render it 00105 glutSwapBuffers(); 00106 } 00107 00108 // glut's way of telling program that window size changed 00109 void reshape(int x, int y) { 00110 glMatrixMode(GL_PROJECTION); 00111 glLoadIdentity(); 00112 glViewport(0,0,x,y); 00113 gluOrtho2D(0,x,0,y); 00114 00115 // we rotate the entire coordinate sys because we use system opposite to GL's 00116 // (just flipped) 00117 // we do that for projection matrix so modelview can be reset whenever we want 00118 glRotatef(180., 1., 0., 0.); 00119 glTranslatef(0,-y,0.0); 00120 00121 glMatrixMode(GL_MODELVIEW); 00122 00123 00124 // set desktop's width and height to what we got 00125 desktop.SetWidth(x); 00126 desktop.SetHeight(y); 00127 00128 window.SetWidth(96*4); 00129 window.SetHeight(96*4); 00130 00131 window.SetPos(x/2-96*2, y/2-96*2); 00132 00133 00134 glutPostRedisplay(); 00135 } 00136 00137 // glut's way of telling us a mouse-press event happened 00138 void mouse(int button, int shift, int mousex, int mousey) { 00139 glictPos pos; 00140 pos.x = mousex; pos.y = mousey; 00141 00142 if (shift==GLUT_DOWN) desktop.CastEvent(GLICT_MOUSEDOWN, &pos, 0); 00143 if (shift==GLUT_UP) desktop.CastEvent(GLICT_MOUSEUP, &pos, 0); 00144 glutPostRedisplay(); 00145 } 00146 00147 00148 00149 // this happens when msgbox is dismissed; serves for memory cleanup 00150 void OnDismissSuccess (glictPos* relmousepos, glictContainer* caller) { 00151 delete caller; 00152 } 00153 00154 00155 // CardOnClick is executed upon click on a card with mouse 00156 // we'll identify which card is used by pointer difference 00157 void CardOnClick(glictPos* relmousepos, glictContainer* callerclass) { 00158 glictButton *button = dynamic_cast<glictButton*>(callerclass); 00159 int cardclicked = button - cards; 00160 //char c[256]; 00161 //sprintf(c, "%d", cardclicked); 00162 00163 00164 glutSetWindowTitle("GLICTMemory"); 00165 00166 00167 if (flipd[1]!=-1 ) { 00168 00169 if (!solved[flipd[0]]) { 00170 char tmp[16]; 00171 sprintf(tmp, "%d", flipd[0]); cards[flipd[0]].SetCaption(tmp); cards[flipd[0]].SetBGColor(0.5, 0.5, 0.5, 1.); 00172 sprintf(tmp, "%d", flipd[1]); cards[flipd[1]].SetCaption(tmp); cards[flipd[1]].SetBGColor(0.5, 0.5, 0.5, 1.); 00173 00174 } 00175 flipd[0]=-1; 00176 flipd[1]=-1; 00177 00178 } 00179 00180 if (solved[cardclicked]) { 00181 glutSetWindowTitle("GLICTMemory - Card's been solved already."); 00182 return; 00183 } 00184 00185 if (flipd[0]!=-1 && cardclicked==flipd[0]) { 00186 return; 00187 } 00188 00189 00190 button->SetCaption(cardtitles[matrix[cardclicked]]); 00191 button->SetBGColor(cardcolor[matrix[cardclicked]][0], cardcolor[matrix[cardclicked]][1], cardcolor[matrix[cardclicked]][2], 1.); 00192 if (flipd[0]==-1) flipd[0]=cardclicked; else { 00193 flipd[1]=cardclicked; 00194 00195 00196 totalopens++; 00197 if (matrix[flipd[0]] == matrix[flipd[1]]) { 00198 glutSetWindowTitle("GLICTMemory - Correct!"); 00199 solved[flipd[0]] = 1; 00200 solved[flipd[1]] = 1; 00201 totalsolved++; 00202 00203 if (totalsolved == 8) { 00204 msgSuccess = new glictMessageBox; 00205 msgSuccess->SetOnDismiss(OnDismissSuccess); 00206 msgSuccess->SetCaption("Congrats!"); 00207 msgSuccess->SetMessage("You've solved the game!"); 00208 msgSuccess->SetPos(32,32); 00209 window.AddObject(msgSuccess); 00210 00211 } 00212 } else { 00213 glutSetWindowTitle("GLICTMemory - Wrong!"); 00214 } 00215 } 00216 00217 00218 char solveds[256]; 00219 sprintf(solveds, "Solved: %d\nOpens: %d", totalsolved, totalopens); 00220 pnlSolveds.SetCaption(solveds); 00221 glutPostRedisplay(); 00222 } 00223 00224 00225 // game related, board generation function 00226 void generate() { 00227 bool gen; 00228 int x,y; 00229 srand(time(NULL)); 00230 for (int i=0;i<16;i++) taken[i]=false; 00231 for (int i=0;i<8;i++) { 00232 gen=false; 00233 while (!gen) { 00234 x = (int)(rand() / (float)RAND_MAX * (float)16); 00235 if (!taken[x]) {taken[x]=true; matrix[x]=i; gen=true;} 00236 } 00237 00238 gen=false; 00239 while (!gen) { 00240 x = (int)(rand() / (float)RAND_MAX * (float)16); 00241 if (!taken[x]) {taken[x]=true; matrix[x]=i; gen=true;} 00242 00243 } 00244 } 00245 flipd[0]=-1; 00246 flipd[1]=-1; 00247 } 00248 // MainWidgets initializes the widgets on main screen 00249 void MainWidgets() { 00250 generate(); 00251 window.SetCaption("Board"); 00252 desktop.AddObject(&window); 00253 00254 for (int i=0; i<16;i++) { 00255 00256 cards[i].SetPos((i % 4) * 96, (i / 4) * 96); 00257 cards[i].SetWidth(96); 00258 cards[i].SetHeight(96); 00259 cards[i].SetBGColor(0.5, 0.5, 0.5, 1.); 00260 00261 char tmp[3]; 00262 sprintf(tmp,"%d", i); 00263 cards[i].SetCaption(tmp); 00264 cards[i].SetOnClick(CardOnClick); 00265 00266 window.AddObject(&cards[i]); 00267 } 00268 00269 desktop.AddObject(&pnlSolveds); 00270 pnlSolveds.SetCaption("Solved: 0\nOpens: 0"); 00271 pnlSolveds.SetBGColor(0.,0.,0.,1.); 00272 pnlSolveds.SetWidth(100); 00273 } 00274 00275 00276 00277 // the main function initializes everything 00278 int main(int argc, char** argv) { 00279 00280 glutInit(&argc, argv); 00281 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL); 00282 glutInitWindowSize (640, 480); 00283 glutInitWindowPosition (0, 0); 00284 00285 windowhandle = glutCreateWindow ("GLICTMemory"); 00286 00287 MainWidgets(); 00288 00289 glictFont* sysfont = glictCreateFont("system"); 00290 sysfont->SetFontParam(GLUT_STROKE_MONO_ROMAN); 00291 sysfont->SetRenderFunc(glutxStrokeString); 00292 sysfont->SetSizeFunc(glutxStrokeSize); 00293 00294 00295 00296 glutDisplayFunc(display); 00297 glutReshapeFunc(reshape); 00298 glutMouseFunc(mouse); 00299 00300 00301 glutSetWindow(windowhandle); 00302 glutShowWindow(); 00303 00304 00305 glutMainLoop(); 00306 return 0; 00307 }