asteroids.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:8k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /* Copyright (c) Mark J. Kilgard, 1997, 1998. */
  2. /* This program is freely distributable without licensing fees
  3.    and is provided without guarantee or warrantee expressed or
  4.    implied. This program is -not- in the public domain. */
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <math.h>
  9. #include <GL/glut.h>
  10. /* Some <math.h> files do not define M_PI... */
  11. #ifndef M_PI
  12. #define M_PI 3.14159265358979323846
  13. #endif
  14. void initWindow(void);
  15. float angle = 0.0;
  16. int left, right;
  17. int leftTime, rightTime;
  18. int thrust, thrustTime;
  19. int joyThrust = 0, joyLeft = 0, joyRight = 0;
  20. float x = 20, y = 20, xv, yv, v;
  21. int shield = 0, joyShield = 0, cursor = 1;
  22. int lastTime;
  23. int paused = 0;
  24. int resuming = 1;
  25. int originalWindow = 0, currentWindow;
  26. typedef struct {
  27.   int inuse;
  28.   float x;
  29.   float y;
  30.   float v;
  31.   float xv;
  32.   float yv;
  33.   int expire;
  34. } Bullet;
  35. #define MAX_BULLETS 10
  36. Bullet bullet[MAX_BULLETS];
  37. int
  38. allocBullet(void)
  39. {
  40.   int i;
  41.   for (i=0; i<MAX_BULLETS; i++) {
  42.     if (!bullet[i].inuse) {
  43.       return i;
  44.     }
  45.   }
  46.   return -1;
  47. }
  48. void
  49. initBullet(int i, int time)
  50. {
  51.   float c = cos(angle*M_PI/180.0);
  52.   float s = sin(angle*M_PI/180.0);
  53.   bullet[i].inuse = 1;
  54.   bullet[i].x = x + 2 * c;
  55.   bullet[i].y = y + 2 * s;
  56.   bullet[i].v = 0.025;
  57.   bullet[i].xv = xv + c * bullet[i].v;
  58.   bullet[i].yv = yv + s * bullet[i].v;
  59.   bullet[i].expire = time + 1000;
  60. }
  61. void
  62. advanceBullets(int delta, int time)
  63. {
  64.   int i;
  65.   for (i=0; i<MAX_BULLETS; i++) {
  66.     if (bullet[i].inuse) {
  67.       float x, y;
  68.       if (time > bullet[i].expire) {
  69. bullet[i].inuse = 0;
  70. continue;
  71.       }
  72.       x = bullet[i].x + bullet[i].xv * delta;
  73.       y = bullet[i].y + bullet[i].yv * delta;
  74.       x = x / 40.0;
  75.       bullet[i].x = (x - floor(x))*40.0;
  76.       y = y / 40.0;
  77.       bullet[i].y = (y - floor(y))*40.0;
  78.     }
  79.   }
  80. }
  81. void
  82. shotBullet(void)
  83. {
  84.   int entry;
  85.   entry = allocBullet();
  86.   if (entry >= 0) {
  87.     initBullet(entry, glutGet(GLUT_ELAPSED_TIME));
  88.   }
  89. }
  90. void
  91. drawBullets(void)
  92. {
  93.   int i;
  94.   glBegin(GL_POINTS);
  95.   glColor3f(1.0, 0.0, 1.0);
  96.   for (i=0; i<MAX_BULLETS; i++) {
  97.     if (bullet[i].inuse) {
  98.       glVertex2f(bullet[i].x, bullet[i].y);
  99.     }
  100.   }
  101.   glEnd();
  102. }
  103. void
  104. drawShip(float angle)
  105. {
  106.   float rad;
  107.   glPushMatrix();
  108.   glTranslatef(x, y, 0.0);
  109.   glRotatef(angle, 0.0, 0.0, 1.0);
  110.   if (thrust) {
  111.     glColor3f(1.0, 0.0, 0.0);
  112.     glBegin(GL_LINE_STRIP);
  113.     glVertex2f(-0.75, -0.5);
  114.     glVertex2f(-1.75, 0);
  115.     glVertex2f(-0.75, 0.5);
  116.     glEnd();
  117.   }
  118.   glColor3f(1.0, 1.0, 0.0);
  119.   glBegin(GL_LINE_LOOP);
  120.   glVertex2f(2.0, 0.0);
  121.   glVertex2f(-1.0, -1.0);
  122.   glVertex2f(-0.5, 0.0);
  123.   glVertex2f(-1.0, 1.0);
  124.   glVertex2f(2.0, 0.0);
  125.   glEnd();
  126.   if (shield) {
  127.     glColor3f(0.1, 0.1, 1.0);
  128.     glBegin(GL_LINE_LOOP);
  129.     for (rad=0.0; rad<12.0; rad += 1.0) {
  130.       glVertex2f(2.3 * cos(2*rad/M_PI)+0.2, 2.0 * sin(2*rad/M_PI));
  131.     }
  132.     glEnd();
  133.   }
  134.   glPopMatrix();
  135. }
  136. void
  137. display(void)
  138. {
  139.   glClear(GL_COLOR_BUFFER_BIT);
  140.   drawShip(angle);
  141.   drawBullets();
  142.   glutSwapBuffers();
  143. }
  144. void
  145. idle(void)
  146. {
  147.   int time, delta;
  148.   time = glutGet(GLUT_ELAPSED_TIME);
  149.   if (resuming) {
  150.     lastTime = time;
  151.     resuming = 0;
  152.   }
  153.   if (left) {
  154.     delta = time - leftTime;
  155.     angle = angle + delta * 0.4;
  156.     leftTime = time;
  157.   }
  158.   if (right) {
  159.     delta = time - rightTime;
  160.     angle = angle - delta * 0.4;
  161.     rightTime = time;
  162.   }
  163.   if (thrust) {
  164.     delta = time - thrustTime;
  165.     v = delta * 0.00004;
  166.     xv = xv + cos(angle*M_PI/180.0) * v;
  167.     yv = yv + sin(angle*M_PI/180.0) * v;
  168.     thrustTime = time;
  169.   }
  170.   delta = time - lastTime;
  171.   x = x + xv * delta;
  172.   y = y + yv * delta;
  173.   x = x / 40.0;
  174.   x = (x - floor(x))*40.0;
  175.   y = y / 40.0;
  176.   y = (y - floor(y))*40.0;
  177.   lastTime = time;
  178.   advanceBullets(delta, time);
  179.   glutPostWindowRedisplay(currentWindow);
  180. }
  181. void
  182. visible(int vis)
  183. {
  184.   if (vis == GLUT_VISIBLE) {
  185.     if (!paused) {
  186.       glutIdleFunc(idle);
  187.     }
  188.   } else {
  189.     glutIdleFunc(NULL);
  190.   }
  191. }
  192. /* ARGSUSED1 */
  193. void
  194. key(unsigned char key, int px, int py)
  195. {
  196.   switch (key) {
  197.   case 27:
  198.     exit(0);
  199.     break;
  200.   case 'A':
  201.   case 'a':
  202.     thrust = 1;
  203.     thrustTime = glutGet(GLUT_ELAPSED_TIME);
  204.     break;
  205.   case 'S':
  206.   case 's':
  207.     shield = 1;
  208.     break;
  209.   case 'C':
  210.   case 'c':
  211.     cursor = !cursor;
  212.     glutSetCursor(
  213.       cursor ? GLUT_CURSOR_INHERIT : GLUT_CURSOR_NONE);
  214.     break;
  215.   case 'z':
  216.   case 'Z':
  217.     x = 20;
  218.     y = 20;
  219.     xv = 0;
  220.     yv = 0;
  221.     break;
  222.   case 'f':
  223.     glutGameModeString("400x300:16@60");
  224.     glutEnterGameMode();
  225.     initWindow();
  226.     break;
  227.   case 'g':
  228.     glutGameModeString("640x480:16@60");
  229.     glutEnterGameMode();
  230.     initWindow();
  231.     break;
  232.   case 'l':
  233.     if (originalWindow != 0 && currentWindow != originalWindow) {
  234.       glutLeaveGameMode();
  235.       currentWindow = originalWindow;
  236.     }
  237.     break;
  238.   case 'P':
  239.   case 'p':
  240.     paused = !paused;
  241.     if (paused) {
  242.       glutIdleFunc(NULL);
  243.     } else {
  244.       glutIdleFunc(idle);
  245.       resuming = 1;
  246.     }
  247.     break;
  248.   case 'Q':
  249.   case 'q':
  250.   case ' ':
  251.     shotBullet();
  252.     break;
  253.   }
  254. }
  255. /* ARGSUSED1 */
  256. void
  257. keyup(unsigned char key, int x, int y)
  258. {
  259.   switch (key) {
  260.   case 'A':
  261.   case 'a':
  262.     thrust = 0;
  263.     break;
  264.   case 'S':
  265.   case 's':
  266.     shield = 0;
  267.     break;
  268.   }
  269. }
  270. /* ARGSUSED1 */
  271. void
  272. special(int key, int x, int y)
  273. {
  274.   switch (key) {
  275.   case GLUT_KEY_F1:
  276.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  277.     glEnable(GL_BLEND);
  278.     glEnable(GL_LINE_SMOOTH);
  279.     glEnable(GL_POINT_SMOOTH);
  280.     break;
  281.   case GLUT_KEY_F2:
  282.     glDisable(GL_BLEND);
  283.     glDisable(GL_LINE_SMOOTH);
  284.     glDisable(GL_POINT_SMOOTH);
  285.     break;
  286.   case GLUT_KEY_UP:
  287.     thrust = 1;
  288.     thrustTime = glutGet(GLUT_ELAPSED_TIME);
  289.     break;
  290.   case GLUT_KEY_LEFT:
  291.     left = 1;
  292.     leftTime = glutGet(GLUT_ELAPSED_TIME);
  293.     break;
  294.   case GLUT_KEY_RIGHT:
  295.     right = 1;
  296.     rightTime = glutGet(GLUT_ELAPSED_TIME);
  297.     break;
  298.   }
  299. }
  300. /* ARGSUSED1 */
  301. void
  302. specialup(int key, int x, int y)
  303. {
  304.   switch (key) {
  305.   case GLUT_KEY_UP:
  306.     thrust = 0;
  307.     break;
  308.   case GLUT_KEY_LEFT:
  309.     left = 0;
  310.     break;
  311.   case GLUT_KEY_RIGHT:
  312.     right = 0;
  313.     break;
  314.   }
  315. }
  316. /* ARGSUSED3 */
  317. void
  318. joystick(unsigned int buttons, int x, int y, int z)
  319. {
  320.   if (buttons & 0x1) {
  321.     thrust = 1;
  322.     thrustTime = glutGet(GLUT_ELAPSED_TIME);
  323.     joyThrust = 1;
  324.   } else {
  325.     if (joyThrust) {
  326.       thrust = 0;
  327.       joyThrust = 0;
  328.     }
  329.   }
  330.   if (buttons & 0x2) {
  331.     shotBullet();
  332.   }
  333.   if (buttons & 0x4) {
  334.     shield = 1;
  335.     joyShield = 1;
  336.   } else {
  337.     if (joyShield) {
  338.       shield = 0;
  339.       joyShield = 0;
  340.     }
  341.   }
  342.   if (x < -300) {
  343.     left = 1;
  344.     leftTime = glutGet(GLUT_ELAPSED_TIME);
  345.     joyLeft = 1;
  346.   } else {
  347.     /* joyLeft helps avoid "joystick in neutral"
  348.        from continually stopping rotation. */
  349.     if (joyLeft) {
  350.       left = 0;
  351.       joyLeft = 0;
  352.     }
  353.   }
  354.   if (x > 300) {
  355.     right = 1;
  356.     rightTime = glutGet(GLUT_ELAPSED_TIME);
  357.     joyRight = 1;
  358.   } else {
  359.     /* joyRight helps avoid "joystick in neutral"
  360.        from continually stopping rotation. */
  361.     if (joyRight) {
  362.       right = 0;
  363.       joyRight = 0;
  364.     }
  365.   }
  366. }
  367. void
  368. initWindow(void)
  369. {
  370.   glutIgnoreKeyRepeat(1);
  371.   glutDisplayFunc(display);
  372.   glutVisibilityFunc(visible);
  373.   glutKeyboardFunc(key);
  374.   glutKeyboardUpFunc(keyup);
  375.   glutSpecialFunc(special);
  376.   glutSpecialUpFunc(specialup);
  377.   glutJoystickFunc(joystick, 100);
  378.   glMatrixMode(GL_PROJECTION);
  379.   glLoadIdentity();
  380.   glOrtho(0, 40, 0, 40, 0, 40);
  381.   glMatrixMode(GL_MODELVIEW); 
  382.   glPointSize(3.0);
  383.   currentWindow = glutGetWindow();
  384. }
  385. int
  386. main(int argc, char **argv)
  387. {
  388.   glutInit(&argc, argv);
  389.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  390.   if (argc > 1 && !strcmp(argv[1], "-fullscreen")) {
  391.     glutGameModeString("640x480:16@60");
  392.     glutEnterGameMode();
  393.   } else {
  394.     originalWindow = glutCreateWindow("asteroids");
  395.   }
  396.   initWindow();
  397.   glutMainLoop();
  398.   return 0;             /* ANSI C requires main to return int. */
  399. }