I have written a pong game in C++ using SDL2.0 for the graphics. I have a couple of questions regarding this code:
How can I make the AI better, in such a way that it is actually dumber? Right now, my AI can return the ball to me every time, which is unfair. I want the player to be able to score at least some of the time. Some sort of percentage of error variable might do the trick, not sure.
How can I fix the ugliness of some of the functions? Currently, my
load_rendered_text()
function takes 2 things of text and returns 2 textures, when it should only take 1 thing of text for 1 texture, and be called twice. Also, myBall::move_ball()
function has more than 10 if statements, checking various conditions. How would one go about fixing that?Am I using too many comments? Not enough comments? I generally try and aim for self documenting code. Meaning that the code should tell you what its doing without the need for comments, most of the time. To achieve this I've tried my best to use consistent naming, and easy to understand variable names. Let me know if you spot any naming errors or things that could be better in this area.
class Ball
{
public:
const int BALL_WIDTH = 15;
const int BALL_HEIGHT = 15;
const float BALL_VELOCITY = 2;
Ball();
void init_ball_direction();
void move_ball(float timeStep, SDL_Rect playerPaddle, SDL_Rect aiPaddle);
void render_ball();
private:
float ballPositionX, ballPositionY;
float ballVelocityX, ballVelocityY;
bool isMovingDown, isMovingUp;
bool isMovingLeft, isMovingRight;
SDL_Rect bCollider;
};
...
class AI
{
public:
const float AI_VELOCITY = 3;
void init_ai();
void move_ai();
void handle_ai_events();
SDL_Rect aiPaddle;
private:
float aiYPosition;
float aiVelocity;
};
...
void Ball::move_ball(float timeStep, SDL_Rect playerPaddle, SDL_Rect aiPaddle)
{
//move the ball, its collider, and the raycast. Check for collisions with the paddles
//by calling the check_collision() function.
if(ballPositionY + BALL_HEIGHT > SCREEN_HEIGHT){
isMovingDown = false;
isMovingUp = true;
}
if(ballPositionY < 0){
isMovingDown = true;
isMovingUp = false;
}
if(ballPositionX + BALL_WIDTH > SCREEN_WIDTH){
ballPositionX = SCREEN_WIDTH/2;
}
if(ballPositionX < 0){
ballPositionX = SCREEN_WIDTH/2;
}
if(check_collision(bCollider, playerPaddle)){
isMovingLeft = false;
isMovingRight = true;
}
if(check_collision(bCollider, aiPaddle)){
isMovingRight = false;
isMovingLeft = true;
}
if(isMovingUp){
ballPositionY -= ballVelocityY;
bCollider.y = ballPositionY;
bRaycastLine.y = ballPositionY;
}
if(isMovingDown){
ballPositionY += ballVelocityY;
bCollider.y = ballPositionY;
bRaycastLine.y = ballPositionY;
}
if(isMovingLeft){
ballPositionX -= ballVelocityX;
bCollider.x = ballPositionX;
bRaycastLine.x = ballPositionX;
}
if(isMovingRight){
ballPositionX += ballVelocityX;
bCollider.x = ballPositionX;
bRaycastLine.x = ballPositionX;
}
}
...
void AI::init_ai()
{
//initialize the AI, not much here becaue the AI is very basic.
aiPaddle.h = 40;
aiPaddle.w = 10;
aiPaddle.x = SCREEN_WIDTH - aiPaddle.w;
aiPaddle.y = SCREEN_HEIGHT/2 - aiPaddle.h/2;
aiYPosition = aiPaddle.y;
aiVelocity = 0;
}
void AI::handle_ai_events()
{
//check if the raycasted line is above/below the AI paddle...
if(bRaycastLine.y > aiPaddle.y + aiPaddle.h){
aiVelocity += AI_VELOCITY;
} else if(bRaycastLine.y < aiPaddle.y){
aiVelocity -= AI_VELOCITY;
}
}
void AI::move_ai()
{
//apply the velocities to the AI...
aiYPosition = aiVelocity;
aiPaddle.y = aiYPosition;
if(aiYPosition < 0){
aiYPosition -= aiVelocity;
aiPaddle.y = aiYPosition;
}
if(aiYPosition > aiPaddle.y + SCREEN_HEIGHT){
aiYPosition += aiVelocity;
aiPaddle.y = aiYPosition;
}
}
bRaycastLine
is an SDL_Rect
that follows the position of the ball.
...
's in your code? \$\endgroup\$