PTdecode/CImg-1.3.0/examples/odykill.cpp

Mon, 03 Aug 2009 23:41:04 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Mon, 03 Aug 2009 23:41:04 +0100
changeset 11
69416826d18c
parent 5
1204ebf9340d
permissions
-rwxr-xr-x

added dep/*.d and obj/*.o to hgignore

philpem@5 1 /*
philpem@5 2 #
philpem@5 3 # File : odykill.cpp
philpem@5 4 # ( C++ source file )
philpem@5 5 #
philpem@5 6 # Description : Simple shoot-em-up game featuring the Robotvis/Odyssee Team !
philpem@5 7 # This file is a part of the CImg Library project.
philpem@5 8 # ( http://cimg.sourceforge.net )
philpem@5 9 #
philpem@5 10 # Copyright : David Tschumperle
philpem@5 11 # ( http://www.greyc.ensicaen.fr/~dtschump/ )
philpem@5 12 #
philpem@5 13 # License : CeCILL v2.0
philpem@5 14 # ( http://www.cecill.info/licences/Licence_CeCILL_V2-en.html )
philpem@5 15 #
philpem@5 16 # This software is governed by the CeCILL license under French law and
philpem@5 17 # abiding by the rules of distribution of free software. You can use,
philpem@5 18 # modify and/ or redistribute the software under the terms of the CeCILL
philpem@5 19 # license as circulated by CEA, CNRS and INRIA at the following URL
philpem@5 20 # "http://www.cecill.info".
philpem@5 21 #
philpem@5 22 # As a counterpart to the access to the source code and rights to copy,
philpem@5 23 # modify and redistribute granted by the license, users are provided only
philpem@5 24 # with a limited warranty and the software's author, the holder of the
philpem@5 25 # economic rights, and the successive licensors have only limited
philpem@5 26 # liability.
philpem@5 27 #
philpem@5 28 # In this respect, the user's attention is drawn to the risks associated
philpem@5 29 # with loading, using, modifying and/or developing or reproducing the
philpem@5 30 # software by the user in light of its specific status of free software,
philpem@5 31 # that may mean that it is complicated to manipulate, and that also
philpem@5 32 # therefore means that it is reserved for developers and experienced
philpem@5 33 # professionals having in-depth computer knowledge. Users are therefore
philpem@5 34 # encouraged to load and test the software's suitability as regards their
philpem@5 35 # requirements in conditions enabling the security of their systems and/or
philpem@5 36 # data to be ensured and, more generally, to use and operate it in the
philpem@5 37 # same conditions as regards security.
philpem@5 38 #
philpem@5 39 # The fact that you are presently reading this means that you have had
philpem@5 40 # knowledge of the CeCILL license and that you accept its terms.
philpem@5 41 #
philpem@5 42 */
philpem@5 43
philpem@5 44 #include "img/odykill.h"
philpem@5 45 #include "CImg.h"
philpem@5 46 using namespace cimg_library;
philpem@5 47
philpem@5 48 // The lines below are necessary when using a non-standard compiler as visualcpp6.
philpem@5 49 #ifdef cimg_use_visualcpp6
philpem@5 50 #define std
philpem@5 51 #endif
philpem@5 52 #ifdef min
philpem@5 53 #undef min
philpem@5 54 #undef max
philpem@5 55 #endif
philpem@5 56
philpem@5 57 int main(int argc,char **argv) {
philpem@5 58
philpem@5 59 // Create game graphics
philpem@5 60 CImg<unsigned char> graphics[21] = {
philpem@5 61 CImg<unsigned char>(data_tomato,100,100,1,3,false),
philpem@5 62 CImg<unsigned char>(data_heart,100,100,1,3,false),
philpem@5 63 CImg<unsigned char>(data_dynamite,100,100,1,3,false),
philpem@5 64 CImg<unsigned char>(data_brain,100,100,1,3,false),
philpem@5 65 CImg<unsigned char>(data_cdrom,100,100,1,3,false),
philpem@5 66 CImg<unsigned char>(data_enemy,113,150,1,3,false),
philpem@5 67 CImg<unsigned char>(data_enemy2,116,155,1,3,false),
philpem@5 68 CImg<unsigned char>(data_enemy3,104,134,1,3,false),
philpem@5 69 CImg<unsigned char>(data_enemy4,141,151,1,3,false),
philpem@5 70 CImg<unsigned char>(data_enemy5,140,152,1,3,false),
philpem@5 71 CImg<unsigned char>(data_enemy6,131,156,1,3,false),
philpem@5 72 CImg<unsigned char>(data_enemy7,114,125,1,3,false),
philpem@5 73 CImg<unsigned char>(data_enemy8,97,125,1,3,false),
philpem@5 74 CImg<unsigned char>(data_enemy9,143,134,1,3,false),
philpem@5 75 CImg<unsigned char>(data_enemy10,158,214,1,3,false),
philpem@5 76 CImg<unsigned char>(data_enemy11,131,168,1,3,false),
philpem@5 77 CImg<unsigned char>(data_enemy12,114,138,1,3,false),
philpem@5 78 CImg<unsigned char>(data_enemy13,144,144,1,3,false),
philpem@5 79 CImg<unsigned char>(data_enemy14,132,153,1,3,false),
philpem@5 80 CImg<unsigned char>(data_enemy15,152,151,1,3,false),
philpem@5 81 CImg<unsigned char>(data_enemy16,139,185,1,3,false),
philpem@5 82 };
philpem@5 83 CImg<> masks[21];
philpem@5 84 const unsigned char black[] = { 0,0,0 }, white[] = { 255,255,255 };
philpem@5 85
philpem@5 86 // Display weapon selection menu
philpem@5 87 CImg<unsigned char> back0(640,480,1,3), title(data_title,294,94,1,3,true), choose(data_choose,524,49,1,3,true);
philpem@5 88 back0.fill(0).draw_image(back0.dimx()/2-title.dimx()/2,30,title).draw_image(back0.dimx()/2-choose.dimx()/2,150,choose);
philpem@5 89 CImgDisplay disp(back0,"OdyKill");
philpem@5 90 int weapon=-1;
philpem@5 91
philpem@5 92 while (!disp.is_closed && !disp.button) {
philpem@5 93 weapon = -1;
philpem@5 94 for (int k=0; k<5; k++) {
philpem@5 95 const int mx = disp.mouse_x, my = disp.mouse_y;
philpem@5 96 if (!((mx-40)/110==k && my>250 && my<350)) back0.draw_image(40+k*110,250,graphics[k]/2.0);
philpem@5 97 else back0.draw_image(40+k*110,250,graphics[weapon=k]);
philpem@5 98 }
philpem@5 99 CImg<unsigned char> tmp = CImg<unsigned char>().draw_text(0,0,
philpem@5 100 weapon==0?" Tomato ":
philpem@5 101 weapon==1?" Heart ":
philpem@5 102 weapon==2?" Dynamite ":
philpem@5 103 weapon==3?" Brain ":
philpem@5 104 weapon==4?" CD-Rom ":
philpem@5 105 " ",white,black,1,32).resize(-100,-100,1,1),
philpem@5 106 tmp2 = tmp.get_blur(6).normalize(0,255).draw_image(tmp,0.5f);
philpem@5 107 { cimg_forV(back0,k) back0.draw_image(250,390,0,k,tmp2); }
philpem@5 108
philpem@5 109 disp.resize(disp).display(back0).wait();
philpem@5 110 if (disp.is_keyCTRLLEFT && disp.key==cimg::keyF) disp.toggle_fullscreen();
philpem@5 111 if (disp.is_closed || disp.is_keyQ || disp.is_keyESC) std::exit(0);
philpem@5 112 }
philpem@5 113 disp.hide_mouse();
philpem@5 114
philpem@5 115 /*---------------------------------
philpem@5 116
philpem@5 117 Go !
philpem@5 118
philpem@5 119 --------------------------------*/
philpem@5 120
philpem@5 121 const CImg<unsigned char>
philpem@5 122 background = CImg<unsigned char>(100,100,1,3,0).noise(100,2).draw_plasma(0,0,99,99).
philpem@5 123 resize(back0.dimx(),back0.dimy(),1,3,5)/2.5;
philpem@5 124 { for (unsigned int k=0; k<21; k++) {
philpem@5 125 CImg<> tmp = graphics[k].resize(k<5?32:164,k<5?32:164,1,3);
philpem@5 126 cimg_forXY(tmp,x,y) tmp(x,y) = (tmp(x,y,0)==255 && tmp(x,y,1)==255 && tmp(x,y,2)==255)?0.0f:1.0f;
philpem@5 127 masks[k]=tmp.get_shared_channel(0);
philpem@5 128 graphics[k].resize(k<5?32:164,k<5?32:164,1,3,5);
philpem@5 129 }}
philpem@5 130
philpem@5 131 CImg<unsigned char> canvas(background);
philpem@5 132 int n = 5+((int)(200*cimg::rand())%16);
philpem@5 133 CImg<unsigned char> tomato = graphics[weapon], enemy = graphics[n];
philpem@5 134 CImg<> m_tomato = masks[weapon], m_enemy = masks[n];
philpem@5 135
philpem@5 136 double angle=0;
philpem@5 137 int tomato_x=0,tomato_y=0,shooted=0;
philpem@5 138 double enemy_x=-1000, enemy_y=-1000, enemy_z=-1000, tomato_z = 0, vx = 0, vy = 0, vz = 0, va = 0;
philpem@5 139 double speed = cimg_option("-speed",5.0,"Speed");
philpem@5 140 int timeleft = 2000, score = 0;
philpem@5 141 CImg<unsigned char> r_enemy;
philpem@5 142
philpem@5 143 // Main loop
philpem@5 144 while(timeleft && !disp.is_closed && !disp.is_keyESC && !disp.is_keyQ) {
philpem@5 145 timeleft--;
philpem@5 146 const int mx = disp.mouse_x*back0.dimx()/disp.dimx(), my = disp.mouse_y*back0.dimy()/disp.dimy();
philpem@5 147
philpem@5 148 // Handle object motion
philpem@5 149 if (tomato_z>0) {
philpem@5 150 tomato_z+=0.07; tomato_y -= (int)(20*std::cos(cimg::valuePI/7 + tomato_z*cimg::valuePI));
philpem@5 151 if (tomato_z>=1) { tomato_z=0; tomato_x = mx; tomato_y = my; }
philpem@5 152 }
philpem@5 153 if (!shooted) {
philpem@5 154 enemy_x +=vx;
philpem@5 155 enemy_y +=vy;
philpem@5 156 enemy_z +=vz;
philpem@5 157 }
philpem@5 158 else {
philpem@5 159 va = 10;
philpem@5 160 enemy_y += vy;
philpem@5 161 vy += 2;
philpem@5 162 tomato_z = 0;
philpem@5 163 if (enemy_y>5*canvas.dimy()/4) {
philpem@5 164 shooted = 0;
philpem@5 165 int n = 5 + ((int)(200*cimg::rand())%16);
philpem@5 166 enemy = graphics[n];
philpem@5 167 m_enemy = masks[n];
philpem@5 168 enemy_x=cimg::crand()*1e8; enemy_y=cimg::crand()*1e8; enemy_z=cimg::crand()*1e8;
philpem@5 169 va = angle = 0;
philpem@5 170 }
philpem@5 171 }
philpem@5 172
philpem@5 173 if (enemy_x<0) { enemy_x=0; vx = speed*cimg::crand(); }
philpem@5 174 if (enemy_x>canvas.dimx()) { enemy_x=canvas.dimx(); vx = speed*cimg::crand(); }
philpem@5 175 if (enemy_y<0) { enemy_y=0; vy = speed*cimg::crand(); }
philpem@5 176 if (!shooted && enemy_y>canvas.dimy()) { enemy_y=canvas.dimy(); vy = speed*cimg::crand(); }
philpem@5 177 if (enemy_z<0.1) { enemy_z = 0.1; vz = speed*0.01*cimg::crand(); }
philpem@5 178 if (enemy_z>0.7) { enemy_z = 0.7; vz = speed*0.01*cimg::crand(); }
philpem@5 179 angle+=va;
philpem@5 180
philpem@5 181 // Handle mouse interaction
philpem@5 182 if (!disp.button) {
philpem@5 183 if (tomato_z==0) {
philpem@5 184 tomato_x = mx; tomato_y = my;
philpem@5 185 }
philpem@5 186 } else tomato_z +=0.0001;
philpem@5 187
philpem@5 188 // Detect shooting
philpem@5 189 if (cimg::abs(tomato_z-enemy_z)<0.1) {
philpem@5 190 if (tomato_x>enemy_x-r_enemy.dimx()/2 && tomato_x<enemy_x+r_enemy.dimx()/2 &&
philpem@5 191 tomato_y>enemy_y-r_enemy.dimy()/2 && tomato_y<enemy_y+r_enemy.dimy()/2) {
philpem@5 192 score++;
philpem@5 193 shooted = 1;
philpem@5 194 }
philpem@5 195 }
philpem@5 196
philpem@5 197 // Draw into canvas
philpem@5 198 canvas = background;
philpem@5 199 r_enemy = enemy.get_resize((int)(8+enemy.dimx()*(1-enemy_z)),(int)(8+enemy.dimy()*(1-enemy_z)),-100,-100);
philpem@5 200 CImg<> rm_enemy = m_enemy.get_resize(r_enemy.dimx(),r_enemy.dimy());
philpem@5 201 CImg<unsigned char> r_tomato = tomato.get_resize((int)(8+tomato.dimx()*(1-tomato_z)),(int)(8+tomato.dimy()*(1-tomato_z)),-100,-100);
philpem@5 202 CImg<> rm_tomato = m_tomato.get_resize(r_tomato.dimx(),r_tomato.dimy());
philpem@5 203
philpem@5 204 if (angle!=0) { r_enemy.rotate((float)angle,0,0); rm_enemy.rotate((float)angle,0,0); cimg_forXY(r_enemy,x,y) r_enemy(x,y,0) = (r_enemy(x,y,0)+255)/2; }
philpem@5 205 r_enemy*=(1-(enemy_z-0.1)/1.6);
philpem@5 206 r_tomato*=(1-tomato_z/1.6);
philpem@5 207 rm_enemy*=(1-(enemy_z-0.1)/1.6);
philpem@5 208
philpem@5 209 if (enemy_z>tomato_z) {
philpem@5 210 canvas.draw_image((int)(enemy_x - r_enemy.dimx()/2),
philpem@5 211 (int)(enemy_y - r_enemy.dimy()/2),
philpem@5 212 r_enemy,rm_enemy);
philpem@5 213 if (tomato_x>=0) canvas.draw_image(tomato_x - r_tomato.dimx()/2,
philpem@5 214 tomato_y - r_tomato.dimy()/2,
philpem@5 215 r_tomato,rm_tomato);
philpem@5 216 }
philpem@5 217 else {
philpem@5 218 if (tomato_x>=0) canvas.draw_image(tomato_x - r_tomato.dimx()/2,
philpem@5 219 tomato_y - r_tomato.dimy()/2,
philpem@5 220 r_tomato,rm_tomato);
philpem@5 221 canvas.draw_image((int)(enemy_x - r_enemy.dimx()/2),
philpem@5 222 (int)(enemy_y - r_enemy.dimy()/2),
philpem@5 223 r_enemy,rm_enemy);
philpem@5 224 }
philpem@5 225 canvas.draw_text(1,1," Time left %d, Score = %d",white,0,0.5f,24,timeleft,score);
philpem@5 226 disp.resize(disp).display(canvas).wait(25);
philpem@5 227 if (disp.is_key(cimg::keyCTRLLEFT,cimg::keyF,true)) disp.toggle_fullscreen();
philpem@5 228 }
philpem@5 229
philpem@5 230 std::fprintf(stderr,"\n\n YOUR SCORE : %d\n\n\n",score);
philpem@5 231
philpem@5 232 return 0;
philpem@5 233 }