X-Git-Url: https://code.delx.au/pong/blobdiff_plain/91d3bf2065f6f0a90845c5bc3098a250b30312be..6c1893c335f49f5a595e04b66c18dc88f8b5cff3:/pong.c diff --git a/pong.c b/pong.c index af2dce8..4ecaa8a 100644 --- a/pong.c +++ b/pong.c @@ -9,14 +9,23 @@ #include #include +#include -#define SPEEDINC 1.15 -#define PADDLESPEED 2.5 +// Amount to increase speed by on x, y axis, and when bouncing +#define SPEEDXINC 1.1 +#define SPEEDYINC 1.1 +#define SPEEDBINC 0.15 +#define PADDLESPEED 3.0 #define FRAME 40 #define PADDLESIZE 10 #define HEIGHT 100 -static int AI = 0; +#define STATE_UI 0 +#define STATE_1P 1 +#define STATE_2P 2 + +static char* menu = ""; +static int state = 0; static int p1move = 0; static int p2move = 0; static int score1 = 0; @@ -29,7 +38,7 @@ static GLdouble ballVecX = 0.0; static GLdouble ballVecY = 0.0; -static void initball(void) { +static void initBall(void) { ballX = 0.0; ballY = 0.0; if(ballVecX < 0) @@ -40,8 +49,8 @@ static void initball(void) { } static void run(void) { - // AI - if(AI) { + // AI is on + if(state == STATE_1P) { if(ballY < paddle2 - PADDLESIZE) p2move = -1; else if(ballY > paddle2 + PADDLESIZE) @@ -65,14 +74,16 @@ static void run(void) { // Check for collisions with paddles if(ballVecX < 0 && ballX <= -HEIGHT + -ballVecX * 1.5) { if(ballY >= paddle1 - PADDLESIZE && ballY <= paddle1 + PADDLESIZE) { - ballVecX *= -SPEEDINC; - ballVecY *= SPEEDINC; + GLdouble speedChange = fmax(1.0, fabs(paddle1 - ballY) * SPEEDBINC); + ballVecX *= -speedChange * SPEEDXINC; + ballVecY *= speedChange * SPEEDYINC; } } if(ballVecX > 0 && ballX >= HEIGHT - ballVecX * 1.5) { if(ballY >= paddle2 - PADDLESIZE && ballY <= paddle2 + PADDLESIZE) { - ballVecX *= -SPEEDINC; - ballVecY *= SPEEDINC; + GLdouble speedChange = fmax(1.0, fabs(paddle2 - ballY) * SPEEDBINC); + ballVecX *= -speedChange * SPEEDXINC; + ballVecY *= speedChange * SPEEDYINC; } } @@ -84,11 +95,11 @@ static void run(void) { // Check if it's past the sides of the screen if(ballX >= HEIGHT) { ++score1; - initball(); + initBall(); } if(ballX <= -HEIGHT) { ++score2; - initball(); + initBall(); } // Move the ball @@ -97,19 +108,53 @@ static void run(void) { // Check scores for winners.. if(score1 == 9) { - // Player 1 wins + menu = "Player 1 wins!"; + state = STATE_UI; score1 = score2 = 0; } if(score2 == 9) { - // Player 2 wins + menu = "Player 2 wins!"; + state = STATE_UI; score1 = score2 = 0; } } -static void display(void) { - glClear(GL_COLOR_BUFFER_BIT); - glColor3d(0.0, 0.0, 0.0); +static void timer(int lastTime) { + if(state == STATE_UI) { + return; + } + + int curTime = glutGet(GLUT_ELAPSED_TIME); + do { + lastTime += FRAME; + run(); + } while(lastTime + FRAME < curTime); + glutPostRedisplay(); + glutTimerFunc(FRAME - (curTime - lastTime), timer, curTime); +} +static void startGame(void) { + glutTimerFunc(FRAME, timer, glutGet(GLUT_ELAPSED_TIME)); + initBall(); +} + +static void drawText(double x, double y, char* str) { + glRasterPos2d(x, y); + while(*str) { + glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, *str); + ++str; + } +} + +static void menuDisplay(void) { + drawText(-20, 50, "Awesome PONG!"); + drawText(-50, -50, "Press 1 for a single player game."); + drawText(-50, -60, "Press 2 for a multi player game."); + drawText(-50, -70, "Keys: w/s and i/k"); + drawText(-20, 0, menu); +} + +static void gameDisplay(void) { // Draw the paddles glLineWidth(2.0); glBegin(GL_LINES); @@ -120,9 +165,9 @@ static void display(void) { glEnd(); // Draw the ball - glPointSize(5.0); - glBegin(GL_POINTS); + glBegin(GL_LINES); glVertex2d(ballX, ballY); + glVertex2d(ballX - ballVecX, ballY - ballVecY); glEnd(); // Write the score @@ -130,6 +175,17 @@ static void display(void) { glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0' + score1); glRasterPos2d( 5.0, HEIGHT - 10.0); glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0' + score2); +} + +static void display(void) { + glClear(GL_COLOR_BUFFER_BIT); + glColor3d(0.0, 0.0, 0.0); + + if(state == STATE_UI) { + menuDisplay(); + } else { + gameDisplay(); + } glutSwapBuffers(); } @@ -140,15 +196,24 @@ static void resize(int w, int h) { glOrtho(-HEIGHT, HEIGHT, -HEIGHT, HEIGHT, -1.0, 1.0); } -static void keyboard(unsigned char key, int x, int y) { - (void)x;(void)y; - +static void menuKeyboard(unsigned char key) { switch(key) { - case 'q': - case 'Q': - case '\033': - exit(0); + case '1': + state = STATE_1P; + break; + case '2': + state = STATE_2P; + break; + + default: + return; + } + startGame(); +} + +static void gameKeyboard(unsigned char key) { + switch(key) { case 'w': p1move = 1; break; @@ -169,6 +234,24 @@ static void keyboard(unsigned char key, int x, int y) { glutPostRedisplay(); } +static void keyboard(unsigned char key, int x, int y) { + (void)x;(void)y; + + switch(key) { + case 'q': + case 'Q': + case '\033': + exit(0); + } + + + if(state == STATE_UI) { + menuKeyboard(key); + } else { + gameKeyboard(key); + } +} + static void keyboardUp(unsigned char key, int x, int y) { (void)x;(void)y; @@ -186,26 +269,7 @@ static void keyboardUp(unsigned char key, int x, int y) { } } -static void timer(int lastTime) { - int curTime = glutGet(GLUT_ELAPSED_TIME); - do { - lastTime += FRAME; - run(); - } while(lastTime + FRAME < curTime); - glutPostRedisplay(); - glutTimerFunc(FRAME - (curTime - lastTime), timer, curTime); -} - -static void init(void) { - glClearColor(1.0, 1.0, 1.0, 0.0); - initball(); -} - int main(int argc, char *argv[]) { - if(argc == 2 && *argv[1] == '1') { - AI = 1; - } - glutInitWindowPosition(100, 100); glutInitWindowSize(640, 480); glutInit(&argc, argv); @@ -215,8 +279,7 @@ int main(int argc, char *argv[]) { glutReshapeFunc(resize); glutKeyboardFunc(keyboard); glutKeyboardUpFunc(keyboardUp); - glutTimerFunc(FRAME, timer, glutGet(GLUT_ELAPSED_TIME)); - init(); + glClearColor(1.0, 1.0, 1.0, 0.0); glutMainLoop(); return 0; }