#include #include #include using namespace std; int SCORE1 = 0, SCORE2 = 0; float PX1 = -230, PY1 = 0, PX2 = 230, PY2 = 0; float PADDLE_WIDTH = 10, PADDLE_HEIGHT = 80, PADDLE_SPEED = 8; float BALLX = 0, BALLY = 0, BALL_SIZE = 10; float DIRX = 1, DIRY = 1, SPEEDX = 4, SPEEDY = 4; char MESSAGE[60]; bool KEYS_NORMAL[256], KEYS_SPECIAL[256], GAME_OVER = false; void type_text(char *str, float x, float y, float s) { char *c; glPushMatrix(); glTranslatef(x, y, 0); glScalef(0.1 * s, 0.1 * s, 0); for (c = str; *c != '\0'; c++) glutStrokeCharacter(GLUT_STROKE_ROMAN, *c); glScalef(1, 1, 1); glPopMatrix(); } void draw_middle_line() { glPushAttrib(GL_ALL_ATTRIB_BITS); glEnable(GL_LINE_STIPPLE); glLineStipple(1, 0x00FF); glLineWidth(4); glColor3ub(128, 128, 128); glBegin(GL_LINES); glVertex2i(0, 180); glVertex2i(0, -180); glEnd(); glDisable(GL_LINE_STIPPLE); glPopAttrib(); } void draw_ball(float cx, float cy, float s) { float x, y, r = s / 2; glBegin(GL_TRIANGLE_FAN); glVertex2f(cx, cy); for(int angle = 0; angle <= 360; angle++) { x = cx + r * cos(M_PI * angle / 180); y = cy + r * sin(M_PI * angle / 180); glVertex2f(x, y); } glEnd(); } void draw_paddle(float x, float y, float w, float h) { glRectf(x - w / 2, y - h / 2, x + w / 2, y + h / 2); } void check_collisions() { if(BALLY > 180 - BALL_SIZE / 2) DIRY *= -1; if(BALLY < -180 + BALL_SIZE / 2) DIRY *= -1; if(BALLX >= PX1 - PADDLE_WIDTH / 2 - BALL_SIZE / 2 && BALLX <= PX1 + PADDLE_WIDTH / 2 + BALL_SIZE / 2 && BALLY <= PY1 + PADDLE_HEIGHT / 2 + BALL_SIZE / 2 && BALLY >= PY1 - PADDLE_HEIGHT / 2 - BALL_SIZE / 2 ) DIRX *= -1; if(BALLX >= PX2 - PADDLE_WIDTH / 2 - BALL_SIZE / 2 && BALLX <= PX2 + PADDLE_WIDTH / 2 + BALL_SIZE / 2 && BALLY <= PY2 + PADDLE_HEIGHT / 2 + BALL_SIZE / 2 && BALLY >= PY2 - PADDLE_HEIGHT / 2 - BALL_SIZE / 2 ) DIRX *= -1; if(BALLX >= 240 - BALL_SIZE / 2) { SCORE1++; BALLX = 0; BALLY = 0; DIRX = -1; DIRY = 1; } if(BALLX <= -240 + BALL_SIZE / 2) { SCORE2++; BALLX = 0; BALLY = 0; DIRX = 1; DIRY = 1; } } void check_keyboard() { if (KEYS_SPECIAL[GLUT_KEY_UP] && PY2 < (180 - PADDLE_HEIGHT / 2)) PY2 += PADDLE_SPEED; if (KEYS_SPECIAL[GLUT_KEY_DOWN] && PY2 > (-180 + PADDLE_HEIGHT / 2)) PY2 -= PADDLE_SPEED; if ((KEYS_NORMAL['W'] || KEYS_NORMAL['w']) && PY1 < (180 - PADDLE_HEIGHT / 2)) PY1 += PADDLE_SPEED; if ((KEYS_NORMAL['S'] || KEYS_NORMAL['s']) && PY1 > (-180 + PADDLE_HEIGHT / 2)) PY1 -= PADDLE_SPEED; } void display() { glClearColor(1,1,1,1); glClear(GL_COLOR_BUFFER_BIT); if(GAME_OVER) { // Show game vver type_text("GAME OVER", -195, 0, 5); } else { // Draw middle line draw_middle_line(); // Player 1 paddle glColor3ub(255, 0, 0); draw_paddle(PX1, PY1, PADDLE_WIDTH, PADDLE_HEIGHT); // Player 2 paddle glColor3ub(0, 0, 255); draw_paddle(PX2, PY2, PADDLE_WIDTH, PADDLE_HEIGHT); // Draw ball glColor3ub(0, 0, 0); draw_ball(BALLX, BALLY, BALL_SIZE); // Move ball BALLX += DIRX * SPEEDX; BALLY += DIRY * SPEEDY; // Collisions check_collisions(); // Keyboard check_keyboard(); // Score sprintf(MESSAGE, "%d", SCORE1); type_text(MESSAGE, -120, 100, 5); sprintf(MESSAGE, "%d", SCORE2); type_text(MESSAGE, 120, 100, 5); if(SCORE1 == 5 || SCORE2 == 5) GAME_OVER = true; } glutSwapBuffers(); } void keyboard_normal(unsigned char key, int x, int y) { KEYS_NORMAL[key] = true; } void keyboard_normal_up(unsigned char key, int x, int y) { KEYS_NORMAL[key] = false; } void keyboard_special(int key, int x, int y) { KEYS_SPECIAL[key] = true; } void keyboard_special_up(int key, int x, int y) { KEYS_SPECIAL[key] = false; } void timer(int value) { glutPostRedisplay(); glutTimerFunc(1000.0 / 60.0, timer, 0); } int main(int argc, char** argv) { glutInit(&argc,argv); glutInitWindowPosition(250, 50); glutInitWindowSize(480,360); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutCreateWindow("PONG"); glMatrixMode(GL_PROJECTION); gluOrtho2D(-240, 240, -180, 180); glutDisplayFunc(display); glutKeyboardFunc(keyboard_normal); glutKeyboardUpFunc(keyboard_normal_up); glutSpecialFunc(keyboard_special); glutSpecialUpFunc(keyboard_special_up); glutTimerFunc(1000.0 / 60.0, timer, 0); glutMainLoop(); return 0; }