]> code.delx.au - pong/blob - pong.c
Paddles move better now
[pong] / pong.c
1 #if defined(WIN32)
2 #pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
3 #include "glut.h"
4 #elif defined(__APPLE__) || defined(MACOSX)
5 #include <GLUT/glut.h>
6 #else
7 #include <GL/glut.h>
8 #endif
9
10 #include <stdio.h>
11 #include <stdlib.h>
12
13 #define SPEEDINC 1.15
14 #define PADDLESPEED 2.5
15 #define FRAME 40
16 #define PADDLESIZE 10
17 #define HEIGHT 100
18
19 static int p1move = 0;
20 static int p2move = 0;
21 static int score1 = 0;
22 static int score2 = 0;
23 static GLdouble paddle1 = 0.0;
24 static GLdouble paddle2 = 0.0;
25 static GLdouble ballX = 0.0;
26 static GLdouble ballY = 0.0;
27 static GLdouble ballVecX = 0.0;
28 static GLdouble ballVecY = 0.0;
29
30
31 static void initball(void) {
32 ballX = 0.0;
33 ballY = 0.0;
34 if(ballVecX < 0)
35 ballVecX = -1.2;
36 else
37 ballVecX = 1.2;
38 ballVecY = 0.7;
39 }
40
41 static void run(void) {
42 // Move the paddles
43 paddle1 += p1move * PADDLESPEED;
44 paddle2 += p2move * PADDLESPEED;
45
46 // Check for collisions with paddles
47 if(ballVecX < 0 && ballX <= -HEIGHT + -ballVecX * 1.5) {
48 if(ballY >= paddle1 - PADDLESIZE && ballY <= paddle1 + PADDLESIZE) {
49 ballVecX *= -SPEEDINC;
50 ballVecY *= SPEEDINC;
51 }
52 }
53 if(ballVecX > 0 && ballX >= HEIGHT - ballVecX * 1.5) {
54 if(ballY >= paddle2 - PADDLESIZE && ballY <= paddle2 + PADDLESIZE) {
55 ballVecX *= -SPEEDINC;
56 ballVecY *= SPEEDINC;
57 }
58 }
59
60 // Check if it's past the top or bottom of the screen
61 if(ballY >= HEIGHT || ballY <= -HEIGHT) {
62 ballVecY = -ballVecY;
63 }
64
65 // Check if it's past the sides of the screen
66 if(ballX >= HEIGHT) {
67 ++score1;
68 initball();
69 return;
70 }
71 if(ballX <= -HEIGHT) {
72 ++score2;
73 initball();
74 return;
75 }
76
77 // Move the ball
78 ballX += ballVecX;
79 ballY += ballVecY;
80 }
81
82 static void display(void) {
83 glClear(GL_COLOR_BUFFER_BIT);
84 glColor3d(0.0, 0.0, 0.0);
85
86 // Draw the paddles
87 glLineWidth(2.0);
88 glBegin(GL_LINES);
89 glVertex2d(-HEIGHT + 1, paddle1 - PADDLESIZE);
90 glVertex2d(-HEIGHT + 1, paddle1 + PADDLESIZE);
91 glVertex2d( HEIGHT - 1, paddle2 + PADDLESIZE);
92 glVertex2d( HEIGHT - 1, paddle2 - PADDLESIZE);
93 glEnd();
94
95 // Draw the ball
96 glPointSize(5.0);
97 glBegin(GL_POINTS);
98 glVertex2d(ballX, ballY);
99 glEnd();
100
101 // Write the score
102 glRasterPos2d(-5.0, HEIGHT - 10.0);
103 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0' + score1);
104 glRasterPos2d( 5.0, HEIGHT - 10.0);
105 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '0' + score2);
106
107 glutSwapBuffers();
108 }
109
110 static void resize(int w, int h) {
111 glViewport(0, 0, w, h);
112 glLoadIdentity();
113 glOrtho(-HEIGHT, HEIGHT, -HEIGHT, HEIGHT, -1.0, 1.0);
114 }
115
116 static void keyboard(unsigned char key, int x, int y) {
117 (void)x;(void)y;
118
119 switch(key) {
120 case 'q':
121 case 'Q':
122 case '\033':
123 exit(0);
124
125 case 'w':
126 p1move = 1;
127 break;
128 case 's':
129 p1move = -1;
130 break;
131
132 case 'i':
133 p2move = 1;
134 break;
135 case 'k':
136 p2move = -1;
137 break;
138
139 default:
140 return;
141 }
142 glutPostRedisplay();
143 }
144
145 static void keyboardUp(unsigned char key, int x, int y) {
146 (void)x;(void)y;
147
148 switch(key) {
149 case 'w':
150 case 's':
151 p1move = 0;
152 break;
153
154 case 'i':
155 case 'k':
156 p2move = 0;
157 p2move = 0;
158 break;
159 }
160 }
161
162 static void timer(int lastTime) {
163 int curTime = glutGet(GLUT_ELAPSED_TIME);
164 do {
165 lastTime += FRAME;
166 run();
167 } while(lastTime + FRAME < curTime);
168 glutPostRedisplay();
169 glutTimerFunc(FRAME - (curTime - lastTime), timer, curTime);
170 }
171
172 static void init(void) {
173 glClearColor(1.0, 1.0, 1.0, 0.0);
174 initball();
175 }
176
177 int main(int argc, char *argv[]) {
178 glutInitWindowPosition(100, 100);
179 glutInitWindowSize(640, 480);
180 glutInit(&argc, argv);
181 glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
182 glutCreateWindow(argv[0]);
183 glutDisplayFunc(display);
184 glutReshapeFunc(resize);
185 glutKeyboardFunc(keyboard);
186 glutKeyboardUpFunc(keyboardUp);
187 glutTimerFunc(FRAME, timer, glutGet(GLUT_ELAPSED_TIME));
188 init();
189 glutMainLoop();
190 return 0;
191 }
192