#include #include #include #include #include using namespace std; // Game state enum { MENU, GAME, END }; int width=800, height=600; // Window params int gamestate = MENU; // Game state int score1=0, score2=0; // Scores of 2 players int winScore=10; // Score to win bool keyStates[256] = { 0 }; // Key presses // Board params double board1x=20, board2x=770; double board1y=450, board2y=450; double boardWidth=10, boardHeight=100; double boardSpeed = 12; // Ball params bool ballUp = true; bool ballRight = true; double ballSpeed = 8; double ballCurSpeed = ballSpeed; //Speed just after hitting a board (fn of distance from center) Max value = 2*ballSpeed double ballSize = 10; double ballX = board1x + boardWidth; double ballY = board1y - boardHeight/2; // Misc params time_t start; int timePassed = 0; bool miss1,miss2; string self("by Max"); string text("Press RETURN to start"); string ins1("Player 1 - keys Q,A"); string ins2("Player 2 - keys P,L"); string rule("First to score 10 wins!"); string miss("MISS!"); string win1("Player 1 wins!"); string win2("Player 2 wins!"); string playagain("Play again (RETURN)"); string reset("Reset (Spacebar)"); void ball(); // Draws ball void ballOperations(); // Moves ball void board(double,double); // Draws boards void cube(); // Draws cube void drawTitle(); // Draws menu void drawString(string,double,double); // Draws a string void init(); void keyOperations(); void display(); void keyboardDown(); void keyboardUp(); void idle(); void resetState() { ballUp = true; ballRight = true; ballSpeed = 10; ballCurSpeed = ballSpeed; ballSize = 10; ballX = board1x + boardWidth; ballY = board1y - boardHeight/2; score1=0; score2=0; } void ball() { glColor3f(1,1,1); glBegin(GL_POLYGON); glVertex2d(ballX,ballY); glVertex2d(ballX+ballSize,ballY); glVertex2d(ballX+ballSize,ballY-ballSize); glVertex2d(ballX,ballY-ballSize); glEnd(); } void board(double boardx, double boardy) { glColor3f(1,1,1); glBegin(GL_POLYGON); glVertex2d(boardx,boardy); glVertex2d(boardx+boardWidth,boardy); glVertex2d(boardx+boardWidth,boardy-boardHeight); glVertex2d(boardx,boardy-boardHeight); glEnd(); } void ballOperations() { miss1 = false; miss2 = false; // Player 1 miss if(ballX < 0) { score2++; ballCurSpeed = ballSpeed; if(score2==winScore) { gamestate = END; return; } ballX = board1x + boardWidth; ballY = board1y - boardHeight/2; ballRight = true; miss1 = true; display(); Sleep(1000); } // Player 2 miss if(ballX > 800) { score1++; ballCurSpeed = ballSpeed; if(score1==winScore) { gamestate = END; return; } ballX = board2x - ballSize; ballY = board2y - boardHeight/2; ballRight = false; miss2 = true; display(); Sleep(1000); } // Board-ball collision if(ballX < board1x+boardWidth && ballY-ballSize < board1y && ballY > board1y-100) { ballRight = !ballRight; ballCurSpeed = ballSpeed + ballSpeed * abs( board1y-(boardHeight/2)-ballY ) / (boardHeight/2+ballSize) ; ballX += ballCurSpeed; // Just to be safe after a collision } if(ballX+ballSize > board2x && ballY-ballSize < board2y && ballY > board2y-100) { ballRight = !ballRight; ballCurSpeed = ballSpeed + ballSpeed * abs( board2y-(boardHeight/2)-ballY ) / (boardHeight/2+ballSize) ; ballX -= ballCurSpeed; // Just to be safe after a collision } // Top-bottom collison detection if(ballY > height) //collide top ballUp = !ballUp; if(ballY < ballSize) //collide bottom ballUp = !ballUp; // Code to move the ball if(ballRight) ballX += ballCurSpeed; else ballX -= ballCurSpeed; if(ballUp) ballY += ballCurSpeed; else ballY -= ballCurSpeed; } void cube(int x, int y) { glColor3f(1,1,1); glBegin(GL_POLYGON); glVertex2d(x,y); glVertex2d(x,y+20); glVertex2d(x+20,y+20); glVertex2d(x+20,y); glEnd(); } void drawTitle() { // Dirty way to draw "PONG" cube(200,500); cube(220,500); cube(240,500); cube(260,500); cube(260,480); cube(260,460); cube(240,460); cube(220,460); cube(200,460); cube(200,480); cube(200,460); cube(200,440); cube(200,420); cube(300,500); cube(320,500); cube(340,500); cube(360,500); cube(300,480); cube(300,460); cube(300,440); cube(300,420); cube(360,480); cube(360,460); cube(360,440); cube(360,420); cube(300,420); cube(320,420); cube(340,420); cube(360,420); cube(400,500); cube(400,480); cube(400,460); cube(400,440); cube(400,420); cube(420,480); cube(440,460); cube(460,440); cube(480,500); cube(480,480); cube(480,460); cube(480,440); cube(480,420); cube(520,500); cube(540,500); cube(560,500); cube(580,500); cube(520,480); cube(520,460); cube(520,440); cube(520,420); cube(540,420); cube(560,420); cube(580,420); cube(580,440); cube(580,460); cube(560,460); // "by Max" drawString(self,530,400); } void drawString(string s, double x, double y) { glRasterPos2f(x,y); for(int i=0 ; i 100) board1y-=boardSpeed; if(keyStates['p']) if(board2y < 600) board2y+=boardSpeed; if(keyStates['l']) if(board2y > 100) board2y-=boardSpeed; } void display (void) { glClear(GL_COLOR_BUFFER_BIT); keyOperations(); switch(gamestate) { case MENU: // Draw menu drawTitle(); drawString(ins1,300,300); drawString(ins2,300,250); drawString(rule,300,200); // Blink if(timePassed % 2 == 0) drawString(text,290,100); break; case GAME: if(miss1) drawString(miss,100,50); //if miss if(miss2) drawString(miss,600,50); ballOperations(); // Move ball ball(); // Draw ball board(board1x, board1y); // Draw boards board(board2x, board2y); glBegin(GL_LINES); // Center line glVertex2i(400,0); glVertex2i(400,600); glEnd(); // Draw score { string number; stringstream conv1; conv1<(clock()-start)/CLOCKS_PER_SEC; } int main (int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(width, height); glutInitWindowPosition (0, 0); glutCreateWindow("Pong by Max"); init(); glutDisplayFunc(display); glutIdleFunc(idle); glutKeyboardFunc(keyboardDown); glutKeyboardUpFunc(keyboardUp); start = clock(); glutMainLoop(); return 0; }