OpenGL Creating "Sparks" for Pong

I am trying to learn OpenGL for C++. I want to do more 2D work. I started by making a Pong clone. Everything works fine, but I want to make the GUI look better. My question, more specifically, is how can I make "sparks" shoot off the racket when the ball hits it?
I have tried drawing rectangles but I cannot make them appear when and where I want them to. This is my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
#include <string>
#include <Windows.h>
#include <iostream>
#include <conio.h>
#include <sstream>
#include <cmath>
#include <gl\GL.h>
#include <gl\GLU.h>
#include "GL\freeglut.h"

//window size and update rate(60 fps)
int width = 600;
int height = 300;
int interval = 1000 / 60;

//Particles
int particle_speed_x;
int particle_speed_y;
int particle_width = 3;
int particle_height = 10;

//score
int score_left = 0;
int left_gameWon = 0;
int score_right = 0;
int right_gameWon = 0;

//rackets in general
float racket_width = 10;
float racket_height = 80;
float racket_speed = 3;
float racket_x_speed = 4;

//left racket position
float racket_left_x = 10.0f;
float racket_left_y = 50.0f;

//right racket position
float racket_right_x = width - racket_width - 10;
float racket_right_y = 50;

//Middle line'
float line_pos_x = width / 2;
float line_pos_y = height / 500;
float line_width = 1;
float line_height = height;

//ball
float ball_pos_x = width / 2;
float ball_pos_y = height / 2;
float ball_dir_x = -1.0f;
float ball_dir_y = 0.0f;
int ball_size = 8;
int ball_speed = 2;

//things to say
char left_team[] = "Left Team";
char right_team[] = "Right Team";

//pause stuff
int racket_sped = 3;
int ball_sped = 2;

void drawRect(float x, float y, float width, float height)
{
	glBegin(GL_QUADS);
	glVertex2f(x, y);
	glVertex2f(x + width, y);
	glVertex2f(x + width, y + height);
	glVertex2f(x, y + height);
	glEnd();
}

void vec2_norm(float& x, float &y) {
	// sets a vectors length to 1 (which means that x + y == 1)
	float length = sqrt((x * x) + (y * y));
	if (length != 0.0f) {
		length = 1.0f / length;
		x *= length;
		y *= length;
	}
}

std::string int2str(int x)
{
	//converts int to string
	std::stringstream ss;
	ss << x;
	return ss.str();
}
void drawText(float x, float y, std::string text)
{
	glRasterPos2f(x, y);
	glutBitmapString(GLUT_BITMAP_8_BY_13, (const unsigned char*)text.c_str());
}

void draw()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

	//draw rackets
	drawRect(racket_left_x, racket_left_y, racket_width, racket_height);
	drawRect(racket_right_x, racket_right_y, racket_width, racket_height);
	drawRect(ball_pos_x - ball_size / 2, ball_pos_y - ball_size / 2, ball_size, ball_size);
	drawRect(line_pos_x, line_pos_y, line_width, line_height);

	//draw score
	drawText(width / 2.076, height - 15, int2str(score_left) + " " + int2str(score_right));

	//Draw team left and right
	glRasterPos2f(width / 2 - 250, height - 20);
	glutBitmapString(GLUT_BITMAP_8_BY_13, (const unsigned char*)left_team);
	glRasterPos2f(width / 2 + 165, height - 20);
	glutBitmapString(GLUT_BITMAP_8_BY_13, (const unsigned char*)right_team);
	drawText(width / 2.079, height / 9 - 20, int2str(left_gameWon) + " " + int2str(right_gameWon));
	
	//swap buffers(has to be done at the end)
	glutSwapBuffers();
}

void keyboard()
{
	//left racket
	if (GetAsyncKeyState('W')) racket_left_y += racket_speed;
	if (GetAsyncKeyState('S')) racket_left_y -= racket_speed;
	//if (GetAsyncKeyState('D')) racket_left_x += racket_x_speed;
	//if (GetAsyncKeyState('A')) racket_left_x -= racket_x_speed;

	//pause
	if (GetAsyncKeyState(VK_SPACE))racket_speed = 0;
	if (GetAsyncKeyState(VK_SPACE))ball_speed = 0;
	if (GetAsyncKeyState(VK_ESCAPE))racket_speed = racket_sped;
	if (GetAsyncKeyState(VK_ESCAPE))ball_speed = ball_sped;
	if (GetAsyncKeyState(VK_DELETE))exit(0);


	//right racket
	if (GetAsyncKeyState(VK_UP)) racket_right_y += racket_speed;
	if (GetAsyncKeyState(VK_DOWN)) racket_right_y -= racket_speed;
	//if (GetAsyncKeyState(VK_LEFT)) racket_right_x -= racket_x_speed;
	//if (GetAsyncKeyState(VK_RIGHT)) racket_right_x += racket_x_speed;
}
void updateRack()
{
	//Check boundary for left racket
	if (racket_left_y > height - 75)
	{
		racket_left_y = height - 75;
	}
	else if (racket_left_y < height - height)
	{
		racket_left_y = height - height;
	}
	

	//Check boundary for right racket
	if (racket_right_y > height - 75)
	{
		racket_right_y = height - 75;
	}
	else if (racket_right_y < height - height)
	{
		racket_right_y = height - height;
	}
}
void updateBall()
{
	//fly a bit
	ball_pos_x += ball_dir_x * ball_speed;
	ball_pos_y += ball_dir_y * ball_speed;

	//hit by left racket?
	if (ball_pos_x < racket_left_x + racket_width + 3 && ball_pos_x > racket_left_x && ball_pos_y < racket_left_y + racket_height && ball_pos_y > racket_left_y)
	{
		//set fly direction depending on where it hit the racket
		//(t is 0.5 if hit at top, 0 at center, -0.5 at bottom)
		PlaySound(TEXT("Blop.wav"), NULL, SND_FILENAME | SND_ASYNC);
		float t = ((ball_pos_y - racket_left_y) / racket_height) - 0;
		ball_dir_x = fabs(ball_dir_x);//force it to be positive
		ball_dir_y = t;
		if (ball_speed < 7)
		{
			ball_speed++;
			racket_speed = ball_speed;
			ball_sped++;
			racket_sped = ball_sped;
		}
		else if (ball_speed >= 6)
		{

		}
	}
	
	//hit by right racket
	if (ball_pos_x < racket_right_x + racket_width - 3 && ball_pos_x > racket_right_x && ball_pos_y < racket_right_y + racket_height && ball_pos_y > racket_right_y)
	{
		//set fly direction depending on where it hit the racket
		//(t is 0.5 if hit at top, 0 at center, -0.5 at bottom)
		PlaySound(TEXT("Blop.wav"), NULL, SND_FILENAME | SND_ASYNC);
		float t = ((ball_pos_y - racket_right_y) / racket_height) - 0;
		ball_dir_x = -fabs(ball_dir_x);//force it to be positive
		ball_dir_y = t;
		if (ball_speed < 7)
		{
			ball_speed++;
			racket_speed = ball_speed;
			ball_sped++;
			racket_sped = ball_sped;
		}
		else if (ball_speed >= 6)
		{

		}
	}

	// hit left wall?
	if (ball_pos_x < 0) {
		++score_right;
		PlaySound(TEXT("Goal.wav"), NULL, SND_ASYNC | SND_FILENAME | SND_ASYNC);
		if (score_right >= 5)
		{
			std::cout << "\nRight Wins!\nScore: " << score_left << ":" << score_right;
			score_right = 0;
			score_left = 0;
			right_gameWon++;
		}
		ball_pos_x = width / 2;
		ball_pos_y = height / 2;
		ball_dir_x = fabs(ball_dir_x); // force it to be positive
		ball_dir_y = 0;
		ball_speed = 2;
		ball_sped = 2;
	}

	//hit right wall
	if (ball_pos_x > width)
	{
		++score_left;
		PlaySound(TEXT("Goal.wav"), NULL, SND_ASYNC | SND_FILENAME | SND_ASYNC);
		if (score_left >= 5)
		{
			std::cout << "\nLeft Wins!\nScore: " << score_left << ":" << score_right;
			score_right = 0;
			score_left = 0;
			left_gameWon++;
		}
		ball_pos_x = width / 2;
		ball_pos_y = height / 2;
		ball_dir_x = -fabs(ball_dir_x);
		ball_dir_y = 0;
		ball_speed = 2;
		ball_sped = 2;
		
	}

	// hit top wall?
	if (ball_pos_y > height) {
		PlaySound(TEXT("Blop.wav"), NULL, SND_ASYNC | SND_FILENAME | SND_ASYNC);
		ball_dir_y = -fabs(ball_dir_y); // force it to be negative
	}

	// hit bottom wall?
	if (ball_pos_y < 0) {
		PlaySound(TEXT("Blop.wav"), NULL, SND_ASYNC | SND_FILENAME | SND_ASYNC);
		ball_dir_y = fabs(ball_dir_y); // force it to be positive
	}

	// make sure that length of dir stays at 1
	vec2_norm(ball_dir_x, ball_dir_y);
}
void update(int value)
{
	//input handling
	keyboard();

	//update racket
	updateRack();

	//update ball
	updateBall();

	//Call update() again in interval milliseconds
	glutTimerFunc(interval, update, 0);

	//Reddisplay frame
	glutPostRedisplay();
}

void enable2D(int width, int height)
{
	
	glViewport(0, 0, width, height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0f, width, 0.0f, height, 0.0f, 1.0f);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}
int main(int argc, char** argv[])
{
	glutInit(&argc, argv[1]);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(width, height);
	glutInitWindowPosition(0, 0);
	glutCreateWindow("Pong (Clone)");
	glClearColor(0, 0, 0, 0);

	//Register callback functions
	glutDisplayFunc(draw);
	glutTimerFunc(interval, update, 0);

	//set scene to 2D mode and set draw color to white
	enable2D(width, height);
	glColor3f(1.0f, 0.0f, 1.0f);
	glutSetCursor(GLUT_CURSOR_NONE);

	//start the whole thing
	glutMainLoop();
	return 0;
}
Topic archived. No new replies allowed.