Updated code to use variable paddle speed and keep a constant speed (magnitude of velocity); added function to determine the x and y components of ball velocity after collision with paddle
This commit is contained in:
		
							
								
								
									
										56
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										56
									
								
								main.cpp
									
									
									
									
									
								
							| @@ -1,16 +1,43 @@ | ||||
| #include <iostream> | ||||
| #include <cmath> | ||||
| #include <raylib-cpp.hpp> | ||||
| #include "paddle.hpp" | ||||
| #include "ball.hpp" | ||||
| #include "math-helpers.hpp" | ||||
|  | ||||
| /* Global variables used to instantiate structs */ | ||||
| const int WIDTH = 1000; | ||||
| const int HEIGHT = 480; | ||||
| const int RECT_H = HEIGHT / 3; | ||||
| const int RECT_W = 30; | ||||
| const int PADDLE_SPEED = 8; | ||||
| const int CIRC_RAD = 10; | ||||
| const float BASE_BOUNCE_DEG = 30; | ||||
| const float BASE_BOUNCE_RAD = (BASE_BOUNCE_DEG / 180.0) * M_PI; | ||||
| const float BASE_SPEED_COMPONENTS = 7; | ||||
| const float BASE_SPEED = sqrt(powf(BASE_SPEED_COMPONENTS, 2) * 2); | ||||
|  | ||||
| raylib::Vector2 changeVelocityAfterCollision(Paddle paddle, Ball ball) { | ||||
| 	float paddle_mid_y = (paddle.getRect().y + paddle.getRect().GetHeight()) / 2.0; /* Middle y value of rectangle */ | ||||
| 	float  ball_y = ball.pos.y; /* Y co-ordinate of ball */ | ||||
|  | ||||
| 	float offset = paddle_mid_y - ball_y; /* Subtracting the ball coordinate will give us a value between -paddle_mid_y (represents bottom of paddle) and +paddle_mid_y (represents top of paddle) */ | ||||
| 	offset /= (paddle.getRect().GetHeight() / 2.0); /* Normalize the value, by dividing it by its magnitude. It is now a value between -1 and 1. */ | ||||
| //	offset *= -1; /* Reverse the sign of the offset, so that -1 represents the top, and 1 represents the bottom */ | ||||
|  | ||||
| 	float bounce_angle = offset * BASE_BOUNCE_RAD; /* Calculate the actual bounce angle from the base bounce angle. */ | ||||
|  | ||||
| 	/* Calculate new velocities as multiples of the original velocity. I use sine and cosine, because when the ball hits the paddle | ||||
| 	perpendicular to it (bounce angle is 0), the y_velocity should be 0 (i.e. It should bounce straight back). The sin function does | ||||
| 	this for us. A similar reasoning was employed for the use of cosine */ | ||||
| 	float new_x_vel = abs(BASE_SPEED * cosf(bounce_angle)) * (-1 * signum(ball.vel.x)); /* Reverse the sign of the x-velocity */ | ||||
| 	float new_y_vel = abs(BASE_SPEED * sinf(bounce_angle)) * signum(ball.vel.y); /* Keep the sign of the y-velocity */ | ||||
|  | ||||
| 	return raylib::Vector2(new_x_vel, new_y_vel); | ||||
| } | ||||
|  | ||||
|  | ||||
| int main() { | ||||
| 	/* Initialize variables used to instantiate structs*/ | ||||
| 	const int WIDTH = 600; | ||||
| 	const int HEIGHT = 480; | ||||
| 	const int RECT_H = HEIGHT / 3; | ||||
| 	const int RECT_W = 30; | ||||
| 	const int CIRC_RAD = 10; | ||||
|  | ||||
| 	/* Initialize window */ | ||||
| 	raylib::Window window = raylib::Window(WIDTH, HEIGHT, "Pong"); | ||||
| 	SetTraceLogLevel(LOG_INFO); | ||||
| @@ -21,7 +48,7 @@ int main() { | ||||
| 	/* Instantiate Paddle and Ball objects */ | ||||
| 	Paddle pad1 = Paddle(10, 10, RECT_W, RECT_H); | ||||
| 	Paddle pad2 = Paddle(window.GetWidth() - RECT_W - 10, 10, RECT_W, RECT_H); | ||||
| 	Ball ball = Ball(window.GetWidth()/2, window.GetHeight()/2, CIRC_RAD, 3, 3); | ||||
| 	Ball ball = Ball(window.GetWidth()/2, window.GetHeight()/2, CIRC_RAD, 5, 5); | ||||
|  | ||||
| 	window.BeginDrawing(); | ||||
| 	pad1.draw(); | ||||
| @@ -32,10 +59,10 @@ int main() { | ||||
| 	while (!window.ShouldClose()) { | ||||
| 		/* Update paddle velocity */ | ||||
| 		if (IsKeyPressed(KEY_S)) { | ||||
| 			pad1.velocity.y = 5; /* Set positive (downward) velocity, since (0,0) is top-left */ | ||||
| 			pad1.velocity.y = PADDLE_SPEED; /* Set positive (downward) velocity, since (0,0) is top-left */ | ||||
| 		} | ||||
| 		if (IsKeyPressed(KEY_W)) { | ||||
| 			pad1.velocity.y = -5; /* Set negative (upward) velocity */ | ||||
| 			pad1.velocity.y = (-1) * PADDLE_SPEED; /* Set negative (upward) velocity */ | ||||
| 		} | ||||
|  | ||||
| 		if (IsKeyReleased(KEY_S) || IsKeyReleased(KEY_W)) { | ||||
| @@ -43,10 +70,10 @@ int main() { | ||||
| 		} | ||||
|  | ||||
| 		if (IsKeyPressed(KEY_UP)) { | ||||
| 			pad2.velocity.y = -5; | ||||
| 			pad2.velocity.y = (-1) * PADDLE_SPEED; | ||||
| 		} | ||||
| 		if (IsKeyPressed(KEY_DOWN)) { | ||||
| 			pad2.velocity.y = 5; | ||||
| 			pad2.velocity.y = PADDLE_SPEED; | ||||
| 		} | ||||
| 		if (IsKeyReleased(KEY_UP) || IsKeyReleased(KEY_DOWN)) { | ||||
| 			pad2.velocity.y = 0; | ||||
| @@ -54,12 +81,13 @@ int main() { | ||||
|  | ||||
| 		/* Update ball velocity based on collision detection */ | ||||
| 		if (pad1.getRect().CheckCollision(ball.pos, ball.radius)) { /* Collision with paddle 1 */ | ||||
| 			ball.vel.x = ball.vel.x * (-1); | ||||
| 			ball.pos.x = pad1.getRect().x + pad1.getRect().GetWidth() + ball.radius + 1; /* Ensuring that the ball doesn't get stuck inside the paddle */ | ||||
| 			ball.vel = changeVelocityAfterCollision(pad1, ball); | ||||
|  | ||||
| 		} | ||||
| 		if (pad2.getRect().CheckCollision(ball.pos, ball.radius)) { /* Collision with paddle 2 */ | ||||
| 			ball.vel.x = ball.vel.x * (-1); | ||||
| 			ball.pos.x = pad2.getRect().x - ball.radius - 1; | ||||
| 			ball.vel = changeVelocityAfterCollision(pad2, ball); | ||||
| 		} | ||||
|  | ||||
| 		if (ball.pos.x + ball.radius >= window.GetWidth()) { /* Collision with right wall */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user